diff options
| author | ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> | 2025-08-29 15:52:34 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-29 22:52:34 +0000 |
| commit | 7758625d3fea67e55e98e7e4103d56c9918365be (patch) | |
| tree | 2ed40aeb4d16262866e5540dad1a519951b5f772 /source/slang/slang-lower-to-ir.cpp | |
| parent | 450ef7934c1adfdf4a3a3c72967de3c5798a020d (diff) | |
[CBP] Pointer frontend changes + groupshared pointer support (#7848)
Resolves #7628
Resolves: #8197
Primary Goals:
1. Add `Access` to pointer
2. AddressSpace::GroupShared support for pointers (SPIR-V)
3. Add `__getAddress()` to replace `&`
* `&` is not updated to `require(cpu)` since slangpy uses `&`. This
means we must: (1) merge PR; (2) replace `&` with `__getAddress()`; (3)
add `require(cpu)` to `&`
Changes:
* Added to `Ptr` the `Access` generic argument & logic (for
`Access::Read`).
* Moved the generic argument `AddressSpace` from `Ptr` to the end of the
type.
* Added pointer casting support between any `Ptr` as long as the
`AddressSpace` is the same
* Disallow globallycoherent T* and coherent T*
* Disallow const T*, T const*, and const T*
* Fixed .natvis display of `ConstantValue` `ValOperandNode`
* Support generic resolution of type-casted integers
* Added `VariablePointer` emitting for spirv + other minor logic needed
for groupshared pointers
Breaking Changes:
* Anyone using the `AddressSpace` of `Ptr` will now have to account for
the `Access` argument
* we disallow various syntax paired with `Ptr` and `T*`
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source/slang/slang-lower-to-ir.cpp')
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 8e1f85f8e..4df778ee6 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -2067,7 +2067,14 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower auto astValueType = type->getValueType(); IRType* irValueType = lowerType(context, astValueType); + IRInst* accessQualifier = nullptr; IRInst* addrSpace = nullptr; + + if (auto astAccessQualifier = type->getAccessQualifier()) + { + accessQualifier = getSimpleVal(context, lowerVal(context, astAccessQualifier)); + } + if (auto astAddrSpace = type->getAddressSpace()) { addrSpace = getSimpleVal(context, lowerVal(context, astAddrSpace)); @@ -2078,7 +2085,8 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower getBuilder()->getUInt64Type(), (IRIntegerValue)AddressSpace::Generic); } - return getBuilder()->getPtrType(kIROp_PtrType, irValueType, addrSpace); + + return getBuilder()->getPtrType(kIROp_PtrType, irValueType, accessQualifier, addrSpace); } IRType* visitDeclRefType(DeclRefType* type) @@ -3437,7 +3445,6 @@ void _lowerFuncDeclBaseTypeInfo( auto& parameterLists = outInfo.parameterLists; collectParameterLists( context, - declRef, ¶meterLists, kParameterListCollectMode_Default, @@ -3469,7 +3476,7 @@ void _lowerFuncDeclBaseTypeInfo( irParamType = builder->getRefType(irParamType, AddressSpace::Generic); break; case kParameterDirection_ConstRef: - irParamType = builder->getConstRefType(irParamType); + irParamType = builder->getConstRefType(irParamType, AddressSpace::Generic); break; default: SLANG_UNEXPECTED("unknown parameter direction"); @@ -4157,6 +4164,39 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo> ASTBuilder* getASTBuilder() { return context->astBuilder; } LoweredValInfo lowerSubExpr(Expr* expr) { return sharedLoweringContext.lowerSubExpr(expr); } + LoweredValInfo visitAddressOfExpr(AddressOfExpr* expr) + { + auto loweredType = lowerType(context, expr->type); + auto baseVal = lowerLValueExpr(context, expr->arg); + auto ptr = tryGetAddress(context, baseVal, TryGetAddressMode::Aggressive); + + switch (ptr.flavor) + { + case LoweredValInfo::Flavor::Ptr: + { + // TODO: This is a hack. We should just be returning `ptr`. We do not do this since + // `ptr` may have the wrong address space. This happens since when lowering-to-ir we + // don't check what addres-space info we should be using for variables we create. + // example: `groupshared int ptr` ==> lower-to-ir lowers as default address-space + // with groupshared-rate. + // + // We need to emit a temporary variable (and cannot emit a cast) since `operator*` + // has its own hacks and is an incorrect implementation of its own. To elaborate, + // `operator*` is defined as `__intrinsic_op(0)`, which means "pass arguments + // through a function `in`, then set as result". This is an issue since this means + // that our function (which should be returning a `ref`) may in fact, not be + // returning a `ref` but instead be loading via the `in` parameter and generating a + // non-pointer result. + auto irVar = context->irBuilder->emitVar(loweredType); + context->irBuilder->emitStore(irVar, ptr.val); + return LoweredValInfo::ptr(irVar); + } + default: + SLANG_UNIMPLEMENTED_X("cannot get address of __getAddress(...) argument"); + UNREACHABLE_RETURN(LoweredValInfo()); + } + } + LoweredValInfo visitIncompleteExpr(IncompleteExpr*) { SLANG_UNEXPECTED("a valid ast should not contain an IncompleteExpr."); |
