From 15499e68b87c3caa8f9e7bf480f97d0da5fb25c3 Mon Sep 17 00:00:00 2001 From: artur-zawlocki Date: Tue, 21 Oct 2014 21:52:18 +0100 Subject: [PATCH] Fixed bug in phi node rewriting [#80895676] --- libevmjit/Compiler.cpp | 47 +++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/libevmjit/Compiler.cpp b/libevmjit/Compiler.cpp index bf77901cd..71661bde9 100644 --- a/libevmjit/Compiler.cpp +++ b/libevmjit/Compiler.cpp @@ -924,11 +924,13 @@ void Compiler::linkBasicBlocks(Stack& stack) for (auto& pair : this->basicBlocks) { auto& bb = pair.second; - cfg.emplace(std::piecewise_construct, - std::forward_as_tuple(bb.llvm()), - std::forward_as_tuple(bb)); + cfg.emplace(bb.llvm(), bb); } + // Insert jump table block into cfg + if (m_jumpTableBlock) + cfg.emplace(m_jumpTableBlock->llvm(), *m_jumpTableBlock); + auto& entryBlock = m_mainFunc->getEntryBlock(); // Create edges in cfg @@ -976,6 +978,8 @@ void Compiler::linkBasicBlocks(Stack& stack) } } + std::map phiReplacements; + // Propagate values between blocks. for (auto& pair : cfg) { @@ -998,13 +1002,12 @@ void Compiler::linkBasicBlocks(Stack& stack) // Turn the remaining phi nodes into stack.pop's. m_builder.SetInsertPoint(llbb, llvm::BasicBlock::iterator(llbb->getFirstNonPHI())); - for (; llvm::isa(*instrIter); ) + for (; llvm::isa(*instrIter); ++instrIter) { auto phi = llvm::cast(instrIter); auto value = stack.popWord(); - phi->replaceAllUsesWith(value); - ++ instrIter; - phi->eraseFromParent(); + // Don't delete the phi node yet. It may still be stored in a local stack of some block. + phiReplacements[phi] = value; } // Emit stack push's at the end of the block, just before the terminator; @@ -1014,6 +1017,12 @@ void Compiler::linkBasicBlocks(Stack& stack) for (size_t i = 0; i < localStackSize - bbInfo.outputItems; ++i) stack.pushWord(bblock.getStack().get(localStackSize - 1 - i)); } + + for (auto& entry : phiReplacements) + { + entry.first->replaceAllUsesWith(entry.second); + entry.first->eraseFromParent(); + } } void Compiler::dumpBasicBlockGraph(std::ostream& out) @@ -1025,11 +1034,13 @@ void Compiler::dumpBasicBlockGraph(std::ostream& out) std::vector blocks; for (auto& pair : this->basicBlocks) blocks.push_back(&pair.second); - if (m_jumpTableBlock.get()) + if (m_jumpTableBlock) blocks.push_back(m_jumpTableBlock.get()); - if (m_badJumpBlock.get()) + if (m_badJumpBlock) blocks.push_back(m_badJumpBlock.get()); + std::map phiNodesPerBlock; + // Output nodes for (auto bb : blocks) { @@ -1038,27 +1049,29 @@ void Compiler::dumpBasicBlockGraph(std::ostream& out) int numOfPhiNodes = 0; auto firstNonPhiPtr = bb->llvm()->getFirstNonPHI(); for (auto instrIter = bb->llvm()->begin(); &*instrIter != firstNonPhiPtr; ++instrIter, ++numOfPhiNodes); + phiNodesPerBlock[bb] = numOfPhiNodes; + auto initStackSize = bb->getStack().initialSize(); auto endStackSize = bb->getStack().size(); out << " \"" << blockName << "\" [shape=record, label=\"" - << numOfPhiNodes << "|" << blockName << "|" << endStackSize + << initStackSize << "|" << blockName << "|" << endStackSize << "\"];\n"; } - out << " entry -> \"Instr.0\";\n"; - // Output edges for (auto bb : blocks) { std::string blockName = bb->llvm()->getName(); - auto end = llvm::succ_end(bb->llvm()); - for (llvm::succ_iterator it = llvm::succ_begin(bb->llvm()); it != end; ++it) + auto end = llvm::pred_end(bb->llvm()); + for (llvm::pred_iterator it = llvm::pred_begin(bb->llvm()); it != end; ++it) { - std::string succName = it->getName(); - out << " \"" << blockName << "\" -> \"" << succName << "\"" - << ((bb == m_jumpTableBlock.get()) ? " [style = dashed];\n" : "\n"); + out << " \"" << (*it)->getName().str() << "\" -> \"" << blockName << "\" [" + << ((m_jumpTableBlock.get() && *it == m_jumpTableBlock.get()->llvm()) ? "style = dashed, " : "") + << "label = \"" + << phiNodesPerBlock[bb] + << "\"];\n"; } }