From f65d756bff8d4c5cbc15bd0322a2ae8e6b896a21 Mon Sep 17 00:00:00 2001 From: Ellie Hermaszewska Date: Tue, 29 Oct 2024 14:49:26 +0800 Subject: format * format * Minor test fixes * enable checking cpp format in ci --- source/slang/slang-ir-any-value-inference.cpp | 359 +++++++++++++------------- 1 file changed, 183 insertions(+), 176 deletions(-) (limited to 'source/slang/slang-ir-any-value-inference.cpp') diff --git a/source/slang/slang-ir-any-value-inference.cpp b/source/slang/slang-ir-any-value-inference.cpp index b1e82623f..d26dff203 100644 --- a/source/slang/slang-ir-any-value-inference.cpp +++ b/source/slang/slang-ir-any-value-inference.cpp @@ -1,232 +1,239 @@ #include "slang-ir-any-value-inference.h" +#include "../core/slang-func-ptr.h" #include "slang-ir-generics-lowering-context.h" -#include "slang-ir.h" #include "slang-ir-insts.h" -#include "slang-ir-util.h" #include "slang-ir-layout.h" -#include "../core/slang-func-ptr.h" +#include "slang-ir-util.h" +#include "slang-ir.h" namespace Slang { - void _findDependenciesOfTypeInSet(IRType* type, HashSet& targetSet, List& result) +void _findDependenciesOfTypeInSet( + IRType* type, + HashSet& targetSet, + List& result) +{ + switch (type->getOp()) { - switch (type->getOp()) + case kIROp_InterfaceType: { - case kIROp_InterfaceType: + auto interfaceType = cast(type); + if (targetSet.contains(interfaceType)) { - auto interfaceType = cast(type); - if (targetSet.contains(interfaceType)) - { - result.add(interfaceType); - return; - } + result.add(interfaceType); + return; } - break; - case kIROp_StructType: + } + break; + case kIROp_StructType: + { + auto structType = cast(type); + for (auto field : structType->getFields()) { - auto structType = cast(type); - for (auto field : structType->getFields()) - { - _findDependenciesOfTypeInSet(field->getFieldType(), targetSet, result); - } + _findDependenciesOfTypeInSet(field->getFieldType(), targetSet, result); } - break; - default: + } + break; + default: + { + for (UInt i = 0; i < type->getOperandCount(); i++) { - for (UInt i = 0; i < type->getOperandCount(); i++) - { - if (auto operandType = as(type->getOperand(i))) - _findDependenciesOfTypeInSet(operandType, targetSet, result); - } + if (auto operandType = as(type->getOperand(i))) + _findDependenciesOfTypeInSet(operandType, targetSet, result); } - break; } + break; } +} - List findDependenciesOfTypeInSet(IRType* type, HashSet targetSet) - { - List result; - _findDependenciesOfTypeInSet(type, targetSet, result); +List findDependenciesOfTypeInSet( + IRType* type, + HashSet targetSet) +{ + List result; + _findDependenciesOfTypeInSet(type, targetSet, result); - return result; - } + return result; +} - void _sortTopologically( - IRInterfaceType* interfaceType, - HashSet& visited, - List& sortedInterfaceTypes, - const Func, IRInterfaceType*>& getDependencies) - { - if (visited.contains(interfaceType)) - return; +void _sortTopologically( + IRInterfaceType* interfaceType, + HashSet& visited, + List& sortedInterfaceTypes, + const Func, IRInterfaceType*>& getDependencies) +{ + if (visited.contains(interfaceType)) + return; - visited.add(interfaceType); + visited.add(interfaceType); - for (auto dependency : getDependencies(interfaceType)) - { - _sortTopologically(dependency, visited, sortedInterfaceTypes, getDependencies); - } + for (auto dependency : getDependencies(interfaceType)) + { + _sortTopologically(dependency, visited, sortedInterfaceTypes, getDependencies); + } + + sortedInterfaceTypes.add(interfaceType); +} - sortedInterfaceTypes.add(interfaceType); +List sortTopologically( + HashSet interfaceTypes, + const Func, IRInterfaceType*>& getDependencies) +{ + List sortedInterfaceTypes; + HashSet visited; + for (auto interfaceType : interfaceTypes) + { + _sortTopologically(interfaceType, visited, sortedInterfaceTypes, getDependencies); } - - List sortTopologically( - HashSet interfaceTypes, - const Func, IRInterfaceType*>& getDependencies) + return sortedInterfaceTypes; +} + +void inferAnyValueSizeWhereNecessary(TargetProgram* targetProgram, IRModule* module) +{ + // Go through the global insts and collect all interface types. + // For each interface type, infer its any-value-size, by looking up + // all witness tables whose conformance type matches the interface type. + // then using _calcNaturalSizeAndAlignment to find the max size. + // + // Note: we only infer any-value-size for interface types that are used + // as a generic type parameter, because we don't want to infer any-value-size + // for interface types that are used as a witness table type. + // + + HashSet implementedInterfaces; + // Add all interface type that are implemented by at least one type to a set. + for (auto inst : module->getGlobalInsts()) { - List sortedInterfaceTypes; - HashSet visited; - for (auto interfaceType : interfaceTypes) + if (inst->getOp() == kIROp_WitnessTable) { - _sortTopologically(interfaceType, visited, sortedInterfaceTypes, getDependencies); + auto interfaceType = + cast(inst->getDataType())->getConformanceType(); + implementedInterfaces.add(interfaceType); } - return sortedInterfaceTypes; } - void inferAnyValueSizeWhereNecessary( - TargetProgram* targetProgram, - IRModule* module) + // Collect all interface types that require inference. + HashSet interfaceTypes; + for (auto inst : module->getGlobalInsts()) { - // Go through the global insts and collect all interface types. - // For each interface type, infer its any-value-size, by looking up - // all witness tables whose conformance type matches the interface type. - // then using _calcNaturalSizeAndAlignment to find the max size. - // - // Note: we only infer any-value-size for interface types that are used - // as a generic type parameter, because we don't want to infer any-value-size - // for interface types that are used as a witness table type. - // - - HashSet implementedInterfaces; - // Add all interface type that are implemented by at least one type to a set. - for (auto inst : module->getGlobalInsts()) + if (inst->getOp() == kIROp_InterfaceType) { - if (inst->getOp() == kIROp_WitnessTable) - { - auto interfaceType = cast(inst->getDataType())->getConformanceType(); - implementedInterfaces.add(interfaceType); - } - } + auto interfaceType = cast(inst); - // Collect all interface types that require inference. - HashSet interfaceTypes; - for (auto inst : module->getGlobalInsts()) - { - if (inst->getOp() == kIROp_InterfaceType) - { - auto interfaceType = cast(inst); - - // Do not infer anything for COM interfaces. - if (isComInterfaceType((IRType*)interfaceType)) - continue; - - // Also skip builtin types. - if (interfaceType->findDecoration()) - continue; - - // If the interface already has an explicit any-value-size, don't infer anything. - if (interfaceType->findDecoration()) - continue; - - // Skip interfaces that are not implemented by any type. - if (!implementedInterfaces.contains(interfaceType)) - continue; - - interfaceTypes.add(interfaceType); - } + // Do not infer anything for COM interfaces. + if (isComInterfaceType((IRType*)interfaceType)) + continue; + + // Also skip builtin types. + if (interfaceType->findDecoration()) + continue; + + // If the interface already has an explicit any-value-size, don't infer anything. + if (interfaceType->findDecoration()) + continue; + + // Skip interfaces that are not implemented by any type. + if (!implementedInterfaces.contains(interfaceType)) + continue; + + interfaceTypes.add(interfaceType); } + } - Dictionary> mapInterfaceToImplementations; + Dictionary> mapInterfaceToImplementations; - // Collect all concrete types that conform to this interface type. - for (auto interfaceType : interfaceTypes) - { - IRWitnessTableType* witnessTableType = nullptr; - // Find witness table type corresponding to this interface. - for (auto use = interfaceType->firstUse; use; use = use->nextUse) + // Collect all concrete types that conform to this interface type. + for (auto interfaceType : interfaceTypes) + { + IRWitnessTableType* witnessTableType = nullptr; + // Find witness table type corresponding to this interface. + for (auto use = interfaceType->firstUse; use; use = use->nextUse) + { + if (auto _witnessTableType = as(use->getUser())) { - if (auto _witnessTableType = as(use->getUser())) - { - if (_witnessTableType->getConformanceType() == interfaceType && _witnessTableType->hasUses()) - { - witnessTableType = _witnessTableType; - break; - } + if (_witnessTableType->getConformanceType() == interfaceType && + _witnessTableType->hasUses()) + { + witnessTableType = _witnessTableType; + break; } } - - // If we hit this case, we have an interface without any conforming implementations. - // This case should be handled before this point. - // - SLANG_ASSERT(witnessTableType); + } + + // If we hit this case, we have an interface without any conforming implementations. + // This case should be handled before this point. + // + SLANG_ASSERT(witnessTableType); - List implList; + List implList; - // Walk through all the uses of this witness table type to find the witness tables. - for (auto use = witnessTableType->firstUse; use; use = use->nextUse) - { - auto witnessTable = as(use->getUser()); - if (!witnessTable || witnessTable->getDataType() != witnessTableType) - continue; + // Walk through all the uses of this witness table type to find the witness tables. + for (auto use = witnessTableType->firstUse; use; use = use->nextUse) + { + auto witnessTable = as(use->getUser()); + if (!witnessTable || witnessTable->getDataType() != witnessTableType) + continue; - auto concreteImpl = witnessTable->getConcreteType(); + auto concreteImpl = witnessTable->getConcreteType(); - // Only consider implementations at the top-level (ignore those nested - // in generics) - // - if (concreteImpl->getParent() == module->getModuleInst()) - implList.add(concreteImpl); - } - - mapInterfaceToImplementations.add(interfaceType, implList); + // Only consider implementations at the top-level (ignore those nested + // in generics) + // + if (concreteImpl->getParent() == module->getModuleInst()) + implList.add(concreteImpl); } - Dictionary> interfaceDependencyMap; + mapInterfaceToImplementations.add(interfaceType, implList); + } - // Collect dependencies for each interface. - for (auto interfaceType : interfaceTypes) + Dictionary> interfaceDependencyMap; + + // Collect dependencies for each interface. + for (auto interfaceType : interfaceTypes) + { + HashSet dependencySet; + for (auto impl : mapInterfaceToImplementations[interfaceType]) { - HashSet dependencySet; - for (auto impl : mapInterfaceToImplementations[interfaceType]) - { - auto dependencies = findDependenciesOfTypeInSet((IRType*)impl, interfaceTypes); - for (auto dependency : dependencies) - dependencySet.add(dependency); - } - interfaceDependencyMap.add(interfaceType, dependencySet); + auto dependencies = findDependenciesOfTypeInSet((IRType*)impl, interfaceTypes); + for (auto dependency : dependencies) + dependencySet.add(dependency); } + interfaceDependencyMap.add(interfaceType, dependencySet); + } - // Sort the interface types in topological order. - // This is necessary because we need to infer the any-value-size of an interface type - // before we infer the any-value-size of an interface type that depends on it. - // - List sortedInterfaceTypes = sortTopologically(interfaceTypes, [&](IRInterfaceType* interfaceType) - { - return interfaceDependencyMap[interfaceType]; - }); + // Sort the interface types in topological order. + // This is necessary because we need to infer the any-value-size of an interface type + // before we infer the any-value-size of an interface type that depends on it. + // + List sortedInterfaceTypes = sortTopologically( + interfaceTypes, + [&](IRInterfaceType* interfaceType) { return interfaceDependencyMap[interfaceType]; }); - for (auto interfaceType : sortedInterfaceTypes) + for (auto interfaceType : sortedInterfaceTypes) + { + IRIntegerValue maxAnyValueSize = -1; + for (auto implType : mapInterfaceToImplementations[interfaceType]) { - IRIntegerValue maxAnyValueSize = -1; - for (auto implType : mapInterfaceToImplementations[interfaceType]) - { - IRSizeAndAlignment sizeAndAlignment; - getNaturalSizeAndAlignment(targetProgram->getOptionSet(), (IRType*)implType, &sizeAndAlignment); - - maxAnyValueSize = Math::Max(maxAnyValueSize, sizeAndAlignment.size); - } + IRSizeAndAlignment sizeAndAlignment; + getNaturalSizeAndAlignment( + targetProgram->getOptionSet(), + (IRType*)implType, + &sizeAndAlignment); + + maxAnyValueSize = Math::Max(maxAnyValueSize, sizeAndAlignment.size); + } - // Should not encounter interface types without any conforming implementations. - SLANG_ASSERT(maxAnyValueSize >= 0); + // Should not encounter interface types without any conforming implementations. + SLANG_ASSERT(maxAnyValueSize >= 0); - // If we found a max size, add an any-value-size decoration to the interface type. - if (maxAnyValueSize >= 0) - { - IRBuilder builder(module); - builder.addAnyValueSizeDecoration(interfaceType, maxAnyValueSize); - } + // If we found a max size, add an any-value-size decoration to the interface type. + if (maxAnyValueSize >= 0) + { + IRBuilder builder(module); + builder.addAnyValueSizeDecoration(interfaceType, maxAnyValueSize); } } -}; +} +}; // namespace Slang -- cgit v1.2.3