diff options
| author | kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> | 2025-05-15 11:59:15 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-15 09:59:15 -0700 |
| commit | b325474c4aba52cca7e0bcd4eae02d23ca4ab9a3 (patch) | |
| tree | d0790bb56bec865743c95895aedaeb14f63312d7 /source/slang/slang-ir-util.cpp | |
| parent | ed837e205f3e67c4ae112f544cfe486ca3cc8455 (diff) | |
Implement spec const for generic parameter (#7121)
Close #6840.
This PR add supports to use specialize constant in generic parameter, and that parameter can also be used as array size, e.g. following code should work:
```
struct MyStruct<let N: int> { float buffer[N]; }
MyStruct<SpecConstVar> s;
```
- Loose the restriction from Link-Time to SpecializationConstant when extract generic argument
- Tweak the logic of how we decide whether a inst is hoistable. Besides checking existing hoistable flag of each
IRInst, when we detect a IRInst's type is SpecConstRateType, we will treat that inst hoistable. Because IRInst in
global scope can be deduplicated, and every SpecConstRateType inst should be in the global scope or IRGeneric
scope (which will be at global scope after specialization).
- Remove the SpecConstIntVal to IRInst map in IR lowering logic, because we already have way to deduplicate the
global scope IR.
Diffstat (limited to 'source/slang/slang-ir-util.cpp')
| -rw-r--r-- | source/slang/slang-ir-util.cpp | 75 |
1 files changed, 67 insertions, 8 deletions
diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp index 9d8773237..c8faec73b 100644 --- a/source/slang/slang-ir-util.cpp +++ b/source/slang/slang-ir-util.cpp @@ -2261,16 +2261,75 @@ bool isSpecConstRateType(IRType* type) } return false; } -void hoistInstAndOperandsToGlobal(IRBuilder* builder, IRInst* inst) + +IRType* maybeAddRateType(IRBuilder* builder, IRType* rateQulifiedType, IRType* oldType) { - IRInst* moduleInst = builder->getModule()->getModuleInst(); - UInt operandCount = inst->getOperandCount(); - for (UInt ii = 0; ii < operandCount; ++ii) + if (as<IRRateQualifiedType>(oldType)) { - auto operand = inst->getOperand(ii); - if (operand->parent != moduleInst) - hoistInstAndOperandsToGlobal(builder, operand); + return oldType; } - inst->insertAt(IRInsertLoc::atStart(moduleInst)); + + if (isSpecConstRateType(rateQulifiedType)) + { + return builder->getRateQualifiedType(builder->getSpecConstRate(), oldType); + } + return oldType; +} + +bool isArithmeticInst(IROp op) +{ + switch (op) + { + case kIROp_Add: + case kIROp_Sub: + case kIROp_Mul: + case kIROp_Div: + case kIROp_Neg: + case kIROp_Not: + case kIROp_Eql: + case kIROp_Neq: + case kIROp_Leq: + case kIROp_Geq: + case kIROp_Less: + case kIROp_IRem: + case kIROp_FRem: + case kIROp_Greater: + case kIROp_Lsh: + case kIROp_Rsh: + case kIROp_BitAnd: + case kIROp_BitOr: + case kIROp_BitXor: + case kIROp_BitNot: + case kIROp_BitCast: + case kIROp_CastIntToFloat: + case kIROp_CastFloatToInt: + case kIROp_IntCast: + case kIROp_FloatCast: + case kIROp_Select: + return true; + default: + return false; + } +} +bool isArithmeticInst(IRInst* inst) +{ + return isArithmeticInst(inst->getOp()); +} + +bool isInstHoistable(IROp op, IRType* type) +{ + if ((getIROpInfo(op).flags & kIROpFlag_Hoistable)) + { + return true; + } + + if (isArithmeticInst(op)) + { + if (type && isSpecConstRateType(type)) + { + return true; + } + } + return false; } } // namespace Slang |
