mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 03:36:44 +00:00
parent
bb51b3476c
commit
f233122943
3 changed files with 72 additions and 2 deletions
|
|
@ -929,6 +929,58 @@ void Compiler::linkBasicBlocks()
|
|||
}
|
||||
}
|
||||
|
||||
void Compiler::dumpBasicBlockGraph(std::ostream& out)
|
||||
{
|
||||
out << "digraph BB {\n"
|
||||
<< " node [shape=record];\n"
|
||||
<< " entry [share=record, label=\"entry block\"];\n";
|
||||
|
||||
// std::map<std::string, BasicBlock*> blocksByName;
|
||||
std::vector<BasicBlock*> blocks;
|
||||
for (auto& pair : this->basicBlocks)
|
||||
{
|
||||
blocks.push_back(&pair.second);
|
||||
}
|
||||
blocks.push_back(m_jumpTableBlock.get());
|
||||
blocks.push_back(m_badJumpBlock.get());
|
||||
|
||||
// Output nodes
|
||||
for (auto bb : blocks)
|
||||
{
|
||||
std::string blockName = bb->llvm()->getName();
|
||||
// blocksByName.insert(std::pair<std::string, BasicBlock*>(blockName, bb));
|
||||
|
||||
int numOfPhiNodes = 0;
|
||||
auto firstNonPhiPtr = bb->llvm()->getFirstNonPHI();
|
||||
for (auto instrIter = bb->llvm()->begin(); &*instrIter != firstNonPhiPtr; ++instrIter, ++numOfPhiNodes);
|
||||
|
||||
auto endStackSize = bb->getStack().size();
|
||||
|
||||
out << " \"" << blockName << "\" [shape=record, label=\""
|
||||
<< std::to_string(numOfPhiNodes) << "|"
|
||||
<< blockName << "|"
|
||||
<< std::to_string(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)
|
||||
{
|
||||
std::string succName = it->getName();
|
||||
out << " \"" << blockName << "\" -> \"" << succName << "\";\n";
|
||||
}
|
||||
}
|
||||
|
||||
out << "}\n";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ public:
|
|||
|
||||
std::unique_ptr<llvm::Module> compile(const bytes& bytecode);
|
||||
|
||||
void dumpBasicBlockGraph(std::ostream& out);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void createBasicBlocks(const bytes& bytecode);
|
||||
|
|
@ -32,6 +35,7 @@ private:
|
|||
|
||||
void linkBasicBlocks();
|
||||
|
||||
|
||||
llvm::IRBuilder<> m_builder;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -22,6 +23,7 @@ void show_usage()
|
|||
std::cerr << "usage: evmcc (-b|-c|-d)+ <inputfile.bc>\n";
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
|
|
@ -30,7 +32,8 @@ int main(int argc, char** argv)
|
|||
bool opt_show_bytes = false;
|
||||
bool opt_compile = false;
|
||||
bool opt_interpret = false;
|
||||
bool opt_unknown = false;
|
||||
bool opt_dump_graph = false;
|
||||
bool opt_unknown = false;
|
||||
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
|
|
@ -43,6 +46,8 @@ int main(int argc, char** argv)
|
|||
opt_dissassemble = true;
|
||||
else if (option == "-i")
|
||||
opt_interpret = true;
|
||||
else if (option == "-g")
|
||||
opt_dump_graph = true;
|
||||
else if (option[0] != '-' && input_file.empty())
|
||||
input_file = option;
|
||||
else
|
||||
|
|
@ -89,9 +94,18 @@ int main(int argc, char** argv)
|
|||
|
||||
if (opt_compile)
|
||||
{
|
||||
auto module = eth::jit::Compiler().compile(bytecode);
|
||||
auto compiler = eth::jit::Compiler();
|
||||
auto module = compiler.compile(bytecode);
|
||||
llvm::raw_os_ostream out(std::cout);
|
||||
module->print(out, nullptr);
|
||||
|
||||
if (opt_dump_graph)
|
||||
{
|
||||
std::ofstream ofs("blocks.dot");
|
||||
compiler.dumpBasicBlockGraph(ofs);
|
||||
ofs.close();
|
||||
std::cout << "Basic blocks graph written to block.dot\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (opt_interpret)
|
||||
|
|
|
|||
Loading…
Reference in a new issue