diff options
| author | Yong He <yonghe@outlook.com> | 2020-09-04 10:18:44 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-04 10:18:44 -0700 |
| commit | 8f962894fd38edb47d782d303ac9ff87b3a3bb6a (patch) | |
| tree | 449d0d58ca7d90a11759372c9dc82650a565f96a /source | |
| parent | 5e10f1b4f0654515af1fcb29e8d1f35e691c8aa3 (diff) | |
Allow mixing unspecialized and specialized existential parameters. (#1533)
* Allow mixing unspecialized and specialized existential parameters.
* Fixes.
Diffstat (limited to 'source')
22 files changed, 205 insertions, 23 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 62039992e..8d0ce1d1d 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -315,6 +315,11 @@ __intrinsic_type($(kIROp_StringType)) struct String {}; +__magic_type(DynamicType) +__intrinsic_type($(kIROp_DynamicType)) +struct __Dynamic +{}; + /// An `N` component vector with elements of type `T`. __generic<T = float, let N : int = 4> __magic_type(Vector) diff --git a/source/slang/slang-ast-builder.cpp b/source/slang/slang-ast-builder.cpp index ec4fd20f1..64061549e 100644 --- a/source/slang/slang-ast-builder.cpp +++ b/source/slang/slang-ast-builder.cpp @@ -100,6 +100,16 @@ Type* SharedASTBuilder::getEnumTypeType() return m_enumTypeType; } +Type* SharedASTBuilder::getDynamicType() +{ + if (!m_dynamicType) + { + auto dynamicTypeDecl = findMagicDecl("DynamicType"); + m_dynamicType = DeclRefType::create(m_astBuilder, makeDeclRef<Decl>(dynamicTypeDecl)); + } + return m_dynamicType; +} + SharedASTBuilder::~SharedASTBuilder() { // Release built in types.. diff --git a/source/slang/slang-ast-builder.h b/source/slang/slang-ast-builder.h index 2cc03054b..08d22f6ca 100644 --- a/source/slang/slang-ast-builder.h +++ b/source/slang/slang-ast-builder.h @@ -25,6 +25,8 @@ public: Type* getStringType(); /// Get the enum type type Type* getEnumTypeType(); + /// Get the __Dynamic type + Type* getDynamicType(); const ReflectClassInfo* findClassInfo(Name* name); SyntaxClass<NodeBase> findSyntaxClass(Name* name); @@ -62,6 +64,7 @@ protected: // Type* m_stringType = nullptr; Type* m_enumTypeType = nullptr; + Type* m_dynamicType = nullptr; Type* m_builtinTypes[Index(BaseType::CountOf)]; diff --git a/source/slang/slang-ast-type.h b/source/slang/slang-ast-type.h index 4c1c07ba3..b2e43a507 100644 --- a/source/slang/slang-ast-type.h +++ b/source/slang/slang-ast-type.h @@ -466,6 +466,11 @@ class StringType : public BuiltinType SLANG_CLASS(StringType) }; +// The built-in `__Dynamic` type +class DynamicType : public BuiltinType +{ + SLANG_CLASS(DynamicType) +}; // Type built-in `__EnumType` type class EnumTypeType : public BuiltinType diff --git a/source/slang/slang-ast-val.h b/source/slang/slang-ast-val.h index 4926643d3..6bc86e805 100644 --- a/source/slang/slang-ast-val.h +++ b/source/slang/slang-ast-val.h @@ -206,4 +206,11 @@ class ThisTypeSubtypeWitness : public SubtypeWitness SLANG_CLASS(ThisTypeSubtypeWitness) }; + /// A witness of the fact that a user provided "__Dynamic" type argument is a + /// subtype to the existential type parameter. +class DynamicSubtypeWitness : public SubtypeWitness +{ + SLANG_CLASS(DynamicSubtypeWitness) +}; + } // namespace Slang diff --git a/source/slang/slang-check-conformance.cpp b/source/slang/slang-check-conformance.cpp index 25a7ac4ee..6a397e8b6 100644 --- a/source/slang/slang-check-conformance.cpp +++ b/source/slang/slang-check-conformance.cpp @@ -180,8 +180,16 @@ namespace Slang } return true; } - - if( auto aggTypeDeclRef = declRef.as<AggTypeDecl>() ) + if (auto dynamicType = as<DynamicType>(subType)) + { + // A __Dynamic type always conforms to the interface via its witness table. + if (outWitness) + { + *outWitness = m_astBuilder->create<DynamicSubtypeWitness>(); + } + return true; + } + else if( auto aggTypeDeclRef = declRef.as<AggTypeDecl>() ) { ensureDecl(aggTypeDeclRef, DeclCheckState::CanEnumerateBases); @@ -363,7 +371,6 @@ namespace Slang } return true; } - // default is failure return false; } diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 231207626..090d06f28 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -942,6 +942,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst) case kIROp_getElementPtr: case kIROp_Specialize: case kIROp_lookup_interface_method: + case kIROp_GetValueFromExistentialBox: return true; } @@ -2388,6 +2389,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO break; case kIROp_GlobalConstant: + case kIROp_GetValueFromExistentialBox: emitOperand(inst->getOperand(0), outerPrec); break; diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index c614a7a50..9ab42569a 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -314,7 +314,7 @@ Result linkAndOptimizeIR( // generics / interface types to ordinary functions and types using // function pointers. dumpIRIfEnabled(compileRequest, irModule, "BEFORE-LOWER-GENERICS"); - lowerGenerics(irModule, sink); + lowerGenerics(targetRequest, irModule, sink); dumpIRIfEnabled(compileRequest, irModule, "LOWER-GENERICS"); break; default: diff --git a/source/slang/slang-ir-collect-global-uniforms.cpp b/source/slang/slang-ir-collect-global-uniforms.cpp index 306bbdfee..44f1e4ac0 100644 --- a/source/slang/slang-ir-collect-global-uniforms.cpp +++ b/source/slang/slang-ir-collect-global-uniforms.cpp @@ -50,6 +50,20 @@ struct CollectGlobalUniformParametersContext IRModule* module; IRVarLayout* globalScopeVarLayout; + IRGlobalParam* _getGlobalParamFromLayoutFieldKey(IRInst* key) + { + switch (key->op) + { + case kIROp_GlobalParam: + return cast<IRGlobalParam>(key); + case kIROp_MakeExistential: + case kIROp_WrapExistential: + return as<IRGlobalParam>(key->getOperand(0)); + default: + return nullptr; + } + } + // This is a relatively simple pass, and it is all driven // by a single subroutine. // @@ -158,7 +172,7 @@ struct CollectGlobalUniformParametersContext // layout so that the "key" for the field is the corresponding // global shader parameter. // - auto globalParam = as<IRGlobalParam>(fieldLayoutAttr->getFieldKey()); + auto globalParam = _getGlobalParamFromLayoutFieldKey(fieldLayoutAttr->getFieldKey()); SLANG_ASSERT(globalParam); auto globalParamLayout = fieldLayoutAttr->getLayout(); diff --git a/source/slang/slang-ir-generics-lowering-context.cpp b/source/slang/slang-ir-generics-lowering-context.cpp index b7e2917d5..9c4eb7856 100644 --- a/source/slang/slang-ir-generics-lowering-context.cpp +++ b/source/slang/slang-ir-generics-lowering-context.cpp @@ -197,6 +197,11 @@ namespace Slang SLANG_ASSERT(reqVal && reqVal->op == kIROp_AssociatedType); return lowerType(builder, reqVal, typeMapping); } + case kIROp_ExistentialBoxType: + { + auto existentialBoxType = static_cast<IRExistentialBoxType*>(paramType); + return lowerType(builder, existentialBoxType->getInterfaceType(), typeMapping); + } default: { bool translated = false; diff --git a/source/slang/slang-ir-generics-lowering-context.h b/source/slang/slang-ir-generics-lowering-context.h index 8c23cad44..be56e9c84 100644 --- a/source/slang/slang-ir-generics-lowering-context.h +++ b/source/slang/slang-ir-generics-lowering-context.h @@ -16,6 +16,8 @@ namespace Slang // we are processing. IRModule* module; + TargetRequest* targetReq; + DiagnosticSink* sink; // RTTI objects for each type used to call a generic function. diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index 4074a435f..7863b9a9c 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -26,6 +26,8 @@ INST(Nop, nop, 0, 0) INST(StringType, String, 0, 0) + INST(DynamicType, DynamicType, 0, 0) + INST(AnyValueType, AnyValueType, 1, 0) INST(RawPointerType, RawPointerType, 0, 0) @@ -587,6 +589,10 @@ INST(MakeExistentialWithRTTI, makeExistentialWithRTTI, 3, 0) // INST(WrapExistential, wrapExistential, 2, 0) +// A `GetValueFromExistentialBox` takes a `ExistentialBox` value and returns the value wrapped by +// the existential box. +INST(GetValueFromExistentialBox, getValueFromExistentialBox, 1, 0) + INST(ExtractExistentialValue, extractExistentialValue, 1, 0) INST(ExtractExistentialType, extractExistentialType, 1, 0) INST(ExtractExistentialWitnessTable, extractExistentialWitnessTable, 1, 0) diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 2197456a1..dc841bb3a 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -1622,6 +1622,11 @@ struct IRWrapExistential : IRInst IR_LEAF_ISA(WrapExistential) }; +struct IRGetValueFromExistentialBox : IRInst +{ + IR_LEAF_ISA(GetValueFromExistentialBox); +}; + struct IRExtractExistentialValue : IRInst { IR_LEAF_ISA(ExtractExistentialValue); @@ -1745,6 +1750,7 @@ struct IRBuilder IRBasicType* getIntType(); IRBasicType* getUIntType(); IRStringType* getStringType(); + IRAssociatedType* getAssociatedType(ArrayView<IRInterfaceType*> constraintTypes); IRThisType* getThisType(IRInterfaceType* interfaceType); IRRawPointerType* getRawPointerType(); @@ -1752,6 +1758,7 @@ struct IRBuilder IRRTTIType* getRTTIType(); IRAnyValueType* getAnyValueType(IRIntegerValue size); IRAnyValueType* getAnyValueType(IRInst* size); + IRDynamicType* getDynamicType(); IRTupleType* getTupleType(UInt count, IRType* const* types); IRTupleType* getTupleType(IRType* type0, IRType* type1); @@ -1770,6 +1777,7 @@ struct IRBuilder IRInOutType* getInOutType(IRType* valueType); IRRefType* getRefType(IRType* valueType); IRPtrTypeBase* getPtrType(IROp op, IRType* valueType); + IRExistentialBoxType* getExistentialBoxType(IRType* concreteType, IRType* interfaceType); IRArrayTypeBase* getArrayTypeBase( IROp op, @@ -1838,6 +1846,9 @@ struct IRBuilder // its rate, if any. void setDataType(IRInst* inst, IRType* dataType); + /// Extract the value wrapped inside an existential box. + IRInst* emitGetValueFromExistentialBox(IRType* type, IRInst* existentialBox); + /// Given an existential value, extract the underlying "real" value IRInst* emitExtractExistentialValue( IRType* type, diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp index 3a1471f98..2161b0223 100644 --- a/source/slang/slang-ir-legalize-types.cpp +++ b/source/slang/slang-ir-legalize-types.cpp @@ -1210,6 +1210,9 @@ static LegalVal legalizeInst( case kIROp_Load: return legalizeLoad(context, args[0]); + case kIROp_GetValueFromExistentialBox: + return args[0]; + case kIROp_FieldAddress: return legalizeFieldAddress(context, type, args[0], args[1]); diff --git a/source/slang/slang-ir-lower-existential.cpp b/source/slang/slang-ir-lower-existential.cpp index a6db2b781..0dce96de2 100644 --- a/source/slang/slang-ir-lower-existential.cpp +++ b/source/slang/slang-ir-lower-existential.cpp @@ -7,6 +7,9 @@ namespace Slang { + bool isCPUTarget(TargetRequest* targetReq); + bool isCUDATarget(TargetRequest* targetReq); + struct ExistentialLoweringContext { SharedGenericsLoweringContext* sharedContext; @@ -79,12 +82,40 @@ namespace Slang processExtractExistentialElement(inst, 0); } + void processGetValueFromExistentialBox(IRGetValueFromExistentialBox* inst) + { + // Currently we do not translate on HLSL/GLSL targets, + // since we don't attempt to actually layout the value inside an fixed sized + // existential box for these targets. + if (isCPUTarget(sharedContext->targetReq) || isCUDATarget(sharedContext->targetReq)) + { + IRBuilder builderStorage; + auto builder = &builderStorage; + builder->sharedBuilder = &sharedContext->sharedBuilderStorage; + builder->setInsertBefore(inst); + + auto element = extractTupleElement(builder, inst->getOperand(0), 2); + // TODO: it is not technically sound to use `getAddress` on a temporary value. + // We probably need to develop a mechanism to allow a temporary value to be used + // in the place of a pointer. + auto elementAddr = + builder->emitGetAddress(builder->getPtrType(element->getDataType()), element); + auto reinterpretAddr = builder->emitBitCast(inst->getDataType(), elementAddr); + inst->replaceUsesWith(reinterpretAddr); + inst->removeAndDeallocate(); + } + } + void processInst(IRInst* inst) { if (auto makeExistential = as<IRMakeExistentialWithRTTI>(inst)) { processMakeExistential(makeExistential); } + else if (auto getExistentialValue = as<IRGetValueFromExistentialBox>(inst)) + { + processGetValueFromExistentialBox(getExistentialValue); + } else if (auto extractExistentialVal = as<IRExtractExistentialValue>(inst)) { processExtractExistentialValue(extractExistentialVal); diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp index 63e1fdc49..a9540a87a 100644 --- a/source/slang/slang-ir-lower-generics.cpp +++ b/source/slang/slang-ir-lower-generics.cpp @@ -15,10 +15,12 @@ namespace Slang { void lowerGenerics( + TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink) { SharedGenericsLoweringContext sharedContext; + sharedContext.targetReq = targetReq; sharedContext.module = module; sharedContext.sink = sink; diff --git a/source/slang/slang-ir-lower-generics.h b/source/slang/slang-ir-lower-generics.h index 76b5c1b58..ea83b35bf 100644 --- a/source/slang/slang-ir-lower-generics.h +++ b/source/slang/slang-ir-lower-generics.h @@ -7,10 +7,12 @@ namespace Slang {
struct IRModule;
class DiagnosticSink;
+ class TargetRequest;
/// Lower generic and interface-based code to ordinary types and functions using
/// dynamic dispatch mechanisms.
void lowerGenerics(
+ TargetRequest* targetReq,
IRModule* module,
DiagnosticSink* sink);
diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp index 3acb34c87..75b2beeec 100644 --- a/source/slang/slang-ir-specialize.cpp +++ b/source/slang/slang-ir-specialize.cpp @@ -611,6 +611,33 @@ struct SpecializationContext return nullptr; } + void maybeInsertGetExistentialValue(IRInst* inst) + { + // If inst has `ExistentialBox` type, we need to make sure + // all uses are through `GetValueFromExistentialBox`. + if (auto existentialBoxType = as<IRExistentialBoxType>(inst->getDataType())) + { + ShortList<IRUse*> usesToReplace; + for (auto use = inst->firstUse; use; use = use->nextUse) + { + if (use->getUser()->op != kIROp_GetValueFromExistentialBox) + usesToReplace.add(use); + } + for (auto use : usesToReplace) + { + auto user = use->getUser(); + IRBuilder builderStorage; + auto builder = &builderStorage; + builder->sharedBuilder = &sharedBuilderStorage; + builder->setInsertBefore(user); + auto getValueInst = builder->emitGetValueFromExistentialBox( + builder->getPtrType(existentialBoxType->getValueType()), inst); + use->set(getValueInst); + addToWorkList(getValueInst); + } + } + } + // All of the machinery for generic specialization // has been defined above, so we will now walk // through the flow of the overall specialization pass. @@ -678,6 +705,10 @@ struct SpecializationContext workListSet.Remove(inst); cleanInsts.Add(inst); + // If inst represents a value of ExistentialBox type, all its uses + // must be through a `GetValueFromExistentialBox` inst. + maybeInsertGetExistentialValue(inst); + // For each instruction we process, we want to perform // a few steps. // @@ -1640,7 +1671,7 @@ struct SpecializationContext if(slotOperandCount <= 1) return; auto concreteType = (IRType*) type->getExistentialArg(0); - auto newVal = builder.getPtrType(kIROp_ExistentialBoxType, concreteType); + auto newVal = builder.getExistentialBoxType(concreteType, baseInterfaceType); addUsersToWorkList(type); type->replaceUsesWith(newVal); diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index 2f27bbebc..37841c35f 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -2232,6 +2232,8 @@ namespace Slang return (IRStringType*)getType(kIROp_StringType); } + IRDynamicType* IRBuilder::getDynamicType() { return (IRDynamicType*)getType(kIROp_DynamicType); } + IRAssociatedType* IRBuilder::getAssociatedType(ArrayView<IRInterfaceType*> constraintTypes) { return (IRAssociatedType*)getType(kIROp_AssociatedType, @@ -2331,6 +2333,12 @@ namespace Slang operands); } + IRExistentialBoxType* IRBuilder::getExistentialBoxType(IRType* concreteType, IRType* interfaceType) + { + IRInst* operands[] = {concreteType, interfaceType}; + return (IRExistentialBoxType*)getType(kIROp_ExistentialBoxType, 2, operands); + } + IRArrayTypeBase* IRBuilder::getArrayTypeBase( IROp op, IRType* elementType, @@ -2471,7 +2479,7 @@ namespace Slang // so we just want to return `ExistentialBox<someConcreteType>`. // auto concreteType = (IRType*) slotArgs[0]; - auto ptrType = getPtrType(kIROp_ExistentialBoxType, concreteType); + auto ptrType = getExistentialBoxType(concreteType, (IRType*)baseType); return ptrType; } } @@ -2524,6 +2532,14 @@ namespace Slang } } + IRInst* IRBuilder::emitGetValueFromExistentialBox(IRType* type, IRInst* existentialBox) + { + auto inst = + createInst<IRInst>(this, kIROp_GetValueFromExistentialBox, type, 1, &existentialBox); + addInst(inst); + return inst; + } + IRUndefined* IRBuilder::emitUndefined(IRType* type) { @@ -5273,6 +5289,7 @@ namespace Slang case kIROp_Specialize: case kIROp_lookup_interface_method: case kIROp_getAddr: + case kIROp_GetValueFromExistentialBox: case kIROp_Construct: case kIROp_makeVector: case kIROp_MakeMatrix: diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h index 2c6ad244b..9a0c71cb1 100644 --- a/source/slang/slang-ir.h +++ b/source/slang/slang-ir.h @@ -626,6 +626,7 @@ struct IRBoolType : IRBasicType SIMPLE_IR_TYPE(StringType, Type) +SIMPLE_IR_TYPE(DynamicType, Type) // True if types are equal // Note compares nominal types by name alone @@ -1109,7 +1110,12 @@ SIMPLE_IR_TYPE(RefType, PtrTypeBase) SIMPLE_IR_PARENT_TYPE(OutTypeBase, PtrTypeBase) SIMPLE_IR_TYPE(OutType, OutTypeBase) SIMPLE_IR_TYPE(InOutType, OutTypeBase) -SIMPLE_IR_TYPE(ExistentialBoxType, PtrTypeBase) + +struct IRExistentialBoxType : public IRPtrTypeBase +{ + IR_LEAF_ISA(ExistentialBoxType); + IRType* getInterfaceType() { return (IRType*)getOperand(1); } +}; /// The base class of RawPointerType and RTTIPointerType. struct IRRawPointerTypeBase : IRType diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index ee5338236..424358d3c 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -1420,10 +1420,14 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower // getBuilder()->createWitnessTableEntry(irWitnessTable, irReqKey, irSatisfyingVal); } - return LoweredValInfo::simple(irWitnessTable); } + LoweredValInfo visitDynamicSubtypeWitness(DynamicSubtypeWitness * /*val*/) + { + return LoweredValInfo::simple(nullptr); + } + LoweredValInfo visitThisTypeSubtypeWitness(ThisTypeSubtypeWitness* val) { SLANG_UNUSED(val); @@ -7859,6 +7863,8 @@ struct SpecializedComponentTypeIRGenContext : ComponentTypeVisitor IRInst* irParam = getSimpleVal(context, ensureDecl(context, shaderParam.paramDeclRef)); List<IRInst*> irSlotArgs; + // Tracks if there are any type args that is not an IRDynamicType. + bool hasConcreteTypeArg = false; for( Index jj = 0; jj < specializationArgCount; ++jj ) { auto& specializationArg = specializationInfo->existentialArgs[existentialArgOffset++]; @@ -7866,14 +7872,21 @@ struct SpecializedComponentTypeIRGenContext : ComponentTypeVisitor auto irType = lowerSimpleVal(context, specializationArg.val); auto irWitness = lowerSimpleVal(context, specializationArg.witness); + if (irType->op != kIROp_DynamicType) + hasConcreteTypeArg = true; + irSlotArgs.add(irType); irSlotArgs.add(irWitness); } - - builder->addBindExistentialSlotsDecoration( - irParam, - irSlotArgs.getCount(), - irSlotArgs.getBuffer()); + // Only insert a `BindExistentialSlots` decoration when there are at least + // one non-dynamic type argument. + if (hasConcreteTypeArg) + { + builder->addBindExistentialSlotsDecoration( + irParam, + irSlotArgs.getCount(), + irSlotArgs.getBuffer()); + } } } } diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp index fd0b126e8..d4c6a7016 100644 --- a/source/slang/slang-type-layout.cpp +++ b/source/slang/slang-type-layout.cpp @@ -3662,9 +3662,10 @@ static TypeLayoutResult _createTypeLayout( typeLayout->rules = rules; LayoutSize fixedExistentialValueSize = 0; - bool useFixedSizedExistentialValue = + bool targetSupportsPointer = isCPUTarget(context.targetReq) || isCUDATarget(context.targetReq); - if (useFixedSizedExistentialValue) + + if (targetSupportsPointer) { fixedExistentialValueSize = 16; if (auto anyValueAttr = @@ -3672,7 +3673,9 @@ static TypeLayoutResult _createTypeLayout( { fixedExistentialValueSize = anyValueAttr->size; } - typeLayout->addResourceUsage(LayoutResourceKind::Uniform, fixedExistentialValueSize + 16); + // Append 16 bytes to accommodate RTTI pointer and witness table pointer. + auto uniformSlotSize = fixedExistentialValueSize + 16; + typeLayout->addResourceUsage(LayoutResourceKind::Uniform, uniformSlotSize); } typeLayout->addResourceUsage(LayoutResourceKind::ExistentialTypeParam, 1); typeLayout->addResourceUsage(LayoutResourceKind::ExistentialObjectParam, 1); @@ -3695,17 +3698,14 @@ static TypeLayoutResult _createTypeLayout( // the existential value. We should remove this special case logic // and always use anyValueRule once we implement the correct loading // code gen logic for these targets. - if (!(isCPUTarget(context.targetReq) || isCUDATarget(context.targetReq))) + if (!targetSupportsPointer) anyValueRules = context.rules; RefPtr<TypeLayout> concreteTypeLayout = createTypeLayout(context.with(anyValueRules), concreteType); - auto uniformLayoutInfo = - concreteTypeLayout->FindResourceInfo(LayoutResourceKind::Uniform); - if (!useFixedSizedExistentialValue || - (uniformLayoutInfo && uniformLayoutInfo->count > fixedExistentialValueSize)) + if (!targetSupportsPointer) { - // TODO: for targets that supports pointers, oversized existential values + // For targets that supports pointers, oversized existential values // should be placed in an overflow region and only a pointer is needed in // the place of the fixed sized uniform slot. // We only need the "pending layout" mechanism for targets that does not |
