mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 12:16: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);
|
std::unique_ptr<llvm::Module> compile(const bytes& bytecode);
|
||||||
|
|
||||||
|
void dumpBasicBlockGraph(std::ostream& out);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void createBasicBlocks(const bytes& bytecode);
|
void createBasicBlocks(const bytes& bytecode);
|
||||||
|
|
@ -32,6 +35,7 @@ private:
|
||||||
|
|
||||||
void linkBasicBlocks();
|
void linkBasicBlocks();
|
||||||
|
|
||||||
|
|
||||||
llvm::IRBuilder<> m_builder;
|
llvm::IRBuilder<> m_builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -22,6 +23,7 @@ void show_usage()
|
||||||
std::cerr << "usage: evmcc (-b|-c|-d)+ <inputfile.bc>\n";
|
std::cerr << "usage: evmcc (-b|-c|-d)+ <inputfile.bc>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -30,6 +32,7 @@ int main(int argc, char** argv)
|
||||||
bool opt_show_bytes = false;
|
bool opt_show_bytes = false;
|
||||||
bool opt_compile = false;
|
bool opt_compile = false;
|
||||||
bool opt_interpret = false;
|
bool opt_interpret = false;
|
||||||
|
bool opt_dump_graph = false;
|
||||||
bool opt_unknown = false;
|
bool opt_unknown = false;
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
|
|
@ -43,6 +46,8 @@ int main(int argc, char** argv)
|
||||||
opt_dissassemble = true;
|
opt_dissassemble = true;
|
||||||
else if (option == "-i")
|
else if (option == "-i")
|
||||||
opt_interpret = true;
|
opt_interpret = true;
|
||||||
|
else if (option == "-g")
|
||||||
|
opt_dump_graph = true;
|
||||||
else if (option[0] != '-' && input_file.empty())
|
else if (option[0] != '-' && input_file.empty())
|
||||||
input_file = option;
|
input_file = option;
|
||||||
else
|
else
|
||||||
|
|
@ -89,9 +94,18 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
if (opt_compile)
|
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);
|
llvm::raw_os_ostream out(std::cout);
|
||||||
module->print(out, nullptr);
|
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)
|
if (opt_interpret)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue