diff options
author | GregF <greg@LunarG.com> | 2017-08-29 18:35:05 -0600 |
---|---|---|
committer | GregF <greg@LunarG.com> | 2017-08-29 18:35:05 -0600 |
commit | a699d1ade750b45326015211d2614b25506237a3 (patch) | |
tree | 6ed537ffbf6380815a449d17eafbd1d8ff80d491 /source/opt/inline_pass.cpp | |
parent | 1687bd32357154c2508701f8b5d9a26b4a3858cb (diff) |
Inline: Fix remapping of non-label forward references in callee phi
Diffstat (limited to 'source/opt/inline_pass.cpp')
-rw-r--r-- | source/opt/inline_pass.cpp | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/source/opt/inline_pass.cpp b/source/opt/inline_pass.cpp index 6d0379f4..3ad7d292 100644 --- a/source/opt/inline_pass.cpp +++ b/source/opt/inline_pass.cpp @@ -242,6 +242,15 @@ void InlinePass::GenInlineCode( // Create return var if needed. uint32_t returnVarId = CreateReturnVar(calleeFn, new_vars); + // Create set of callee result ids. Used to detect forward references + std::unordered_set<uint32_t> callee_result_ids; + calleeFn->ForEachInst([&callee_result_ids]( + const ir::Instruction* cpi) { + const uint32_t rid = cpi->result_id(); + if (rid != 0) + callee_result_ids.insert(rid); + }); + // Clone and map callee code. Copy caller block code to beginning of // first block and end of last block. bool prevInstWasReturn = false; @@ -259,7 +268,7 @@ void InlinePass::GenInlineCode( &returnLabelId, &returnVarId, &calleeTypeId, &multiBlocks, &postCallSB, &preCallSB, multiReturn, &singleTripLoopHeaderId, &singleTripLoopContinueId, - this]( + &callee_result_ids, this]( const ir::Instruction* cpi) { switch (cpi->opcode()) { case SpvOpFunction: @@ -398,27 +407,32 @@ void InlinePass::GenInlineCode( default: { // Copy callee instruction and remap all input Ids. std::unique_ptr<ir::Instruction> cp_inst(new ir::Instruction(*cpi)); - cp_inst->ForEachInId([&callee2caller, &cpi, this](uint32_t* iid) { + cp_inst->ForEachInId([&callee2caller, &cpi, &callee_result_ids, this] + (uint32_t* iid) { const auto mapItr = callee2caller.find(*iid); if (mapItr != callee2caller.end()) { *iid = mapItr->second; - } else if (cpi->HasLabels()) { - const ir::Instruction* inst = - def_use_mgr_->id_to_defs().find(*iid)->second; - if (inst->opcode() == SpvOpLabel) { - // Forward label reference. Allocate a new label id, map it, - // use it and check for it at each label. - const uint32_t nid = this->TakeNextId(); - callee2caller[*iid] = nid; - *iid = nid; - } + } else if (callee_result_ids.find(*iid) != callee_result_ids.end()) { + // Forward reference. Allocate a new id, map it, + // use it and check for it when remapping result ids + const uint32_t nid = this->TakeNextId(); + callee2caller[*iid] = nid; + *iid = nid; } }); - // Map and reset result id. + // If result id is non-zero, remap it. If already mapped, use mapped + // value, else use next id. const uint32_t rid = cp_inst->result_id(); if (rid != 0) { - const uint32_t nid = this->TakeNextId(); - callee2caller[rid] = nid; + const auto mapItr = callee2caller.find(rid); + uint32_t nid; + if (mapItr != callee2caller.end()) { + nid = mapItr->second; + } + else { + nid = this->TakeNextId(); + callee2caller[rid] = nid; + } cp_inst->SetResultId(nid); } new_blk_ptr->AddInstruction(std::move(cp_inst)); |