diff options
| author | Yong He <yonghe@outlook.com> | 2024-08-19 15:03:56 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-19 15:03:56 -0700 |
| commit | 453683bf44f2112719802eaac2b332d49eebd640 (patch) | |
| tree | d399db4c9cba90c11980186d3df1ffcc4d423b5a /source/slang/slang-lower-to-ir.cpp | |
| parent | ecf85df6eee3da76ef54b14e4ab083f22da89e46 (diff) | |
Tuple swizzling, concat, comparison and `countof`. (#4856)
* Tuple swizzling and element access.
* Update proposal status.
* Cleanup.
* Fix merrge error.
* Address review.
Diffstat (limited to 'source/slang/slang-lower-to-ir.cpp')
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 91 |
1 files changed, 52 insertions, 39 deletions
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 9ceb3074a..44c62e858 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -336,11 +336,8 @@ struct SwizzledLValueInfo : ExtendedValueInfo // The base expression (this should be an l-value) LoweredValInfo base; - // The number of elements in the swizzle - UInt elementCount; - // THe indices for the elements being swizzled - UInt elementIndices[4]; + ShortList<UInt, 4> elementIndices; }; // Represents the result of a matrix swizzle operation in an l-value context. @@ -1183,8 +1180,8 @@ top: return LoweredValInfo::simple(builder->emitSwizzle( swizzleInfo->type, getSimpleVal(context, swizzleInfo->base), - swizzleInfo->elementCount, - swizzleInfo->elementIndices)); + swizzleInfo->elementIndices.getCount(), + swizzleInfo->elementIndices.getArrayView().getBuffer())); } case LoweredValInfo::Flavor::SwizzledMatrixLValue: @@ -1656,6 +1653,15 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower return LoweredValInfo::simple(resultVal); } + LoweredValInfo visitCountOfIntVal(CountOfIntVal* val) + { + auto irBuilder = getBuilder(); + auto type = lowerType(context, val->getType()); + auto typeArg = lowerType(context, as<Type>(val->getTypeArg())); + auto count = irBuilder->emitCountOf(type, typeArg); + return LoweredValInfo::simple(count); + } + LoweredValInfo visitConcreteTypePack(ConcreteTypePack* typePack) { ShortList<IRType*> types; @@ -1665,7 +1671,7 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower types.add(loweredType); } auto irBuilder = getBuilder(); - IRType* irTypePack = irBuilder->getTupleType((UInt)types.getCount(), types.getArrayView().getBuffer()); + IRType* irTypePack = irBuilder->getTypePack((UInt)types.getCount(), types.getArrayView().getBuffer()); return LoweredValInfo::simple(irTypePack); } @@ -4038,6 +4044,7 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo> const auto size = naturalLayoutContext.calcSize(sizeOfLikeExpr->sizedType); auto builder = getBuilder(); + auto resultType = lowerType(context, sizeOfLikeExpr->type); if (!size) { @@ -4051,10 +4058,15 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo> { inst = builder->emitAlignOf(sizedType); } - else + else if (as<SizeOfExpr>(sizeOfLikeExpr)) { inst = builder->emitSizeOf(sizedType); } + else + { + + inst = builder->emitCountOf(resultType, sizedType); + } return LoweredValInfo::simple(inst); } @@ -4064,7 +4076,7 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo> size.size : size.alignment; - return LoweredValInfo::simple(getBuilder()->getIntValue(builder->getUIntType(), value)); + return LoweredValInfo::simple(getBuilder()->getIntValue(resultType, value)); } LoweredValInfo visitOverloadedExpr(OverloadedExpr* /*expr*/) @@ -4422,7 +4434,7 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo> { irArgs.add(getSimpleVal(context, lowerSubExpr(arg))); } - auto irMakeTuple = getBuilder()->emitMakeTuple(irArgs); + auto irMakeTuple = getBuilder()->emitMakeValuePack((UInt)irArgs.getCount(), irArgs.getBuffer()); return LoweredValInfo::simple(irMakeTuple); } @@ -5367,10 +5379,10 @@ struct LValueExprLoweringVisitor : ExprLoweringVisitorBase<LValueExprLoweringVis { auto irType = lowerType(context, expr->type); auto loweredBase = lowerLValueExpr(context, expr->base); - UInt elementCount = (UInt)expr->elementCount; + UInt elementCount = (UInt)expr->elementIndices.getCount(); // Assign to 'bs' the elements from 'as' according to the first 'n' indices in 'is' - auto backpermute = [](UInt n, const auto* as, const int* is, auto* bs) + auto backpermute = [](UInt n, const auto as, const auto is, auto bs) { for(UInt i = 0; i < n; ++i) { @@ -5397,7 +5409,7 @@ struct LValueExprLoweringVisitor : ExprLoweringVisitorBase<LValueExprLoweringVis RefPtr<SwizzledLValueInfo> swizzledLValue = new SwizzledLValueInfo; swizzledLValue->type = irType; swizzledLValue->base = baseSwizzleInfo->base; - swizzledLValue->elementCount = elementCount; + swizzledLValue->elementIndices = elementCount; // Take the swizzle element of the "outer" swizzle, as it was // written by the user. In our running example of `foo[i].zw.y` @@ -5406,7 +5418,7 @@ struct LValueExprLoweringVisitor : ExprLoweringVisitorBase<LValueExprLoweringVis // Use that original element index to figure out which of the // elements of the original swizzle this should map to. backpermute( - swizzledLValue->elementCount, + swizzledLValue->elementIndices.getCount(), baseSwizzleInfo->elementIndices, expr->elementIndices, swizzledLValue->elementIndices); @@ -5439,17 +5451,7 @@ struct LValueExprLoweringVisitor : ExprLoweringVisitorBase<LValueExprLoweringVis RefPtr<SwizzledLValueInfo> swizzledLValue = new SwizzledLValueInfo; swizzledLValue->type = irType; swizzledLValue->base = loweredBase; - swizzledLValue->elementCount = elementCount; - - // In the default case, we can just copy the indices being - // used for the swizzle over directly from the expression, - // and use the base as-is. - // - for (UInt ii = 0; ii < elementCount; ++ii) - { - swizzledLValue->elementIndices[ii] = (UInt) expr->elementIndices[ii]; - } - + swizzledLValue->elementIndices = expr->elementIndices; context->shared->extValues.add(swizzledLValue); return LoweredValInfo::swizzledLValue(swizzledLValue); } @@ -5460,8 +5462,6 @@ struct RValueExprLoweringVisitor : public ExprLoweringVisitorBase<RValueExprLowe { static bool _isLValueContext() { return false; } - // A matrix swizzle in an r-value context can save time by just - // emitting the matrix swizzle instructions directly. LoweredValInfo visitMatrixSwizzleExpr(MatrixSwizzleExpr* expr) { auto resultType = lowerType(context, expr->type); @@ -5517,9 +5517,9 @@ struct RValueExprLoweringVisitor : public ExprLoweringVisitorBase<RValueExprLowe auto irIntType = getIntType(context); - UInt elementCount = (UInt)expr->elementCount; - IRInst* irElementIndices[4]; - for (UInt ii = 0; ii < elementCount; ++ii) + ShortList<IRInst*, 4> irElementIndices; + irElementIndices.setCount(expr->elementIndices.getCount()); + for (UInt ii = 0; ii < (UInt)expr->elementIndices.getCount(); ++ii) { irElementIndices[ii] = builder->getIntValue( irIntType, @@ -5529,7 +5529,7 @@ struct RValueExprLoweringVisitor : public ExprLoweringVisitorBase<RValueExprLowe auto irSwizzle = builder->emitSwizzle( irType, irBase, - elementCount, + (UInt)irElementIndices.getCount(), &irElementIndices[0]); return LoweredValInfo::simple(irSwizzle); @@ -6926,7 +6926,7 @@ LoweredValInfo tryGetAddress( auto originalSwizzleInfo = val.getSwizzledLValueInfo(); auto originalBase = originalSwizzleInfo->base; - UInt elementCount = originalSwizzleInfo->elementCount; + UInt elementCount = (UInt)originalSwizzleInfo->elementIndices.getCount(); auto newBase = tryGetAddress(context, originalBase, TryGetAddressMode::Aggressive); if (newBase.flavor == LoweredValInfo::Flavor::Ptr && elementCount == 1) @@ -6942,7 +6942,7 @@ LoweredValInfo tryGetAddress( newSwizzleInfo->base = newBase; newSwizzleInfo->type = originalSwizzleInfo->type; - newSwizzleInfo->elementCount = elementCount; + newSwizzleInfo->elementIndices.setCount(elementCount); for(UInt ee = 0; ee < elementCount; ++ee) newSwizzleInfo->elementIndices[ee] = originalSwizzleInfo->elementIndices[ee]; @@ -7124,8 +7124,8 @@ top: irLeftVal->getDataType(), irLeftVal, irRightVal, - swizzleInfo->elementCount, - swizzleInfo->elementIndices); + (UInt)swizzleInfo->elementIndices.getCount(), + swizzleInfo->elementIndices.getArrayView().getBuffer()); // And finally, store the value back where we got it. // @@ -7158,8 +7158,8 @@ top: swizzledStore( loweredBase.val, irRightVal, - swizzleInfo->elementCount, - swizzleInfo->elementIndices); + (UInt)swizzleInfo->elementIndices.getCount(), + swizzleInfo->elementIndices.getArrayView().getBuffer()); } break; } @@ -11525,7 +11525,7 @@ IRTypeLayout* lowerTypeLayout( else if( auto structTypeLayout = as<StructTypeLayout>(typeLayout) ) { IRStructTypeLayout::Builder builder(context->irBuilder); - + int fieldIndex = 0; for( auto fieldLayout : structTypeLayout->fields ) { auto fieldDecl = fieldLayout->varDecl; @@ -11573,11 +11573,24 @@ IRTypeLayout* lowerTypeLayout( context->mapEntryPointParamToKey.add(paramDecl.getDecl(), irFieldKey); } } - else + else if (fieldDecl.getDecl()) { irFieldKey = getSimpleVal(context, ensureDecl(context, fieldDecl.getDecl())); } + else + { + // If we don't have a concrete field decl for the field in the layout, + // it could be that the field in the layout is for a member of a tuple + // type that hasn't been materialized into a struct decl yet. + // We will use a `IndexFieldKey(type, memberIndex)` inst as a placeholder + // for the field key. + // This placeholder can be replaced with the actual field key when the + // tuple type is materialized into a struct type. + auto irType = lowerType(context, typeLayout->getType()); + irFieldKey = context->irBuilder->getIndexedFieldKey(irType, fieldIndex); + } + fieldIndex++; SLANG_ASSERT(irFieldKey); auto irFieldLayout = lowerVarLayout(context, fieldLayout); |
