diff options
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/emit.cpp | 18 | ||||
| -rw-r--r-- | source/slang/ir-insts.h | 36 | ||||
| -rw-r--r-- | source/slang/ir-legalize-types.cpp | 2 | ||||
| -rw-r--r-- | source/slang/ir-ssa.cpp | 19 | ||||
| -rw-r--r-- | source/slang/ir.cpp | 144 | ||||
| -rw-r--r-- | source/slang/ir.h | 23 | ||||
| -rw-r--r-- | source/slang/syntax.cpp | 4 |
7 files changed, 152 insertions, 94 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 335662ab3..a27492c0b 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -5183,7 +5183,7 @@ emitDeclImpl(decl, nullptr); for(UInt aa = 0; aa < argCount; ++aa) { if(aa != 0) emit(", "); - emitIROperand(ctx, args[aa].usedValue, mode); + emitIROperand(ctx, args[aa].get(), mode); } emit(")"); } @@ -5488,7 +5488,7 @@ emitDeclImpl(decl, nullptr); for (UInt aa = 0; aa < argCount; ++aa) { if (aa != 0) Emit(", "); - emitIROperand(ctx, args[aa].usedValue, mode); + emitIROperand(ctx, args[aa].get(), mode); } Emit(")"); return; @@ -5524,7 +5524,7 @@ emitDeclImpl(decl, nullptr); UInt argIndex = d - '0'; SLANG_RELEASE_ASSERT((0 <= argIndex) && (argIndex < argCount)); Emit("("); - emitIROperand(ctx, args[argIndex].usedValue, mode); + emitIROperand(ctx, args[argIndex].get(), mode); Emit(")"); } break; @@ -5536,8 +5536,8 @@ emitDeclImpl(decl, nullptr); // texturing operation. SLANG_RELEASE_ASSERT(argCount >= 2); - auto textureArg = args[0].usedValue; - auto samplerArg = args[1].usedValue; + auto textureArg = args[0].get(); + auto samplerArg = args[1].get(); if (auto baseTextureType = textureArg->type->As<TextureType>()) { @@ -5576,7 +5576,7 @@ emitDeclImpl(decl, nullptr); // // We are going to hack this *hard* for now. - auto textureArg = args[0].usedValue; + auto textureArg = args[0].get(); if (auto baseTextureType = textureArg->type->As<TextureType>()) { emitGLSLTextureOrTextureSamplerType(baseTextureType, "sampler"); @@ -5602,7 +5602,7 @@ emitDeclImpl(decl, nullptr); // shape. SLANG_RELEASE_ASSERT(argCount >= 1); - auto textureArg = args[0].usedValue; + auto textureArg = args[0].get(); if (auto baseTextureType = textureArg->type->As<TextureType>()) { auto elementType = baseTextureType->elementType; @@ -6269,7 +6269,7 @@ emitDeclImpl(decl, nullptr); break; } - IRValue* arg = args[argIndex].usedValue; + IRValue* arg = args[argIndex].get(); emitIROperand(ctx, pp, IREmitMode::Default); emit(" = "); @@ -7142,7 +7142,7 @@ emitDeclImpl(decl, nullptr); if(value->op == kIROp_specialize) { - value = ((IRSpecialize*) value)->genericVal.usedValue; + value = ((IRSpecialize*) value)->genericVal.get(); } if(value->op != kIROp_Func) diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h index eec42d59a..f53004ae4 100644 --- a/source/slang/ir-insts.h +++ b/source/slang/ir-insts.h @@ -124,8 +124,8 @@ struct IRFieldExtract : IRInst IRUse base; IRUse field; - IRValue* getBase() { return base.usedValue; } - IRValue* getField() { return field.usedValue; } + IRValue* getBase() { return base.get(); } + IRValue* getField() { return field.get(); } }; struct IRFieldAddress : IRInst @@ -133,8 +133,8 @@ struct IRFieldAddress : IRInst IRUse base; IRUse field; - IRValue* getBase() { return base.usedValue; } - IRValue* getField() { return field.usedValue; } + IRValue* getBase() { return base.get(); } + IRValue* getField() { return field.get(); } }; // Terminators @@ -146,7 +146,7 @@ struct IRReturnVal : IRReturn { IRUse val; - IRValue* getVal() { return val.usedValue; } + IRValue* getVal() { return val.get(); } }; struct IRReturnVoid : IRReturn @@ -168,7 +168,7 @@ struct IRUnconditionalBranch : IRTerminatorInst { IRUse block; - IRBlock* getTargetBlock() { return (IRBlock*)block.usedValue; } + IRBlock* getTargetBlock() { return (IRBlock*)block.get(); } }; // Special cases of unconditional branch, to handle @@ -191,8 +191,8 @@ struct IRLoop : IRUnconditionalBranch // on a `continue`. IRUse continueBlock; - IRBlock* getBreakBlock() { return (IRBlock*)breakBlock.usedValue; } - IRBlock* getContinueBlock() { return (IRBlock*)continueBlock.usedValue; } + IRBlock* getBreakBlock() { return (IRBlock*)breakBlock.get(); } + IRBlock* getContinueBlock() { return (IRBlock*)continueBlock.get(); } }; struct IRConditionalBranch : IRTerminatorInst @@ -201,9 +201,9 @@ struct IRConditionalBranch : IRTerminatorInst IRUse trueBlock; IRUse falseBlock; - IRValue* getCondition() { return condition.usedValue; } - IRBlock* getTrueBlock() { return (IRBlock*)trueBlock.usedValue; } - IRBlock* getFalseBlock() { return (IRBlock*)falseBlock.usedValue; } + IRValue* getCondition() { return condition.get(); } + IRBlock* getTrueBlock() { return (IRBlock*)trueBlock.get(); } + IRBlock* getFalseBlock() { return (IRBlock*)falseBlock.get(); } }; // A conditional branch that represent the test inside a loop @@ -230,7 +230,7 @@ struct IRIfElse : IRConditionalBranch { IRUse afterBlock; - IRBlock* getAfterBlock() { return (IRBlock*)afterBlock.usedValue; } + IRBlock* getAfterBlock() { return (IRBlock*)afterBlock.get(); } }; // A multi-way branch that represents a source-level `switch` @@ -240,9 +240,9 @@ struct IRSwitch : IRTerminatorInst IRUse breakLabel; IRUse defaultLabel; - IRValue* getCondition() { return condition.usedValue; } - IRBlock* getBreakLabel() { return (IRBlock*) breakLabel.usedValue; } - IRBlock* getDefaultLabel() { return (IRBlock*) defaultLabel.usedValue; } + IRValue* getCondition() { return condition.get(); } + IRBlock* getBreakLabel() { return (IRBlock*) breakLabel.get(); } + IRBlock* getDefaultLabel() { return (IRBlock*) defaultLabel.get(); } // remaining args are: caseVal, caseLabel, ... @@ -255,7 +255,7 @@ struct IRSwizzle : IRReturn { IRUse base; - IRValue* getBase() { return base.usedValue; } + IRValue* getBase() { return base.get(); } UInt getElementCount() { return getArgCount() - 1; @@ -271,8 +271,8 @@ struct IRSwizzleSet : IRReturn IRUse base; IRUse source; - IRValue* getBase() { return base.usedValue; } - IRValue* getSource() { return source.usedValue; } + IRValue* getBase() { return base.get(); } + IRValue* getSource() { return source.get(); } UInt getElementCount() { return getArgCount() - 2; diff --git a/source/slang/ir-legalize-types.cpp b/source/slang/ir-legalize-types.cpp index 4e3bafd31..2e69898e5 100644 --- a/source/slang/ir-legalize-types.cpp +++ b/source/slang/ir-legalize-types.cpp @@ -232,7 +232,7 @@ static LegalVal legalizeCall( return LegalVal::simple(context->builder->emitCallInst( callInst->type, - callInst->func.usedValue, + callInst->func.get(), instArgs.Count(), instArgs.Buffer())); } diff --git a/source/slang/ir-ssa.cpp b/source/slang/ir-ssa.cpp index d58fd22e4..432dfc1b1 100644 --- a/source/slang/ir-ssa.cpp +++ b/source/slang/ir-ssa.cpp @@ -110,7 +110,7 @@ bool isPromotableVar( for (auto u = var->firstUse; u; u = u->nextUse) { - auto user = u->user; + auto user = u->getUser(); switch (user->op) { default: @@ -231,7 +231,7 @@ IRValue* tryRemoveTrivialPhi( IRValue* same = nullptr; for (auto u : phiInfo->operands) { - auto usedVal = u.usedValue; + auto usedVal = u.get(); assert(usedVal); if (usedVal == same || usedVal == phi) @@ -542,8 +542,8 @@ void processBlock( case kIROp_Store: { auto storeInst = (IRStore*)ii; - auto ptrArg = storeInst->ptr.usedValue; - auto valArg = storeInst->val.usedValue; + auto ptrArg = storeInst->ptr.get(); + auto valArg = storeInst->val.get(); if (auto var = asPromotableVar(context, ptrArg)) { @@ -563,7 +563,7 @@ void processBlock( case kIROp_Load: { IRLoad* loadInst = (IRLoad*)ii; - auto ptrArg = loadInst->ptr.usedValue; + auto ptrArg = loadInst->ptr.get(); if (auto var = asPromotableVar(context, ptrArg)) { @@ -669,10 +669,10 @@ static void breakCriticalEdges( for (auto edgeUse : criticalEdges) { - auto pred = (IRBlock*) edgeUse->user->parent; + auto pred = (IRBlock*) edgeUse->getUser()->parent; assert(pred->op == kIROp_Block); - auto succ = (IRBlock*)edgeUse->usedValue; + auto succ = (IRBlock*)edgeUse->get(); assert(succ->op == kIROp_Block); IRBuilder builder; @@ -683,6 +683,8 @@ static void breakCriticalEdges( // Create a new block that will sit "along" the edge IRBlock* edgeBlock = builder.createBlock(); + edgeUse->debugValidate(); + // The predecessor block should now branch to // the edge block. edgeUse->set(edgeBlock); @@ -709,7 +711,6 @@ void constructSSA(ConstructSSAContext* context) // because our representation of SSA form doesn't allow for them. breakCriticalEdges(context); - // Figure out what variables we can promote to // SSA temporaries. identifyPromotableVars(context); @@ -766,7 +767,7 @@ void constructSSA(ConstructSSAContext* context) UInt predIndex = predCounter++; auto predInfo = *context->blockInfos.TryGetValue(pp); - IRValue* operandVal = phiInfo->operands[predIndex].usedValue; + IRValue* operandVal = phiInfo->operands[predIndex].get(); phiInfo->operands[predIndex].clear(); diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp index 40c7e20d5..50b0b83e9 100644 --- a/source/slang/ir.cpp +++ b/source/slang/ir.cpp @@ -59,41 +59,81 @@ namespace Slang // + void IRUse::debugValidate() + { +#ifdef _DEBUG + auto uv = this->usedValue; + if(!uv) + { + assert(!user); + assert(!nextUse); + assert(!prevLink); + return; + } + + auto pp = &uv->firstUse; + for(auto u = uv->firstUse; u;) + { + assert(u->prevLink == pp); + + pp = &u->nextUse; + u = u->nextUse; + } +#endif + } + void IRUse::init(IRUser* u, IRValue* v) { + clear(); + user = u; usedValue = v; - if(v) { nextUse = v->firstUse; prevLink = &v->firstUse; + if(nextUse) + { + nextUse->prevLink = &this->nextUse; + } + v->firstUse = this; } + + debugValidate(); } - void IRUse::set(IRValue* usedVal) + void IRUse::set(IRValue* uv) { - // clear out the old value - if (usedVal) - { - if (prevLink) - *prevLink = nextUse; - } - - init(user, usedVal); + init(user, uv); } void IRUse::clear() { + // This `IRUse` is part of the linked list + // of uses for `usedValue`. + + debugValidate(); + if (usedValue) { + auto uv = usedValue; + *prevLink = nextUse; - } + if(nextUse) + { + nextUse->prevLink = prevLink; + } + + user = nullptr; + usedValue = nullptr; + nextUse = nullptr; + prevLink = nullptr; - user = nullptr; - usedValue = nullptr; + if(uv->firstUse) + uv->firstUse->debugValidate(); + } } // @@ -250,7 +290,7 @@ namespace Slang // We will re-use the logic for getting the successor // list from such an instruction. - auto successorList = getSuccessors((IRInst*) use->user); + auto successorList = getSuccessors((IRInst*) use->getUser()); if(use >= successorList.begin_ && use < successorList.end_) @@ -315,7 +355,7 @@ namespace Slang IRBlock* IRBlock::PredecessorList::Iterator::operator*() { if (!use) return nullptr; - return (IRBlock*)use->user->parent; + return (IRBlock*)use->getUser()->parent; } IRBlock::SuccessorList IRBlock::getSuccessors() @@ -351,7 +391,7 @@ namespace Slang IRBlock* IRBlock::SuccessorList::Iterator::operator*() { - return (IRBlock*)use->usedValue; + return (IRBlock*)use->get(); } // IRFunc @@ -714,7 +754,7 @@ namespace Slang auto rightArgs = right.inst->getArgs(); for( UInt aa = 0; aa < argCount; ++aa ) { - if(leftArgs[aa].usedValue != rightArgs[aa].usedValue) + if(leftArgs[aa].get() != rightArgs[aa].get()) return false; } @@ -731,7 +771,7 @@ namespace Slang auto args = inst->getArgs(); for( UInt aa = 0; aa < argCount; ++aa ) { - code = combineHash(code, Slang::GetHashCode(args[aa].usedValue)); + code = combineHash(code, Slang::GetHashCode(args[aa].get())); } return code; } @@ -1894,7 +1934,7 @@ namespace Slang } else if (auto proxyVal = dynamic_cast<IRProxyVal*>(val)) { - dumpOperand(context, proxyVal->inst.usedValue); + dumpOperand(context, proxyVal->inst.get()); } else { @@ -2283,7 +2323,7 @@ namespace Slang if (ii != 0) dump(context, ", "); - auto argVal = inst->getArgs()[ii].usedValue; + auto argVal = inst->getArgs()[ii].get(); dumpOperand(context, argVal); } @@ -2449,9 +2489,9 @@ namespace Slang IRWitnessTableEntry* entry) { dump(context, "witness_table_entry("); - dumpOperand(context, entry->requirementKey.usedValue); + dumpOperand(context, entry->requirementKey.get()); dump(context, ","); - dumpOperand(context, entry->satisfyingVal.usedValue); + dumpOperand(context, entry->satisfyingVal.get()); dump(context, ")\n"); } @@ -2522,6 +2562,20 @@ namespace Slang dumpIRModule(&context, module); } + void dumpIR(IRGlobalValue* globalVal) + { + StringBuilder sb; + + IRDumpContext context; + context.builder = &sb; + context.indent = 0; + + dumpIRGlobalValue(&context, globalVal); + + fprintf(stderr, "%s\n", sb.Buffer()); + fflush(stderr); + } + String getSlangIRAssembly(IRModule* module) { StringBuilder sb; @@ -2551,12 +2605,14 @@ namespace Slang if(!ff) return; + ff->debugValidate(); + IRUse* uu = ff; for(;;) { // The uses had better all be uses of this // instruction, or invariants are broken. - assert(uu->usedValue == this); + assert(uu->get() == this); // Swap this use over to use the other value. uu->usedValue = other; @@ -2597,6 +2653,8 @@ namespace Slang // And `this` will have no uses any more. this->firstUse = nullptr; + + ff->debugValidate(); } void IRValue::deallocate() @@ -2684,15 +2742,7 @@ namespace Slang for( UInt aa = 0; aa < argCount; ++aa ) { IRUse& use = getArgs()[aa]; - - if(!use.usedValue) - continue; - - // Need to unlink this use from the appropriate linked list. - use.usedValue = nullptr; - *use.prevLink = use.nextUse; - use.prevLink = nullptr; - use.nextUse = nullptr; + use.clear(); } } @@ -3616,7 +3666,7 @@ namespace Slang { auto proxyVal = witness.Value.As<IRProxyVal>(); SLANG_ASSERT(proxyVal); - return proxyVal->inst.usedValue; + return proxyVal->inst.get(); } } } @@ -3651,7 +3701,7 @@ namespace Slang { if (auto proxyVal = dynamic_cast<IRProxyVal*>(val)) { - auto newIRVal = cloneValue(context, proxyVal->inst.usedValue); + auto newIRVal = cloneValue(context, proxyVal->inst.get()); RefPtr<IRProxyVal> newProxyVal = new IRProxyVal(); newProxyVal->inst.init(nullptr, newIRVal); @@ -3879,10 +3929,10 @@ namespace Slang // Clone the entries in the witness table as well for( auto originalEntry : originalTable->entries ) { - auto clonedKey = cloneValue(context, originalEntry->requirementKey.usedValue); + auto clonedKey = cloneValue(context, originalEntry->requirementKey.get()); // if a global val with the mangled name already exists, don't clone again - auto clonedVal = maybeCloneValueWithMangledName(context, (IRGlobalValue*)(originalEntry->satisfyingVal.usedValue)); + auto clonedVal = maybeCloneValueWithMangledName(context, (IRGlobalValue*)(originalEntry->satisfyingVal.get())); /*auto clonedEntry = */context->builder->createWitnessTableEntry( clonedTable, @@ -4643,7 +4693,7 @@ namespace Slang // the pointed-to value and not the proxy type-level `Val` // instead. - return context->maybeCloneValue(proxyVal->inst.usedValue); + return context->maybeCloneValue(proxyVal->inst.get()); } else { @@ -4905,9 +4955,9 @@ namespace Slang // of involved functions. for (auto entry : specTable->entries) { - if (entry->satisfyingVal.usedValue->op == kIROp_Func) + if (entry->satisfyingVal.get()->op == kIROp_Func) { - IRFunc* func = (IRFunc*)entry->satisfyingVal.usedValue; + IRFunc* func = (IRFunc*)entry->satisfyingVal.get(); auto specFunc = getSpecializedFunc(sharedContext, func, specDeclRef); entry->satisfyingVal.set(specFunc); insertGlobalValueSymbol(sharedContext, specFunc); @@ -5016,7 +5066,7 @@ namespace Slang { // We expect the key on the entry to be a decl-ref, // but lets go ahead and check, just to be sure. - auto requirementKey = entry->requirementKey.usedValue; + auto requirementKey = entry->requirementKey.get(); if(requirementKey->op != kIROp_decl_ref) continue; auto keyDeclRef = ((IRDeclRef*) requirementKey)->declRef; @@ -5039,7 +5089,7 @@ namespace Slang // If the keys matched, then we use the value from // this entry. - auto satisfyingVal = entry->satisfyingVal.usedValue; + auto satisfyingVal = entry->satisfyingVal.get(); return satisfyingVal; } @@ -5147,11 +5197,11 @@ namespace Slang // Now we extract the specialized decl-ref that will // tell us how to specialize things. - auto specDeclRefVal = (IRDeclRef*)specInst->specDeclRefVal.usedValue; + auto specDeclRefVal = (IRDeclRef*)specInst->specDeclRefVal.get(); auto specDeclRef = specDeclRefVal->declRef; // We need to specialize functions and witness tables - auto genericVal = specInst->genericVal.usedValue; + auto genericVal = specInst->genericVal.get(); if (genericVal->op == kIROp_Func) { auto genericFunc = (IRFunc*)genericVal; @@ -5187,8 +5237,8 @@ namespace Slang // try find concrete witness table from global scope IRLookupWitnessTable* lookupInst = (IRLookupWitnessTable*)ii; IRWitnessTable* witnessTable = nullptr; - auto srcDeclRef = ((IRDeclRef*)lookupInst->sourceType.usedValue)->declRef; - auto interfaceDeclRef = ((IRDeclRef*)lookupInst->interfaceType.usedValue)->declRef; + auto srcDeclRef = ((IRDeclRef*)lookupInst->sourceType.get())->declRef; + auto interfaceDeclRef = ((IRDeclRef*)lookupInst->interfaceType.get())->declRef; auto mangledName = getMangledNameForConformanceWitness(srcDeclRef, interfaceDeclRef); witnessTables.TryGetValue(mangledName, witnessTable); @@ -5221,14 +5271,14 @@ namespace Slang // We only want to deal with the case where the witness-table // argument points to a concrete global table. - auto witnessTableArg = lookupInst->witnessTable.usedValue; + auto witnessTableArg = lookupInst->witnessTable.get(); if(witnessTableArg->op != kIROp_witness_table) continue; IRWitnessTable* witnessTable = (IRWitnessTable*)witnessTableArg; // We also need to be sure that the requirement we // are trying to look up is identified via a decl-ref: - auto requirementArg = lookupInst->requirementDeclRef.usedValue; + auto requirementArg = lookupInst->requirementDeclRef.get(); if(requirementArg->op != kIROp_decl_ref) continue; auto requirementDeclRef = ((IRDeclRef*) requirementArg)->declRef; diff --git a/source/slang/ir.h b/source/slang/ir.h index 028468308..407506116 100644 --- a/source/slang/ir.h +++ b/source/slang/ir.h @@ -82,22 +82,27 @@ IROpInfo getIROpInfo(IROp op); // A use of another value/inst within an IR operation struct IRUse { + IRValue* get() { return usedValue; } + IRUser* getUser() { return user; } + + void init(IRUser* user, IRValue* usedValue); + void set(IRValue* usedValue); + void clear(); + // The value that is being used - IRValue* usedValue; + IRValue* usedValue = nullptr; // The value that is doing the using. - IRUser* user; + IRUser* user = nullptr; // The next use of the same value - IRUse* nextUse; + IRUse* nextUse = nullptr; // A "link" back to where this use is referenced, // so that we can simplify updates. - IRUse** prevLink; + IRUse** prevLink = nullptr; - void init(IRUser* user, IRValue* usedValue); - void set(IRValue* usedValue); - void clear(); + void debugValidate(); }; enum IRDecorationOp : uint16_t @@ -262,7 +267,7 @@ struct IRUser : IRChildValue IRValue* getArg(UInt index) { - return getArgs()[index].usedValue; + return getArgs()[index].get(); } void setArg(UInt index, IRValue* value) @@ -542,6 +547,8 @@ void printSlangIRAssembly(StringBuilder& builder, IRModule* module); String getSlangIRAssembly(IRModule* module); void dumpIR(IRModule* module); +void dumpIR(IRGlobalValue* globalVal); + String dumpIRFunc(IRFunc* func); } diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index d83a91938..e050fc977 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -1888,7 +1888,7 @@ void Type::accept(IValVisitor* visitor, void* extra) if(!otherProxy) return false; - return this->inst.usedValue == otherProxy->inst.usedValue; + return this->inst.get() == otherProxy->inst.get(); } String IRProxyVal::ToString() @@ -1898,7 +1898,7 @@ void Type::accept(IValVisitor* visitor, void* extra) int IRProxyVal::GetHashCode() { - auto hash = Slang::GetHashCode(inst.usedValue); + auto hash = Slang::GetHashCode(inst.get()); return hash; } |
