Browse Source

Fixed bug in phi node rewriting

[#80895676]
cl-refactor
artur-zawlocki 10 years ago
parent
commit
15499e68b8
  1. 47
      libevmjit/Compiler.cpp

47
libevmjit/Compiler.cpp

@ -924,11 +924,13 @@ void Compiler::linkBasicBlocks(Stack& stack)
for (auto& pair : this->basicBlocks) for (auto& pair : this->basicBlocks)
{ {
auto& bb = pair.second; auto& bb = pair.second;
cfg.emplace(std::piecewise_construct, cfg.emplace(bb.llvm(), bb);
std::forward_as_tuple(bb.llvm()),
std::forward_as_tuple(bb));
} }
// Insert jump table block into cfg
if (m_jumpTableBlock)
cfg.emplace(m_jumpTableBlock->llvm(), *m_jumpTableBlock);
auto& entryBlock = m_mainFunc->getEntryBlock(); auto& entryBlock = m_mainFunc->getEntryBlock();
// Create edges in cfg // Create edges in cfg
@ -976,6 +978,8 @@ void Compiler::linkBasicBlocks(Stack& stack)
} }
} }
std::map<llvm::Instruction*, llvm::Value*> phiReplacements;
// Propagate values between blocks. // Propagate values between blocks.
for (auto& pair : cfg) for (auto& pair : cfg)
{ {
@ -998,13 +1002,12 @@ void Compiler::linkBasicBlocks(Stack& stack)
// Turn the remaining phi nodes into stack.pop's. // Turn the remaining phi nodes into stack.pop's.
m_builder.SetInsertPoint(llbb, llvm::BasicBlock::iterator(llbb->getFirstNonPHI())); m_builder.SetInsertPoint(llbb, llvm::BasicBlock::iterator(llbb->getFirstNonPHI()));
for (; llvm::isa<llvm::PHINode>(*instrIter); ) for (; llvm::isa<llvm::PHINode>(*instrIter); ++instrIter)
{ {
auto phi = llvm::cast<llvm::PHINode>(instrIter); auto phi = llvm::cast<llvm::PHINode>(instrIter);
auto value = stack.popWord(); auto value = stack.popWord();
phi->replaceAllUsesWith(value); // Don't delete the phi node yet. It may still be stored in a local stack of some block.
++ instrIter; phiReplacements[phi] = value;
phi->eraseFromParent();
} }
// Emit stack push's at the end of the block, just before the terminator; // 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) for (size_t i = 0; i < localStackSize - bbInfo.outputItems; ++i)
stack.pushWord(bblock.getStack().get(localStackSize - 1 - 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) void Compiler::dumpBasicBlockGraph(std::ostream& out)
@ -1025,11 +1034,13 @@ void Compiler::dumpBasicBlockGraph(std::ostream& out)
std::vector<BasicBlock*> blocks; std::vector<BasicBlock*> blocks;
for (auto& pair : this->basicBlocks) for (auto& pair : this->basicBlocks)
blocks.push_back(&pair.second); blocks.push_back(&pair.second);
if (m_jumpTableBlock.get()) if (m_jumpTableBlock)
blocks.push_back(m_jumpTableBlock.get()); blocks.push_back(m_jumpTableBlock.get());
if (m_badJumpBlock.get()) if (m_badJumpBlock)
blocks.push_back(m_badJumpBlock.get()); blocks.push_back(m_badJumpBlock.get());
std::map<BasicBlock*,int> phiNodesPerBlock;
// Output nodes // Output nodes
for (auto bb : blocks) for (auto bb : blocks)
{ {
@ -1038,27 +1049,29 @@ void Compiler::dumpBasicBlockGraph(std::ostream& out)
int numOfPhiNodes = 0; int numOfPhiNodes = 0;
auto firstNonPhiPtr = bb->llvm()->getFirstNonPHI(); auto firstNonPhiPtr = bb->llvm()->getFirstNonPHI();
for (auto instrIter = bb->llvm()->begin(); &*instrIter != firstNonPhiPtr; ++instrIter, ++numOfPhiNodes); for (auto instrIter = bb->llvm()->begin(); &*instrIter != firstNonPhiPtr; ++instrIter, ++numOfPhiNodes);
phiNodesPerBlock[bb] = numOfPhiNodes;
auto initStackSize = bb->getStack().initialSize();
auto endStackSize = bb->getStack().size(); auto endStackSize = bb->getStack().size();
out << " \"" << blockName << "\" [shape=record, label=\"" out << " \"" << blockName << "\" [shape=record, label=\""
<< numOfPhiNodes << "|" << blockName << "|" << endStackSize << initStackSize << "|" << blockName << "|" << endStackSize
<< "\"];\n"; << "\"];\n";
} }
out << " entry -> \"Instr.0\";\n";
// Output edges // Output edges
for (auto bb : blocks) for (auto bb : blocks)
{ {
std::string blockName = bb->llvm()->getName(); std::string blockName = bb->llvm()->getName();
auto end = llvm::succ_end(bb->llvm()); auto end = llvm::pred_end(bb->llvm());
for (llvm::succ_iterator it = llvm::succ_begin(bb->llvm()); it != end; ++it) for (llvm::pred_iterator it = llvm::pred_begin(bb->llvm()); it != end; ++it)
{ {
std::string succName = it->getName(); out << " \"" << (*it)->getName().str() << "\" -> \"" << blockName << "\" ["
out << " \"" << blockName << "\" -> \"" << succName << "\"" << ((m_jumpTableBlock.get() && *it == m_jumpTableBlock.get()->llvm()) ? "style = dashed, " : "")
<< ((bb == m_jumpTableBlock.get()) ? " [style = dashed];\n" : "\n"); << "label = \""
<< phiNodesPerBlock[bb]
<< "\"];\n";
} }
} }

Loading…
Cancel
Save