mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
parent
5a8ba36fe5
commit
044e83860a
1 changed files with 30 additions and 17 deletions
|
|
@ -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…
Reference in a new issue