summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-addr-inst-elimination.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-01-25 17:27:40 -0800
committerGitHub <noreply@github.com>2023-01-25 17:27:40 -0800
commit1f4c7cab13341c2e9d48df2b01ed2c048c17c152 (patch)
treeed85dda63e1c939cf474961b965b7cc1883940bb /source/slang/slang-ir-addr-inst-elimination.cpp
parentaa6814be1f7dea20597ae34d477e79e53d4a543f (diff)
Unify UpdateField and UpdateElement with access chain. (#2611)
* Unify UpdateField and UpdateElement with access chain. * Fix warnings. Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-addr-inst-elimination.cpp')
-rw-r--r--source/slang/slang-ir-addr-inst-elimination.cpp61
1 files changed, 9 insertions, 52 deletions
diff --git a/source/slang/slang-ir-addr-inst-elimination.cpp b/source/slang/slang-ir-addr-inst-elimination.cpp
index 877be1406..a5e0e0a4e 100644
--- a/source/slang/slang-ir-addr-inst-elimination.cpp
+++ b/source/slang/slang-ir-addr-inst-elimination.cpp
@@ -36,72 +36,29 @@ struct AddressInstEliminationContext
void storeValue(IRBuilder& builder, IRInst* addr, IRInst* val)
{
- List<IRInst*> baseAddrs;
+ List<IRInst*> accessChain;
for (auto inst = addr; inst;)
{
switch (inst->getOp())
{
default:
- baseAddrs.add(inst);
+ accessChain.add(inst);
goto endLoop;
case kIROp_GetElementPtr:
case kIROp_FieldAddress:
- baseAddrs.add(inst);
+ accessChain.add(inst->getOperand(1));
inst = inst->getOperand(0);
break;
}
}
endLoop:;
- List<IRInst*> values;
- values.setCount(baseAddrs.getCount());
- if (values.getCount() > 1)
- {
- IRInst* currentVal = builder.emitLoad(baseAddrs.getLast());
- values.getLast() = currentVal;
- for (Index i = baseAddrs.getCount() - 2; i >= 1; i--)
- {
- auto inst = baseAddrs[i];
- switch (inst->getOp())
- {
- default:
- sink->diagnose(inst->sourceLoc, Diagnostics::unsupportedUseOfLValueForAutoDiff);
- return;
- case kIROp_GetElementPtr:
- case kIROp_FieldAddress:
- {
- IRInst* args[] = { currentVal, inst->getOperand(1) };
- currentVal = builder.emitIntrinsicInst(
- cast<IRPtrTypeBase>(inst->getFullType())->getValueType(),
- (inst->getOp() == kIROp_GetElementPtr ? kIROp_GetElement : kIROp_FieldExtract),
- 2,
- args);
- values[i] = currentVal;
- }
- break;
- }
- }
- }
- values[0] = val;
- for (Index i = 1; i < values.getCount(); i++)
- {
- auto inst = baseAddrs[i - 1];
- switch (inst->getOp())
- {
- case kIROp_GetElementPtr:
- case kIROp_FieldAddress:
- {
- IRInst* args[] = {values[i], inst->getOperand(1), values[i - 1]};
- values[i] = builder.emitIntrinsicInst(
- values[i]->getFullType(),
- (inst->getOp() == kIROp_GetElementPtr ? kIROp_UpdateElement : kIROp_UpdateField),
- 3,
- args);
- }
- break;
- }
- }
- builder.emitStore(baseAddrs.getLast(), values.getLast());
+ auto lastAddr = accessChain.getLast();
+ auto lastVal = builder.emitLoad(lastAddr);
+ accessChain.removeLast();
+ accessChain.reverse();
+ auto update = builder.emitUpdateElement(lastVal, accessChain, val);
+ builder.emitStore(lastAddr, update);
}
void transformLoadAddr(IRUse* use)