diff options
Diffstat (limited to 'source/slang/ir.cpp')
| -rw-r--r-- | source/slang/ir.cpp | 1152 |
1 files changed, 478 insertions, 674 deletions
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp index 8dc158b6c..b4d19c0d5 100644 --- a/source/slang/ir.cpp +++ b/source/slang/ir.cpp @@ -82,7 +82,7 @@ namespace Slang #endif } - void IRUse::init(IRUser* u, IRValue* v) + void IRUse::init(IRInst* u, IRInst* v) { clear(); @@ -104,7 +104,7 @@ namespace Slang debugValidate(); } - void IRUse::set(IRValue* uv) + void IRUse::set(IRInst* uv) { init(user, uv); } @@ -138,7 +138,7 @@ namespace Slang // - IRUse* IRUser::getArgs() + IRUse* IRInst::getOperands() { // We assume that *all* instructions are laid out // in memory such that their arguments come right @@ -150,7 +150,7 @@ namespace Slang return (IRUse*)(this + 1); } - IRDecoration* IRValue::findDecorationImpl(IRDecorationOp decorationOp) + IRDecoration* IRInst::findDecorationImpl(IRDecorationOp decorationOp) { for( auto dd = firstDecoration; dd; dd = dd->next ) { @@ -160,20 +160,37 @@ namespace Slang return nullptr; } + // IRParam + + IRParam* IRParam::getNextParam() + { + return as<IRParam>(getNextInst()); + } + // IRBlock + IRParam* IRBlock::getLastParam() + { + IRParam* param = getFirstParam(); + if (!param) return nullptr; + + while (auto nextParam = param->getNextParam()) + param = nextParam; + + return param; + } + void IRBlock::addParam(IRParam* param) { - if (auto lp = lastParam) + auto lastParam = getLastParam(); + if (lastParam) { - lp->nextParam = param; - param->prevParam = lp; + param->insertAfter(lastParam); } else { - firstParam = param; + param->insertAtStart(this); } - lastParam = param; } // The predecessors of a block should all show up as users @@ -191,7 +208,7 @@ namespace Slang // If the block somehow isn't terminated, then // there is no way to read its successors, so // we return an empty list. - if (!terminator || !isTerminatorInst(terminator)) + if (!terminator || !as<IRTerminatorInst>(terminator)) return IRBlock::SuccessorList(nullptr, nullptr); // Otherwise, based on the opcode of the terminator @@ -200,7 +217,7 @@ namespace Slang IRUse* end = nullptr; UInt stride = 1; - auto args = terminator->getArgs(); + auto operands = terminator->getOperands(); switch (terminator->op) { case kIROp_ReturnVal: @@ -212,21 +229,25 @@ namespace Slang case kIROp_unconditionalBranch: case kIROp_loop: // unconditonalBranch <block> - begin = args + 0; + begin = operands + 0; end = begin + 1; break; case kIROp_conditionalBranch: case kIROp_ifElse: // conditionalBranch <condition> <trueBlock> <falseBlock> - begin = args + 1; + begin = operands + 1; end = begin + 2; break; case kIROp_switch: // switch <val> <break> <default> <caseVal1> <caseBlock1> ... - begin = args + 4; - end = args + terminator->getArgCount() + 1; + begin = operands + 4; + + // TODO: this ends up point one *after* the "one after the end" + // location, so we should really change the representation + // so that we don't need to form this pointer... + end = operands + terminator->getOperandCount() + 1; stride = 2; break; @@ -238,47 +259,6 @@ namespace Slang return IRBlock::SuccessorList(begin, end, stride); } - void IRBlock::insertAfter(IRBlock* other) - { - assert(other); - insertAfter(other, other->parentFunc); - } - - void IRBlock::insertAfter(IRBlock* other, IRGlobalValueWithCode* func) - { - assert(other || func); - - if (!other) other = func->lastBlock; - if (!func) func = other->parentFunc; - - assert(func); - - auto pp = other; - auto nn = other ? other->nextBlock : nullptr; - - if (pp) - { - pp->nextBlock = this; - } - else - { - func->firstBlock = this; - } - - if (nn) - { - nn->prevBlock = this; - } - else - { - func->lastBlock = this; - } - - this->prevBlock = pp; - this->nextBlock = nn; - this->parentFunc = func; - } - static IRUse* adjustPredecessorUse(IRUse* use) { // We will search until we either find a @@ -410,18 +390,7 @@ namespace Slang void IRGlobalValueWithCode::addBlock(IRBlock* block) { - block->parentFunc = this; - - if (auto lb = lastBlock) - { - lb->nextBlock = block; - block->prevBlock = lb; - } - else - { - firstBlock = block; - } - lastBlock = block; + block->insertAtEnd(this); } // @@ -454,52 +423,6 @@ namespace Slang // - void IRValueListBase::addImpl(IRValue* parent, IRChildValue* val) - { - val->parent = parent; - val->prev = last; - val->next = nullptr; - - if (last) - { - last->next = val; - } - else - { - first = val; - } - - last = val; - } - - - // - - // Add an instruction to a specific parent - void IRBuilder::addInst(IRBlock* pblock, IRInst* inst) - { - inst->parent = pblock; - - if (!pblock->firstInst) - { - inst->prev = nullptr; - inst->next = nullptr; - - pblock->firstInst = inst; - pblock->lastInst = inst; - } - else - { - auto prev = pblock->lastInst; - - inst->prev = prev; - inst->next = nullptr; - - prev->next = inst; - pblock->lastInst = inst; - } - } - // Add an instruction into the current scope void IRBuilder::addInst( IRInst* inst) @@ -509,17 +432,19 @@ namespace Slang inst->insertBefore(insertBeforeInst); return; } - - auto parent = curBlock; - if (!parent) - return; - - addInst(parent, inst); + else if (curBlock) + { + inst->insertAtEnd(curBlock); + } + else + { + // Don't append the instruction anywhere + } } static void maybeSetSourceLoc( IRBuilder* builder, - IRValue* value) + IRInst* value) { if(!builder) return; @@ -566,20 +491,21 @@ namespace Slang // argument for all instructions). template<typename T> static T* createInstImpl( + IRModule* module, IRBuilder* builder, UInt size, IROp op, IRType* type, UInt fixedArgCount, - IRValue* const* fixedArgs, + IRInst* const* fixedArgs, UInt varArgCount = 0, - IRValue* const* varArgs = nullptr) + IRInst* const* varArgs = nullptr) { - assert(builder->getModule()); - T* inst = (T*)builder->getModule()->memoryPool.allocZero(size); + assert(module); + T* inst = (T*)module->memoryPool.allocZero(size); new(inst)T(); - inst->argCount = (uint32_t)(fixedArgCount + varArgCount); + inst->operandCount = (uint32_t)(fixedArgCount + varArgCount); inst->op = op; @@ -587,7 +513,7 @@ namespace Slang maybeSetSourceLoc(builder, inst); - auto operand = inst->getArgs(); + auto operand = inst->getOperands(); for( UInt aa = 0; aa < fixedArgCount; ++aa ) { @@ -606,17 +532,40 @@ namespace Slang } operand++; } - builder->getModule()->irObjectsToFree.Add(inst); + module->irObjectsToFree.Add(inst); return inst; } template<typename T> + static T* createInstImpl( + IRBuilder* builder, + UInt size, + IROp op, + IRType* type, + UInt fixedArgCount, + IRInst* const* fixedArgs, + UInt varArgCount = 0, + IRInst* const* varArgs = nullptr) + { + return createInstImpl<T>( + builder->getModule(), + builder, + size, + op, + type, + fixedArgCount, + fixedArgs, + varArgCount, + varArgs); + } + + template<typename T> static T* createInst( IRBuilder* builder, IROp op, IRType* type, UInt argCount, - IRValue* const* args) + IRInst* const* args) { return createInstImpl<T>( builder, @@ -647,7 +596,7 @@ namespace Slang IRBuilder* builder, IROp op, IRType* type, - IRValue* arg) + IRInst* arg) { return createInstImpl<T>( builder, @@ -663,10 +612,10 @@ namespace Slang IRBuilder* builder, IROp op, IRType* type, - IRValue* arg1, - IRValue* arg2) + IRInst* arg1, + IRInst* arg2) { - IRValue* args[] = { arg1, arg2 }; + IRInst* args[] = { arg1, arg2 }; return createInstImpl<T>( builder, sizeof(T), @@ -682,7 +631,7 @@ namespace Slang IROp op, IRType* type, UInt argCount, - IRValue* const* args) + IRInst* const* args) { return createInstImpl<T>( builder, @@ -699,9 +648,9 @@ namespace Slang IROp op, IRType* type, UInt fixedArgCount, - IRValue* const* fixedArgs, + IRInst* const* fixedArgs, UInt varArgCount, - IRValue* const* varArgs) + IRInst* const* varArgs) { return createInstImpl<T>( builder, @@ -719,11 +668,11 @@ namespace Slang IRBuilder* builder, IROp op, IRType* type, - IRValue* arg1, + IRInst* arg1, UInt varArgCount, - IRValue* const* varArgs) + IRInst* const* varArgs) { - IRValue* fixedArgs[] = { arg1 }; + IRInst* fixedArgs[] = { arg1 }; UInt fixedArgCount = sizeof(fixedArgs) / sizeof(fixedArgs[0]); return createInstImpl<T>( @@ -742,11 +691,11 @@ namespace Slang { if(left.inst->op != right.inst->op) return false; if(left.inst->parent != right.inst->parent) return false; - if(left.inst->argCount != right.inst->argCount) return false; + if(left.inst->operandCount != right.inst->operandCount) return false; - auto argCount = left.inst->argCount; - auto leftArgs = left.inst->getArgs(); - auto rightArgs = right.inst->getArgs(); + auto argCount = left.inst->operandCount; + auto leftArgs = left.inst->getOperands(); + auto rightArgs = right.inst->getOperands(); for( UInt aa = 0; aa < argCount; ++aa ) { if(leftArgs[aa].get() != rightArgs[aa].get()) @@ -760,10 +709,10 @@ namespace Slang { auto code = Slang::GetHashCode(inst->op); code = combineHash(code, Slang::GetHashCode(inst->parent)); - code = combineHash(code, Slang::GetHashCode(inst->argCount)); + code = combineHash(code, Slang::GetHashCode(inst->getOperandCount())); - auto argCount = inst->argCount; - auto args = inst->getArgs(); + auto argCount = inst->getOperandCount(); + auto args = inst->getOperands(); for( UInt aa = 0; aa < argCount; ++aa ) { code = combineHash(code, Slang::GetHashCode(args[aa].get())); @@ -838,7 +787,7 @@ namespace Slang // - IRValue* IRBuilder::getBoolValue(bool inValue) + IRInst* IRBuilder::getBoolValue(bool inValue) { IRIntegerValue value = inValue; return findOrEmitConstant( @@ -849,7 +798,7 @@ namespace Slang &value); } - IRValue* IRBuilder::getIntValue(IRType* type, IRIntegerValue value) + IRInst* IRBuilder::getIntValue(IRType* type, IRIntegerValue value) { return findOrEmitConstant( this, @@ -859,7 +808,7 @@ namespace Slang &value); } - IRValue* IRBuilder::getFloatValue(IRType* type, IRFloatingPointValue value) + IRInst* IRBuilder::getFloatValue(IRType* type, IRFloatingPointValue value) { return findOrEmitConstant( this, @@ -881,7 +830,7 @@ namespace Slang return inst; } - IRValue* IRBuilder::getDeclRefVal( + IRInst* IRBuilder::getDeclRefVal( DeclRefBase const& declRef) { // TODO: we should cache these... @@ -893,9 +842,9 @@ namespace Slang return irValue; } - IRValue * IRBuilder::getTypeVal(IRType * type) + IRInst* IRBuilder::getTypeVal(IRType * type) { - auto irValue = createValue<IRValue>( + auto irValue = createValue<IRInst>( this, kIROp_TypeType, nullptr); @@ -905,10 +854,10 @@ namespace Slang return irValue; } - IRValue* IRBuilder::emitSpecializeInst( + IRInst* IRBuilder::emitSpecializeInst( Type* type, - IRValue* genericVal, - IRValue* specDeclRef) + IRInst* genericVal, + IRInst* specDeclRef) { auto inst = createInst<IRSpecialize>( this, @@ -920,9 +869,9 @@ namespace Slang return inst; } - IRValue* IRBuilder::emitSpecializeInst( + IRInst* IRBuilder::emitSpecializeInst( Type* type, - IRValue* genericVal, + IRInst* genericVal, DeclRef<Decl> specDeclRef) { auto specDeclRefVal = getDeclRefVal(specDeclRef); @@ -936,10 +885,10 @@ namespace Slang return inst; } - IRValue* IRBuilder::emitLookupInterfaceMethodInst( - IRType* type, - IRValue* witnessTableVal, - IRValue* interfaceMethodVal) + IRInst* IRBuilder::emitLookupInterfaceMethodInst( + IRType* type, + IRInst* witnessTableVal, + IRInst* interfaceMethodVal) { auto inst = createInst<IRLookupWitnessMethod>( this, @@ -951,7 +900,7 @@ namespace Slang return inst; } - IRValue* IRBuilder::emitLookupInterfaceMethodInst( + IRInst* IRBuilder::emitLookupInterfaceMethodInst( IRType* type, DeclRef<Decl> witnessTableDeclRef, DeclRef<Decl> interfaceMethodDeclRef) @@ -963,9 +912,9 @@ namespace Slang return emitLookupInterfaceMethodInst(type, witnessTableVal, interfaceMethodVal); } - IRValue* IRBuilder::emitLookupInterfaceMethodInst( + IRInst* IRBuilder::emitLookupInterfaceMethodInst( IRType* type, - IRValue* witnessTableVal, + IRInst* witnessTableVal, DeclRef<Decl> interfaceMethodDeclRef) { DeclRef<Decl> removeSubstDeclRef = interfaceMethodDeclRef; @@ -974,7 +923,7 @@ namespace Slang return emitLookupInterfaceMethodInst(type, witnessTableVal, interfaceMethodVal); } - IRValue* IRBuilder::emitFindWitnessTable( + IRInst* IRBuilder::emitFindWitnessTable( DeclRef<Decl> baseTypeDeclRef, IRType* interfaceType) { @@ -992,9 +941,9 @@ namespace Slang IRInst* IRBuilder::emitCallInst( IRType* type, - IRValue* pFunc, + IRInst* pFunc, UInt argCount, - IRValue* const* args) + IRInst* const* args) { auto inst = createInstWithTrailingArgs<IRCall>( this, @@ -1012,7 +961,7 @@ namespace Slang IRType* type, IROp op, UInt argCount, - IRValue* const* args) + IRInst* const* args) { auto inst = createInstWithTrailingArgs<IRInst>( this, @@ -1027,7 +976,7 @@ namespace Slang IRInst* IRBuilder::emitConstructorInst( IRType* type, UInt argCount, - IRValue* const* args) + IRInst* const* args) { auto inst = createInstWithTrailingArgs<IRInst>( this, @@ -1042,7 +991,7 @@ namespace Slang IRInst* IRBuilder::emitMakeVector( IRType* type, UInt argCount, - IRValue* const* args) + IRInst* const* args) { return emitIntrinsicInst(type, kIROp_makeVector, argCount, args); } @@ -1050,7 +999,7 @@ namespace Slang IRInst* IRBuilder::emitMakeArray( IRType* type, UInt argCount, - IRValue* const* args) + IRInst* const* args) { return emitIntrinsicInst(type, kIROp_makeArray, argCount, args); } @@ -1058,7 +1007,7 @@ namespace Slang IRInst* IRBuilder::emitMakeStruct( IRType* type, UInt argCount, - IRValue* const* args) + IRInst* const* args) { return emitIntrinsicInst(type, kIROp_makeStruct, argCount, args); } @@ -1067,148 +1016,28 @@ namespace Slang { auto module = new IRModule(); module->session = getSession(); - return module; - } - - void IRGlobalValue::insertBefore(IRGlobalValue* other) - { - assert(other); - insertBefore(other, other->parentModule); - } - - void IRGlobalValue::insertBefore(IRGlobalValue* other, IRModule* module) - { - assert(other || module); - - if(!other) other = module->firstGlobalValue; - if(!module) module = other->parentModule; - assert(module); - - auto nn = other; - auto pp = other ? other->prevGlobalValue : nullptr; - - if(pp) - { - pp->nextGlobalValue = this; - } - else - { - module->firstGlobalValue = this; - } - - if(nn) - { - nn->prevGlobalValue = this; - } - else - { - module->lastGlobalValue = this; - } - - this->prevGlobalValue = pp; - this->nextGlobalValue = nn; - this->parentModule = module; - } - - void IRGlobalValue::insertAtStart(IRModule* module) - { - insertBefore(module->firstGlobalValue, module); - } - - void IRGlobalValue::insertAfter(IRGlobalValue* other) - { - assert(other); - insertAfter(other, other->parentModule); - } - - void IRGlobalValue::insertAfter(IRGlobalValue* other, IRModule* module) - { - assert(other || module); - - if(!other) other = module->lastGlobalValue; - if(!module) module = other->parentModule; - - assert(module); - - auto pp = other; - auto nn = other ? other->nextGlobalValue : nullptr; - - if(pp) - { - pp->nextGlobalValue = this; - } - else - { - module->firstGlobalValue = this; - } - - if(nn) - { - nn->prevGlobalValue = this; - } - else - { - module->lastGlobalValue = this; - } - - this->prevGlobalValue = pp; - this->nextGlobalValue = nn; - this->parentModule = module; - } - - void IRGlobalValue::insertAtEnd(IRModule* module) - { - assert(module); - insertAfter(module->lastGlobalValue, module); - } - - void IRGlobalValue::removeFromParent() - { - auto module = parentModule; - if(!module) - return; - - auto pp = this->prevGlobalValue; - auto nn = this->nextGlobalValue; - - if(pp) - { - pp->nextGlobalValue = nn; - } - else - { - module->firstGlobalValue = nn; - } - - if( nn ) - { - nn->prevGlobalValue = pp; - } - else - { - module->lastGlobalValue = pp; - } - } + auto moduleInst = createInstImpl<IRModuleInst>( + module, + this, + sizeof(IRModuleInst), + kIROp_Module, + nullptr, + 0, + nullptr); + module->moduleInst = moduleInst; - void IRGlobalValue::moveToEnd() - { - auto module = parentModule; - removeFromParent(); - insertAtEnd(module); + return module; } - - void addGlobalValue( - IRModule* module, + IRModule* module, IRGlobalValue* value) { if(!module) return; - value->parentModule = module; - value->insertAfter(module->lastGlobalValue, module); + value->insertAtEnd(module->moduleInst); } IRFunc* IRBuilder::createFunc() @@ -1259,8 +1088,8 @@ namespace Slang IRWitnessTableEntry* IRBuilder::createWitnessTableEntry( IRWitnessTable* witnessTable, - IRValue* requirementKey, - IRValue* satisfyingVal) + IRInst* requirementKey, + IRInst* satisfyingVal) { IRWitnessTableEntry* entry = createInst<IRWitnessTableEntry>( this, @@ -1271,7 +1100,7 @@ namespace Slang if (witnessTable) { - witnessTable->entries.add(witnessTable, entry); + entry->insertAtEnd(witnessTable); } return entry; @@ -1347,7 +1176,7 @@ namespace Slang } IRInst* IRBuilder::emitLoad( - IRValue* ptr) + IRInst* ptr) { // Note: a `load` operation does not consider the rate // (if any) attached to its operand (see the use of `getDataType` @@ -1394,8 +1223,8 @@ namespace Slang } IRInst* IRBuilder::emitStore( - IRValue* dstPtr, - IRValue* srcVal) + IRInst* dstPtr, + IRInst* srcVal) { auto inst = createInst<IRStore>( this, @@ -1409,9 +1238,9 @@ namespace Slang } IRInst* IRBuilder::emitFieldExtract( - IRType* type, - IRValue* base, - IRValue* field) + IRType* type, + IRInst* base, + IRInst* field) { auto inst = createInst<IRFieldExtract>( this, @@ -1425,9 +1254,9 @@ namespace Slang } IRInst* IRBuilder::emitFieldAddress( - IRType* type, - IRValue* base, - IRValue* field) + IRType* type, + IRInst* base, + IRInst* field) { auto inst = createInst<IRFieldAddress>( this, @@ -1441,9 +1270,9 @@ namespace Slang } IRInst* IRBuilder::emitElementExtract( - IRType* type, - IRValue* base, - IRValue* index) + IRType* type, + IRInst* base, + IRInst* index) { auto inst = createInst<IRFieldAddress>( this, @@ -1458,8 +1287,8 @@ namespace Slang IRInst* IRBuilder::emitElementAddress( IRType* type, - IRValue* basePtr, - IRValue* index) + IRInst* basePtr, + IRInst* index) { auto inst = createInst<IRFieldAddress>( this, @@ -1474,9 +1303,9 @@ namespace Slang IRInst* IRBuilder::emitSwizzle( IRType* type, - IRValue* base, + IRInst* base, UInt elementCount, - IRValue* const* elementIndices) + IRInst* const* elementIndices) { auto inst = createInstWithTrailingArgs<IRSwizzle>( this, @@ -1492,13 +1321,13 @@ namespace Slang IRInst* IRBuilder::emitSwizzle( IRType* type, - IRValue* base, + IRInst* base, UInt elementCount, UInt const* elementIndices) { auto intType = getSession()->getBuiltinType(BaseType::Int); - IRValue* irElementIndices[4]; + IRInst* irElementIndices[4]; for (UInt ii = 0; ii < elementCount; ++ii) { irElementIndices[ii] = getIntValue(intType, elementIndices[ii]); @@ -1510,12 +1339,12 @@ namespace Slang IRInst* IRBuilder::emitSwizzleSet( IRType* type, - IRValue* base, - IRValue* source, + IRInst* base, + IRInst* source, UInt elementCount, - IRValue* const* elementIndices) + IRInst* const* elementIndices) { - IRValue* fixedArgs[] = { base, source }; + IRInst* fixedArgs[] = { base, source }; UInt fixedArgCount = sizeof(fixedArgs) / sizeof(fixedArgs[0]); auto inst = createInstWithTrailingArgs<IRSwizzleSet>( @@ -1533,14 +1362,14 @@ namespace Slang IRInst* IRBuilder::emitSwizzleSet( IRType* type, - IRValue* base, - IRValue* source, + IRInst* base, + IRInst* source, UInt elementCount, UInt const* elementIndices) { auto intType = getSession()->getBuiltinType(BaseType::Int); - IRValue* irElementIndices[4]; + IRInst* irElementIndices[4]; for (UInt ii = 0; ii < elementCount; ++ii) { irElementIndices[ii] = getIntValue(intType, elementIndices[ii]); @@ -1550,7 +1379,7 @@ namespace Slang } IRInst* IRBuilder::emitReturn( - IRValue* val) + IRInst* val) { auto inst = createInst<IRReturnVal>( this, @@ -1621,7 +1450,7 @@ namespace Slang IRBlock* breakBlock, IRBlock* continueBlock) { - IRValue* args[] = { target, breakBlock, continueBlock }; + IRInst* args[] = { target, breakBlock, continueBlock }; UInt argCount = sizeof(args) / sizeof(args[0]); auto inst = createInst<IRLoop>( @@ -1635,11 +1464,11 @@ namespace Slang } IRInst* IRBuilder::emitBranch( - IRValue* val, + IRInst* val, IRBlock* trueBlock, IRBlock* falseBlock) { - IRValue* args[] = { val, trueBlock, falseBlock }; + IRInst* args[] = { val, trueBlock, falseBlock }; UInt argCount = sizeof(args) / sizeof(args[0]); auto inst = createInst<IRConditionalBranch>( @@ -1653,12 +1482,12 @@ namespace Slang } IRInst* IRBuilder::emitIfElse( - IRValue* val, + IRInst* val, IRBlock* trueBlock, IRBlock* falseBlock, IRBlock* afterBlock) { - IRValue* args[] = { val, trueBlock, falseBlock, afterBlock }; + IRInst* args[] = { val, trueBlock, falseBlock, afterBlock }; UInt argCount = sizeof(args) / sizeof(args[0]); auto inst = createInst<IRIfElse>( @@ -1672,7 +1501,7 @@ namespace Slang } IRInst* IRBuilder::emitIf( - IRValue* val, + IRInst* val, IRBlock* trueBlock, IRBlock* afterBlock) { @@ -1680,7 +1509,7 @@ namespace Slang } IRInst* IRBuilder::emitLoopTest( - IRValue* val, + IRInst* val, IRBlock* bodyBlock, IRBlock* breakBlock) { @@ -1688,13 +1517,13 @@ namespace Slang } IRInst* IRBuilder::emitSwitch( - IRValue* val, + IRInst* val, IRBlock* breakLabel, IRBlock* defaultLabel, UInt caseArgCount, - IRValue* const* caseArgs) + IRInst* const* caseArgs) { - IRValue* fixedArgs[] = { val, breakLabel, defaultLabel }; + IRInst* fixedArgs[] = { val, breakLabel, defaultLabel }; UInt fixedArgCount = sizeof(fixedArgs) / sizeof(fixedArgs[0]); auto inst = createInstWithTrailingArgs<IRSwitch>( @@ -1709,14 +1538,14 @@ namespace Slang return inst; } - IRHighLevelDeclDecoration* IRBuilder::addHighLevelDeclDecoration(IRValue* inst, Decl* decl) + IRHighLevelDeclDecoration* IRBuilder::addHighLevelDeclDecoration(IRInst* inst, Decl* decl) { auto decoration = addDecoration<IRHighLevelDeclDecoration>(inst, kIRDecorationOp_HighLevelDecl); decoration->decl = decl; return decoration; } - IRLayoutDecoration* IRBuilder::addLayoutDecoration(IRValue* inst, Layout* layout) + IRLayoutDecoration* IRBuilder::addLayoutDecoration(IRInst* inst, Layout* layout) { auto decoration = addDecoration<IRLayoutDecoration>(inst); decoration->layout = layout; @@ -1732,7 +1561,7 @@ namespace Slang int indent = 0; UInt idCounter = 1; - Dictionary<IRValue*, UInt> mapValueToID; + Dictionary<IRInst*, UInt> mapValueToID; }; static void dump( @@ -1778,11 +1607,11 @@ namespace Slang } } - bool opHasResult(IRValue* inst); + bool opHasResult(IRInst* inst); static UInt getID( IRDumpContext* context, - IRValue* value) + IRInst* value) { UInt id = 0; if (context->mapValueToID.TryGetValue(value, id)) @@ -1799,7 +1628,7 @@ namespace Slang static void dumpID( IRDumpContext* context, - IRValue* inst) + IRInst* inst) { if (!inst) { @@ -1847,7 +1676,7 @@ namespace Slang static void dumpOperand( IRDumpContext* context, - IRValue* inst) + IRInst* inst) { // TODO: we should have a dedicated value for the `undef` case if (!inst) @@ -2107,16 +1936,6 @@ namespace Slang IRDumpContext* context, IRInst* inst); - static void dumpChildrenRaw( - IRDumpContext* context, - IRBlock* block) - { - for (auto ii = block->firstInst; ii; ii = ii->getNextInst()) - { - dumpInst(context, ii); - } - } - static void dumpBlock( IRDumpContext* context, IRBlock* block) @@ -2125,19 +1944,30 @@ namespace Slang dump(context, "block "); dumpID(context, block); - if( block->getFirstParam() ) + IRInst* inst = block->getFirstInst(); + + // First walk through any `param` instructions, + // so that we can format them nicely + if (auto firstParam = as<IRParam>(inst)) { dump(context, "(\n"); context->indent += 2; - for (auto pp = block->getFirstParam(); pp; pp = pp->getNextParam()) + + for(;;) { - if (pp != block->getFirstParam()) + auto param = as<IRParam>(inst); + if (!param) + break; + + if (param != firstParam) dump(context, ",\n"); + inst = inst->getNextInst(); + dumpIndent(context); dump(context, "param "); - dumpID(context, pp); - dumpInstTypeClause(context, pp->getFullType()); + dumpID(context, param); + dumpInstTypeClause(context, param->getFullType()); } context->indent -= 2; dump(context, ")"); @@ -2145,191 +1975,10 @@ namespace Slang dump(context, ":\n"); context->indent++; - dumpChildrenRaw(context, block); - } -#if 0 - static void dumpChildrenRaw( - IRDumpContext* context, - IRFunc* func) - { - for (auto bb = func->getFirstBlock(); bb; bb = bb->getNextBlock()) - { - dumpBlock(context, bb); - } - } - - static void dumpChildren( - IRDumpContext* context, - IRFunc* func) - { - dumpIndent(context); - dump(context, "{\n"); - context->indent++; - dumpChildrenRaw(context, func); - context->indent--; - dumpIndent(context); - dump(context, "}\n"); - } -#endif - static void dumpInst( - IRDumpContext* context, - IRInst* inst) - { - if (!inst) - { - dumpIndent(context); - dump(context, "<null>"); - return; - } - - auto op = inst->op; - - // There are several ops we want to special-case here, - // so that they will be more pleasant to look at. - // -#if 0 - switch (op) - { - case kIROp_Module: - dumpIndent(context); - dump(context, "module\n"); - dumpChildren(context, inst); - return; - - case kIROp_Func: - { - IRFunc* func = (IRFunc*)inst; - dump(context, "\n"); - dumpIndent(context); - dump(context, "func "); - dumpID(context, func); - dumpInstTypeClause(context, func->getType()); - dump(context, "\n"); - - dumpIndent(context); - dump(context, "{\n"); - context->indent++; - - for (auto bb = func->getFirstBlock(); bb; bb = bb->getNextBlock()) - { - if (bb != func->getFirstBlock()) - dump(context, "\n"); - dumpInst(context, bb); - } - - context->indent--; - dump(context, "}\n"); - } - return; - - case kIROp_TypeType: - case kIROp_Param: - case kIROp_IntLit: - case kIROp_FloatLit: - case kIROp_boolConst: - // Don't dump here - return; - - case kIROp_Block: - { - IRBlock* block = (IRBlock*)inst; - - context->indent--; - dump(context, "block "); - dumpID(context, block); - - if( block->getFirstParam() ) - { - dump(context, "("); - context->indent++; - for (auto pp = block->getFirstParam(); pp; pp = pp->getNextParam()) - { - if (pp != block->getFirstParam()) - dump(context, ",\n"); - - dumpIndent(context); - dump(context, "param "); - dumpID(context, pp); - dumpInstTypeClause(context, pp->getType()); - } - context->indent--; - dump(context, ")\n"); - } - dump(context, ":\n"); - context->indent++; - - dumpChildrenRaw(context, block); - } - return; - - default: - break; - } -#endif - -#if 0 - // We also want to special-case based on the *type* - // of the instruction - auto type = inst->getType(); - if (type && type->op == kIROp_TypeType) - { - // We probably don't want to print most types - // when producing "friendly" output. - switch (type->op) - { - case kIROp_StructType: - break; - - default: - return; - } - } -#endif - - - // Okay, we have a seemingly "ordinary" op now - dumpIndent(context); - - auto opInfo = &kIROpInfos[op]; - auto type = inst->getFullType(); - auto dataType = inst->getDataType(); - - if (!dataType) + for(; inst; inst = inst->getNextInst()) { - // No result, okay... + dumpInst(context, inst); } - else - { - auto basicType = dataType->As<BasicExpressionType>(); - if (basicType && basicType->baseType == BaseType::Void) - { - // No result, okay... - } - else - { - dump(context, "let "); - dumpID(context, inst); - dumpInstTypeClause(context, type); - dump(context, "\t= "); - } - } - - dump(context, opInfo->name); - - uint32_t argCount = inst->argCount; - dump(context, "("); - for (uint32_t ii = 0; ii < argCount; ++ii) - { - if (ii != 0) - dump(context, ", "); - - auto argVal = inst->getArgs()[ii].get(); - - dumpOperand(context, argVal); - } - dump(context, ")"); - - dump(context, "\n"); } void dumpGenericSignature( @@ -2506,50 +2155,109 @@ namespace Slang dump(context, "\n{\n"); context->indent++; - for (auto entry : witnessTable->entries) + for (auto ii : witnessTable->getChildren()) { - dumpIRWitnessTableEntry(context, entry); + dumpInst(context, ii); } context->indent--; dump(context, "}\n"); } - void dumpIRGlobalValue( + static void dumpInst( IRDumpContext* context, - IRGlobalValue* value) + IRInst* inst) { - switch (value->op) + if (!inst) + { + dumpIndent(context); + dump(context, "<null>"); + return; + } + + auto op = inst->op; + + // There are several ops we want to special-case here, + // so that they will be more pleasant to look at. + // + switch (op) { case kIROp_Func: - dumpIRFunc(context, (IRFunc*)value); - break; + dumpIRFunc(context, (IRFunc*)inst); + return; case kIROp_global_var: - dumpIRGlobalVar(context, (IRGlobalVar*)value); - break; + dumpIRGlobalVar(context, (IRGlobalVar*)inst); + return; case kIROp_global_constant: - dumpIRGlobalConstant(context, (IRGlobalConstant*)value); - break; + dumpIRGlobalConstant(context, (IRGlobalConstant*)inst); + return; case kIROp_witness_table: - dumpIRWitnessTable(context, (IRWitnessTable*)value); - break; + dumpIRWitnessTable(context, (IRWitnessTable*)inst); + return; + + case kIROp_witness_table_entry: + dumpIRWitnessTableEntry(context, (IRWitnessTableEntry*)inst); + return; default: - dump(context, "???\n"); break; } + + // Okay, we have a seemingly "ordinary" op now + dumpIndent(context); + + auto opInfo = &kIROpInfos[op]; + auto type = inst->getFullType(); + auto dataType = inst->getDataType(); + + if (!dataType) + { + // No result, okay... + } + else + { + auto basicType = dataType->As<BasicExpressionType>(); + if (basicType && basicType->baseType == BaseType::Void) + { + // No result, okay... + } + else + { + dump(context, "let "); + dumpID(context, inst); + dumpInstTypeClause(context, type); + dump(context, "\t= "); + } + } + + dump(context, opInfo->name); + + UInt argCount = inst->getOperandCount(); + dump(context, "("); + for (UInt ii = 0; ii < argCount; ++ii) + { + if (ii != 0) + dump(context, ", "); + + auto argVal = inst->getOperand(ii); + + dumpOperand(context, argVal); + } + dump(context, ")"); + + dump(context, "\n"); } void dumpIRModule( IRDumpContext* context, IRModule* module) { - for( auto gv = module->getFirstGlobalValue(); gv; gv = gv->getNextValue() ) + for(auto ii : module->getGlobalInsts()) { - dumpIRGlobalValue(context, gv); + dumpInst(context, ii); } } @@ -2570,7 +2278,7 @@ namespace Slang context.builder = &sb; context.indent = 0; - dumpIRGlobalValue(&context, globalVal); + dumpInst(&context, globalVal); fprintf(stderr, "%s\n", sb.Buffer()); fflush(stderr); @@ -2595,7 +2303,7 @@ namespace Slang // // - Type* IRValue::getRate() + Type* IRInst::getRate() { if(auto rateQualifiedType = type->As<RateQualifiedType>()) return rateQualifiedType->rate; @@ -2603,7 +2311,7 @@ namespace Slang return nullptr; } - Type* IRValue::getDataType() + Type* IRInst::getDataType() { if(auto rateQualifiedType = type->As<RateQualifiedType>()) return rateQualifiedType->valueType; @@ -2611,7 +2319,7 @@ namespace Slang return type; } - void IRValue::replaceUsesWith(IRValue* other) + void IRInst::replaceUsesWith(IRInst* other) { // We will walk through the list of uses for the current // instruction, and make them point to the other inst. @@ -2635,11 +2343,11 @@ namespace Slang // Try to move to the next use, but bail // out if we are at the last one. - IRUse* next = uu->nextUse; - if( !next ) + IRUse* nn = uu->nextUse; + if( !nn ) break; - uu = next; + uu = nn; } // We are at the last use (and there must @@ -2673,19 +2381,13 @@ namespace Slang ff->debugValidate(); } - void IRValue::deallocate() + void IRInst::deallocate() { -#if 0 - // I'm going to intentionally leak here, - // just to test that this is the source - // of my heap-corruption crashes. -#else // Run destructor to be sure... - this->~IRValue(); -#endif + this->~IRInst(); } - void IRValue::dispose() + void IRInst::dispose() { IRObject::dispose(); type = decltype(type)(); @@ -2695,60 +2397,146 @@ namespace Slang // as `other`, right before it. void IRInst::insertBefore(IRInst* other) { + assert(other); + insertBefore(other, other->parent); + } + + void IRInst::insertAtStart(IRParentInst* newParent) + { + assert(newParent); + insertBefore(newParent->children.first, newParent); + } + + void IRInst::moveToStart() + { + auto p = parent; + removeFromParent(); + insertAtStart(p); + } + + void IRInst::insertBefore(IRInst* other, IRParentInst* newParent) + { // Make sure this instruction has been removed from any previous parent this->removeFromParent(); - auto bb = other->getParentBlock(); - assert(bb); + assert(other || newParent); + if (!other) other = newParent->children.first; + if (!newParent) newParent = other->parent; + assert(newParent); + + auto nn = other; + auto pp = other ? other->getPrevInst() : nullptr; - auto pp = other->getPrevInst(); if( pp ) { pp->next = this; } else { - bb->firstInst = this; + newParent->children.first = this; + } + + if (nn) + { + nn->prev = this; + } + else + { + newParent->children.last = this; } this->prev = pp; - this->next = other; - this->parent = bb; + this->next = nn; + this->parent = newParent; + } + + void IRInst::insertAfter(IRInst* other) + { + assert(other); + insertAfter(other, other->parent); + } + + void IRInst::insertAtEnd(IRParentInst* newParent) + { + assert(newParent); + insertAfter(newParent->children.last, newParent); + } + + void IRInst::moveToEnd() + { + auto p = parent; + removeFromParent(); + insertAtEnd(p); + } + + void IRInst::insertAfter(IRInst* other, IRParentInst* newParent) + { + // Make sure this instruction has been removed from any previous parent + this->removeFromParent(); + + assert(other || newParent); + if (!other) other = newParent->children.last; + if (!newParent) newParent = other->parent; + assert(newParent); + + auto pp = other; + auto nn = other ? other->next : nullptr; + + if (pp) + { + pp->next = this; + } + else + { + newParent->children.first = this; + } + + if (nn) + { + nn->prev = this; + } + else + { + newParent->children.last = this; + } - other->prev = this; + this->prev = pp; + this->next = nn; + this->parent = newParent; } // Remove this instruction from its parent block, // and then destroy it (it had better have no uses!) void IRInst::removeFromParent() { + auto oldParent = getParent(); + // If we don't currently have a parent, then // we are doing fine. - if(!getParentBlock()) + if(!oldParent) return; - auto bb = getParentBlock(); auto pp = getPrevInst(); auto nn = getNextInst(); if(pp) { - SLANG_ASSERT(pp->getParentBlock() == bb); + SLANG_ASSERT(pp->getParent() == oldParent); pp->next = nn; } else { - bb->firstInst = nn; + oldParent->children.first = nn; } if(nn) { - SLANG_ASSERT(nn->getParentBlock() == bb); + SLANG_ASSERT(nn->getParent() == oldParent); nn->prev = pp; } else { - bb->lastInst = pp; + oldParent->children.last = pp; } prev = nullptr; @@ -2758,9 +2546,9 @@ namespace Slang void IRInst::removeArguments() { - for( UInt aa = 0; aa < argCount; ++aa ) + for( UInt aa = 0; aa < operandCount; ++aa ) { - IRUse& use = getArgs()[aa]; + IRUse& use = getOperands()[aa]; use.clear(); } } @@ -2824,10 +2612,10 @@ namespace Slang // no value (null pointer) none, - // A simple `IRValue*` that represents the actual value + // A simple `IRInst*` that represents the actual value value, - // An `IRValue*` that represents the address of the actual value + // An `IRInst*` that represents the address of the actual value address, // A `TupleValImpl` that represents zero or more `ScalarizedVal`s @@ -2840,7 +2628,7 @@ namespace Slang }; // Create a value representing a simple value - static ScalarizedVal value(IRValue* irValue) + static ScalarizedVal value(IRInst* irValue) { ScalarizedVal result; result.flavor = Flavor::value; @@ -2850,7 +2638,7 @@ namespace Slang // Create a value representing an address - static ScalarizedVal address(IRValue* irValue) + static ScalarizedVal address(IRInst* irValue) { ScalarizedVal result; result.flavor = Flavor::address; @@ -2875,7 +2663,7 @@ namespace Slang } Flavor flavor = Flavor::none; - IRValue* irValue = nullptr; + IRInst* irValue = nullptr; RefPtr<ScalarizedValImpl> impl; }; @@ -3457,7 +3245,7 @@ namespace Slang ScalarizedVal adaptType( IRBuilder* builder, - IRValue* val, + IRInst* val, Type* toType, Type* /*fromType*/) { @@ -3585,7 +3373,7 @@ namespace Slang IRBuilder* builder, Type* elementType, ScalarizedVal val, - IRValue* indexVal) + IRInst* indexVal) { switch( val.flavor ) { @@ -3667,11 +3455,11 @@ namespace Slang index)); } - IRValue* materializeValue( + IRInst* materializeValue( IRBuilder* builder, ScalarizedVal const& val); - IRValue* materializeTupleValue( + IRInst* materializeTupleValue( IRBuilder* builder, ScalarizedVal val) { @@ -3689,7 +3477,7 @@ namespace Slang // We will extract a value for each array element, and // then use these to construct our result. - List<IRValue*> arrayElementVals; + List<IRInst*> arrayElementVals; UInt arrayElementCount = (UInt) GetIntVal(arrayType->ArrayLength); for( UInt ii = 0; ii < arrayElementCount; ++ii ) @@ -3720,7 +3508,7 @@ namespace Slang // // TODO: this should be using a `makeStruct` instruction. - List<IRValue*> elementVals; + List<IRInst*> elementVals; for( UInt ee = 0; ee < elementCount; ++ee ) { auto elementVal = materializeValue(builder, tupleVal->elements[ee].val); @@ -3734,7 +3522,7 @@ namespace Slang } } - IRValue* materializeValue( + IRInst* materializeValue( IRBuilder* builder, ScalarizedVal const& val) { @@ -3776,7 +3564,7 @@ namespace Slang } IRTargetIntrinsicDecoration* findTargetIntrinsicDecoration( - IRValue* val, + IRInst* val, String const& targetName) { for( auto dd = val->firstDecoration; dd; dd = dd->next ) @@ -3794,6 +3582,7 @@ namespace Slang void legalizeEntryPointForGLSL( Session* session, + IRModule* module, IRFunc* func, EntryPointLayout* entryPointLayout, DiagnosticSink* sink, @@ -3805,8 +3594,6 @@ namespace Slang context.sink = sink; context.extensionUsageTracker = extensionUsageTracker; - auto module = func->parentModule; - // We require that the entry-point function has no uses, // because otherwise we'd invalidate the signature // at all existing call sites. @@ -3881,7 +3668,7 @@ namespace Slang continue; IRReturnVal* returnInst = (IRReturnVal*) ii; - IRValue* returnValue = returnInst->getVal(); + IRInst* returnValue = returnInst->getVal(); // Make sure we add these instructions to the right block builder.curBlock = bb; @@ -3978,10 +3765,10 @@ namespace Slang continue; // Is it calling the append operation? - auto callee = ii->getArg(0); + auto callee = ii->getOperand(0); while( callee->op == kIROp_specialize ) { - callee = ((IRSpecialize*) callee)->getArg(0); + callee = ((IRSpecialize*) callee)->getOperand(0); } if(callee->op != kIROp_Func) continue; @@ -4003,7 +3790,7 @@ namespace Slang builder.curBlock = bb; builder.insertBeforeInst = ii; - assign(&builder, globalOutputVal, ScalarizedVal::value(ii->getArg(2))); + assign(&builder, globalOutputVal, ScalarizedVal::value(ii->getOperand(2))); } } @@ -4092,7 +3879,7 @@ namespace Slang // references to the variable(s). We are going to do that // somewhat naively, by simply materializing the // variables at the start. - IRValue* materialized = materializeValue(&builder, globalValue); + IRInst* materialized = materializeValue(&builder, globalValue); pp->replaceUsesWith(materialized); } @@ -4107,14 +3894,13 @@ namespace Slang // // We can safely go through and destroy the parameters // themselves, and then clear out the parameter list. + for( auto pp = firstBlock->getFirstParam(); pp; ) { auto next = pp->getNextParam(); pp->deallocate(); pp = next; } - firstBlock->firstParam = nullptr; - firstBlock->lastParam = nullptr; } // Finally, we need to patch up the type of the entry point, @@ -4163,7 +3949,7 @@ namespace Slang // A map from values in the original IR module // to their equivalent in the cloned module. - typedef Dictionary<IRValue*, IRValue*> ClonedValueDictionary; + typedef Dictionary<IRInst*, IRInst*> ClonedValueDictionary; ClonedValueDictionary clonedValues; SharedIRBuilder sharedBuilderStorage; @@ -4199,7 +3985,7 @@ namespace Slang // A callback to be used when a value that is not registerd in `clonedValues` // is needed during cloning. This gives the subtype a chance to intercept // the operation and clone (or not) as needed. - virtual IRValue* maybeCloneValue(IRValue* originalVal) + virtual IRInst* maybeCloneValue(IRInst* originalVal) { return originalVal; } @@ -4225,8 +4011,8 @@ namespace Slang void registerClonedValue( IRSpecContextBase* context, - IRValue* clonedValue, - IRValue* originalValue) + IRInst* clonedValue, + IRInst* originalValue) { if(!originalValue) return; @@ -4249,12 +4035,12 @@ namespace Slang // Information on values to use when registering a cloned value struct IROriginalValuesForClone { - IRValue* originalVal = nullptr; + IRInst* originalVal = nullptr; IRSpecSymbol* sym = nullptr; IROriginalValuesForClone() {} - IROriginalValuesForClone(IRValue* originalValue) + IROriginalValuesForClone(IRInst* originalValue) : originalVal(originalValue) {} @@ -4265,7 +4051,7 @@ namespace Slang void registerClonedValue( IRSpecContextBase* context, - IRValue* clonedValue, + IRInst* clonedValue, IROriginalValuesForClone const& originalValues) { registerClonedValue(context, clonedValue, originalValues.originalVal); @@ -4277,8 +4063,8 @@ namespace Slang void cloneDecorations( IRSpecContextBase* context, - IRValue* clonedValue, - IRValue* originalValue) + IRInst* clonedValue, + IRInst* originalValue) { for (auto dd = originalValue->firstDecoration; dd; dd = dd->next) { @@ -4322,7 +4108,7 @@ namespace Slang struct IRSpecContext : IRSpecContextBase { // Override the "maybe clone" logic so that we always clone - virtual IRValue* maybeCloneValue(IRValue* originalVal) override; + virtual IRInst* maybeCloneValue(IRInst* originalVal) override; // Override teh "maybe clone" logic so that we carefully // clone any IR proxy values inside substitutions @@ -4349,7 +4135,7 @@ namespace Slang } - IRValue* IRSpecContext::maybeCloneValue(IRValue* originalValue) + IRInst* IRSpecContext::maybeCloneValue(IRInst* originalValue) { switch (originalValue->op) { @@ -4425,7 +4211,7 @@ namespace Slang break; case kIROp_TypeType: { - IRValue* od = (IRValue*)originalValue; + IRInst* od = (IRInst*)originalValue; int ioDiff = 0; auto newType = od->type->SubstituteImpl(subst, &ioDiff); return builder->getTypeVal(newType.As<Type>()); @@ -4437,9 +4223,9 @@ namespace Slang } } - IRValue* cloneValue( + IRInst* cloneValue( IRSpecContextBase* context, - IRValue* originalValue); + IRInst* originalValue); RefPtr<Val> cloneSubstitutionArg( IRSpecContext* context, @@ -4526,11 +4312,11 @@ namespace Slang return newDeclRef; } - IRValue* cloneValue( + IRInst* cloneValue( IRSpecContextBase* context, - IRValue* originalValue) + IRInst* originalValue) { - IRValue* clonedValue = nullptr; + IRInst* clonedValue = nullptr; if (context->getClonedValues().TryGetValue(originalValue, clonedValue)) { return clonedValue; @@ -4539,12 +4325,16 @@ namespace Slang return context->maybeCloneValue(originalValue); } - IRValue* maybeCloneValueWithMangledName( + IRInst* maybeCloneValueWithMangledName( IRSpecContextBase* context, IRGlobalValue* originalValue) { - for (auto gv = context->shared->module->firstGlobalValue; gv; gv = gv->nextGlobalValue) + for(auto ii : context->shared->module->getGlobalInsts()) { + auto gv = as<IRGlobalValue>(ii); + if (!gv) + continue; + if (gv->mangledName == originalValue->mangledName) return gv; } @@ -4567,7 +4357,7 @@ namespace Slang // The common case is that we just need to construct a cloned // instruction with the right number of operands, intialize // it, and then add it to the sequence. - UInt argCount = originalInst->getArgCount(); + UInt argCount = originalInst->getOperandCount(); IRInst* clonedInst = createInstWithTrailingArgs<IRInst>( builder, originalInst->op, context->maybeCloneType(originalInst->type), @@ -4578,14 +4368,14 @@ namespace Slang context->builder = builder; for (UInt aa = 0; aa < argCount; ++aa) { - IRValue* originalArg = originalInst->getArg(aa); - IRValue* clonedArg; + IRInst* originalArg = originalInst->getOperand(aa); + IRInst* clonedArg; if (originalArg->op == kIROp_witness_table) clonedArg = cloneGlobalValueWithMangledName((IRSpecContext*)context, ((IRGlobalValue*)originalArg)->mangledName, (IRGlobalValue*)originalArg); else clonedArg = cloneValue(context, originalArg); - clonedInst->getArgs()[aa].init(clonedInst, clonedArg); + clonedInst->getOperands()[aa].init(clonedInst, clonedArg); } builder->addInst(clonedInst); context->builder = oldBuilder; @@ -4681,7 +4471,7 @@ namespace Slang cloneDecorations(context, clonedTable, originalTable); // Clone the entries in the witness table as well - for( auto originalEntry : originalTable->entries ) + for(auto originalEntry : originalTable->getEntries() ) { auto clonedKey = cloneValue(context, originalEntry->requirementKey.get()); @@ -4729,6 +4519,7 @@ namespace Slang clonedValue->addBlock(clonedBlock); registerClonedValue(context, clonedBlock, originalBlock); +#if 0 // We can go ahead and clone parameters here, while we are at it. builder->curBlock = clonedBlock; for (auto originalParam = originalBlock->getFirstParam(); @@ -4741,6 +4532,7 @@ namespace Slang cloneDecorations(context, clonedParam, originalParam); registerClonedValue(context, clonedParam, originalParam); } +#endif } // Okay, now we are in a good position to start cloning @@ -4788,7 +4580,7 @@ namespace Slang // // TODO: This isn't really a good requirement to place on the IR... clonedFunc->removeFromParent(); - clonedFunc->insertAtEnd(context->getModule()); + clonedFunc->insertAtEnd(context->getModule()->getModuleInst()); } IRFunc* specializeIRForEntryPoint( @@ -4933,12 +4725,10 @@ namespace Slang switch (val->op) { case kIROp_witness_table: - return ((IRWitnessTable*)val)->entries.first != nullptr; - case kIROp_global_var: case kIROp_global_constant: case kIROp_Func: - return ((IRGlobalValueWithCode*)val)->firstBlock != nullptr; + return ((IRParentInst*)val)->getFirstChild() != nullptr; default: return false; @@ -5058,7 +4848,7 @@ namespace Slang { // Check if we've already cloned this value, for the case where // an original value has already been established. - IRValue* clonedVal = nullptr; + IRInst* clonedVal = nullptr; if( originalVal && context->getClonedValues().TryGetValue(originalVal, clonedVal) ) { return (IRGlobalValue*) clonedVal; @@ -5168,8 +4958,11 @@ namespace Slang if (!originalModule) return; - for (auto gv = originalModule->firstGlobalValue; gv; gv = gv->nextGlobalValue) + for(auto ii : originalModule->getGlobalInsts()) { + auto gv = as<IRGlobalValue>(ii); + if (!gv) + continue; insertGlobalValueSymbol(sharedContext, gv); } } @@ -5385,6 +5178,7 @@ namespace Slang { legalizeEntryPointForGLSL( session, + context->getModule(), irEntryPoint, entryPointLayout, &compileRequest->mSink, @@ -5402,14 +5196,14 @@ namespace Slang IRSharedSpecContext* getShared() { return shared; } // Override the "maybe clone" logic so that we always clone - virtual IRValue* maybeCloneValue(IRValue* originalVal) override; + virtual IRInst* maybeCloneValue(IRInst* originalVal) override; virtual RefPtr<Type> maybeCloneType(Type* originalType) override; virtual RefPtr<Val> maybeCloneVal(Val* val) override; }; // Convert a type-level value into an IR-level equivalent. - IRValue* getIRValue( + IRInst* getIRValue( IRGenericSpecContext* context, Val* val) { @@ -5467,7 +5261,7 @@ namespace Slang } } - IRValue* getSubstValue( + IRInst* getSubstValue( IRGenericSpecContext* context, DeclRef<Decl> declRef) { @@ -5538,7 +5332,7 @@ namespace Slang } } - IRValue* IRGenericSpecContext::maybeCloneValue(IRValue* originalVal) + IRInst* IRGenericSpecContext::maybeCloneValue(IRInst* originalVal) { switch( originalVal->op ) { @@ -5692,8 +5486,12 @@ namespace Slang if (!dstTable) { auto module = sharedContext->module; - for (auto gv = module->getFirstGlobalValue(); gv; gv = gv->getNextValue()) + for(auto ii : module->getGlobalInsts()) { + auto gv = as<IRGlobalValue>(ii); + if (!gv) + continue; + if (getText(gv->mangledName) == specializedMangledName) return (IRWitnessTable*)gv; } @@ -5718,7 +5516,7 @@ namespace Slang // Specialization of witness tables should trigger cascading specializations // of involved functions. - for (auto entry : specTable->entries) + for (auto entry : specTable->getEntries()) { if (entry->satisfyingVal.get()->op == kIROp_Func) { @@ -5761,8 +5559,12 @@ namespace Slang // avoid it by building a dictionary ahead of time, // as is being done for the `IRSpecContext` used above. // We can probalby use the same basic context, actually. - for (auto gv = sharedContext->module->getFirstGlobalValue(); gv; gv = gv->getNextValue()) + for(auto ii : sharedContext->module->getGlobalInsts()) { + auto gv = as<IRGlobalValue>(ii); + if (!gv) + continue; + if (gv->mangledName == specMangledNameObj) return (IRFunc*) gv; } @@ -5823,12 +5625,12 @@ namespace Slang // Find the value in the given witness table that // satisfies the given requirement (or return // null if not found). - IRValue* findWitnessVal( + IRInst* findWitnessVal( IRWitnessTable* witnessTable, DeclRef<Decl> const& requirementDeclRef) { // For now we will do a dumb linear search - for( auto entry : witnessTable->entries ) + for( auto entry : witnessTable->getEntries() ) { // We expect the key on the entry to be a decl-ref, // but lets go ahead and check, just to be sure. @@ -5889,10 +5691,12 @@ namespace Slang // function. // // We start by building up a work list of non-generic functions. - for( auto gv = module->getFirstGlobalValue(); - gv; - gv = gv->getNextValue() ) + for(auto ii : module->getGlobalInsts()) { + auto gv = as<IRGlobalValue>(ii); + if (!gv) + continue; + // Is it a function? If not, skip. if(gv->op != kIROp_Func) continue; @@ -5907,10 +5711,12 @@ namespace Slang // Build dictionary for witness tables Dictionary<Name*, IRWitnessTable*> witnessTables; - for (auto gv = module->getFirstGlobalValue(); - gv; - gv = gv->getNextValue()) + for(auto ii : module->getGlobalInsts()) { + auto gv = as<IRGlobalValue>(ii); + if (!gv) + continue; + if (gv->op == kIROp_witness_table) witnessTables.AddIfNotExists(gv->mangledName, (IRWitnessTable*)gv); } @@ -6115,20 +5921,18 @@ namespace Slang if (subtypeWitness->sub->EqualsVal(paramSubst->actualType)) { auto witnessTableName = getMangledNameForConformanceWitness(subtypeWitness->sub, subtypeWitness->sup); - auto findWitnessTableByName = [&](String name) + auto findWitnessTableByName = [&](String name) -> IRGlobalValue* { - auto globalVar = originalIRModule->getFirstGlobalValue(); - IRGlobalValue * rs = nullptr; - while (globalVar) + for (auto ii : originalIRModule->getGlobalInsts()) { - if (getText(globalVar->mangledName) == name) - { - rs = globalVar; - break; - } - globalVar = globalVar->getNextValue(); + auto gv = as<IRGlobalValue>(ii); + if (!gv) + continue; + + if (getText(gv->mangledName) == name) + return gv; } - return rs; + return nullptr; }; auto table = findWitnessTableByName(witnessTableName); if (!table) @@ -6170,7 +5974,7 @@ namespace Slang void markConstExpr( Session* session, - IRValue* irValue) + IRInst* irValue) { // We will take an IR value with type `T`, // and turn it into one with type `@ConstExpr T`. |
