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)
{
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<llvm::Instruction*, llvm::Value*> 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<llvm::PHINode>(*instrIter); )
for (; llvm::isa<llvm::PHINode>(*instrIter); ++instrIter)
{
auto phi = llvm::cast<llvm::PHINode>(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<BasicBlock*> 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<BasicBlock*,int> 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";
}
}

Loading…
Cancel
Save