diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-01-21 18:05:39 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-01-21 18:05:39 -0800 |
| commit | 41311209af4963f44acf34942d42828590d4b156 (patch) | |
| tree | 97318b544324b26f056fc824f22ba91e821c6330 /source/slang/ir-legalize-types.cpp | |
| parent | 8196dc4a684a75344e507697273e2123af97b979 (diff) | |
Fix legalization of generic types (#377)
Previously, all legalizations of a generic type would use the name of the original decl for the "ordinary" part of things, and this would lead to collisions because the names didn't include the mangled generic arguments.
This is now fixed by storing the mangled name of the original inside of `struct` declarations created for legalization, and using those names instead.
Also adds support for `getElementPtr` instructions when doing IR type legalization.
Also tries to make a `DeclRefType` convert to a string using the underlying `DeclRef`. This doesn't help because `DeclRef::toString` doesn't actually include generic arguments either.
Diffstat (limited to 'source/slang/ir-legalize-types.cpp')
| -rw-r--r-- | source/slang/ir-legalize-types.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/source/slang/ir-legalize-types.cpp b/source/slang/ir-legalize-types.cpp index 5db3b4d33..d4f6d2a64 100644 --- a/source/slang/ir-legalize-types.cpp +++ b/source/slang/ir-legalize-types.cpp @@ -470,6 +470,114 @@ static LegalVal legalizeFieldAddress( fieldDeclRef); } +static LegalVal legalizeGetElementPtr( + IRTypeLegalizationContext* context, + LegalType type, + LegalVal legalPtrOperand, + IRValue* indexOperand) +{ + auto builder = context->builder; + + switch (legalPtrOperand.flavor) + { + case LegalVal::Flavor::simple: + return LegalVal::simple( + builder->emitElementAddress( + type.getSimple(), + legalPtrOperand.getSimple(), + indexOperand)); + + case LegalVal::Flavor::pair: + { + // There are two sides, the ordinary and the special, + // and we basically just dispatch to both of them. + auto pairVal = legalPtrOperand.getPair(); + auto pairInfo = pairVal->pairInfo; + + LegalType ordinaryType = type; + LegalType specialType = type; + if (type.flavor == LegalType::Flavor::pair) + { + auto pairType = type.getPair(); + ordinaryType = pairType->ordinaryType; + specialType = pairType->specialType; + } + + LegalVal ordinaryVal = legalizeGetElementPtr( + context, + ordinaryType, + pairVal->ordinaryVal, + indexOperand); + + LegalVal specialVal = legalizeGetElementPtr( + context, + specialType, + pairVal->specialVal, + indexOperand); + + return LegalVal::pair(ordinaryVal, specialVal, pairInfo); + } + break; + + case LegalVal::Flavor::tuple: + { + // The operand is a tuple of pointer-like + // values, we want to extract the element + // corresponding to a field. We will handle + // this by simply returning the corresponding + // element from the operand. + auto ptrTupleInfo = legalPtrOperand.getTuple(); + + RefPtr<TuplePseudoVal> resTupleInfo = new TuplePseudoVal(); + + auto tupleType = type.getTuple(); + assert(tupleType); + + auto elemCount = ptrTupleInfo->elements.Count(); + assert(elemCount == tupleType->elements.Count()); + + for(UInt ee = 0; ee < elemCount; ++ee) + { + auto ptrElem = ptrTupleInfo->elements[ee]; + auto elemType = tupleType->elements[ee].type; + + TuplePseudoVal::Element resElem; + resElem.fieldDeclRef = ptrElem.fieldDeclRef; + resElem.val = legalizeGetElementPtr( + context, + elemType, + ptrElem.val, + indexOperand); + + resTupleInfo->elements.Add(resElem); + } + + return LegalVal::tuple(resTupleInfo); + } + + default: + SLANG_UNEXPECTED("unhandled"); + UNREACHABLE_RETURN(LegalVal()); + } +} + +static LegalVal legalizeGetElementPtr( + IRTypeLegalizationContext* context, + LegalType type, + LegalVal legalPtrOperand, + LegalVal legalIndexOperand) +{ + // We don't expect any legalization to affect + // the "index" argument. + auto indexOperand = legalIndexOperand.getSimple(); + + return legalizeGetElementPtr( + context, + type, + legalPtrOperand, + indexOperand); +} + static LegalVal legalizeInst( IRTypeLegalizationContext* context, IRInst* inst, @@ -484,6 +592,9 @@ static LegalVal legalizeInst( case kIROp_FieldAddress: return legalizeFieldAddress(context, type, args[0], args[1]); + case kIROp_getElementPtr: + return legalizeGetElementPtr(context, type, args[0], args[1]); + case kIROp_Store: return legalizeStore(context, args[0], args[1]); |
