Skip to content

Commit

Permalink
fix dot
Browse files Browse the repository at this point in the history
  • Loading branch information
clonker committed Aug 27, 2024
1 parent 08f709f commit ac41450
Showing 1 changed file with 35 additions and 34 deletions.
69 changes: 35 additions & 34 deletions test/libyul/SSAControlFlowGraphTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ class SSACFGPrinter
public:
SSACFGPrinter(SSACFG const& _cfg, SSACFG::BlockId _blockId)
{
printBlock(_cfg, _blockId);
printBlock(_cfg, _blockId, 0);
}
SSACFGPrinter(SSACFG const& _cfg, Scope::Function const& _function)
SSACFGPrinter(SSACFG const& _cfg, size_t _functionIndex, Scope::Function const& _function)
{
printFunction(_cfg, _function);
printFunction(_cfg, _functionIndex, _function);
}
friend std::ostream& operator<<(std::ostream& stream, SSACFGPrinter const& printer) {
stream << printer.m_result.str();
Expand Down Expand Up @@ -109,17 +109,17 @@ class SSACFGPrinter
return fmt::format("φ(\\l\\\n\t{}\\l\\\n)", fmt::join(formattedArgs, ",\\l\\\n\t"));
}

void writeBlock(SSACFG const& _cfg, SSACFG::BlockId const& _id, SSACFG::BasicBlock const& _block)
void writeBlock(SSACFG const& _cfg, SSACFG::BlockId const& _id, SSACFG::BasicBlock const& _block, size_t _functionIndex)
{
auto const transform = [&](SSACFG::ValueId const& valueId) { return varToString(_cfg, valueId); };
bool entryBlock = _id.value == 0;
bool entryBlock = _id.value == 0 && _functionIndex == 0;
if (entryBlock)
{
m_result << "Entry [label=\"Entry\"];\n";
m_result << fmt::format("Entry -> Block{};\n", _id.value);
m_result << fmt::format("Entry{} [label=\"Entry\"];\n", _functionIndex);
m_result << fmt::format("Entry{} -> Block{}_{};\n", _functionIndex, _functionIndex, _id.value);
}
{
m_result << fmt::format("Block{0} [label=\"\\\nBlock {0}\\n", _id.value);
m_result << fmt::format("Block{1}_{0} [label=\"\\\nBlock {0}\\n", _id.value, _functionIndex);
for (auto const& phi : _block.phis)
{
auto const* phiValue = std::get_if<SSACFG::PhiValue>(&_cfg.valueInfo(phi));
Expand Down Expand Up @@ -154,29 +154,29 @@ class SSACFGPrinter
std::visit(util::GenericVisitor{
[&](SSACFG::BasicBlock::MainExit const&)
{
m_result << fmt::format("Block{}Exit [label=\"MainExit\"];\n", _id.value);
m_result << fmt::format("Block{0} -> Block{0}Exit;\n", _id.value);
m_result << fmt::format("Block{}_{}Exit [label=\"MainExit\"];\n", _functionIndex, _id.value);
m_result << fmt::format("Block{1}_{0} -> Block{1}_{0}Exit;\n", _id.value, _functionIndex);
},
[&](SSACFG::BasicBlock::Jump const& _jump)
{
m_result << fmt::format("Block{0} -> Block{0}Exit [arrowhead=none];\n", _id.value);
m_result << fmt::format("Block{}Exit [label=\"Jump\" shape=oval];\n", _id.value);
m_result << fmt::format("Block{}Exit -> Block{};\n", _id.value, _jump.target.value);
m_result << fmt::format("Block{1}_{0} -> Block{1}_{0}Exit [arrowhead=none];\n", _id.value, _functionIndex);
m_result << fmt::format("Block{}_{}Exit [label=\"Jump\" shape=oval];\n", _functionIndex, _id.value);
m_result << fmt::format("Block{}_{}Exit -> Block{}_{};\n", _functionIndex, _id.value, _functionIndex, _jump.target.value);
},
[&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump)
{
m_result << "Block" << _id.value << " -> Block" << _id.value << "Exit;\n";
m_result << "Block" << _id.value << "Exit [label=\"{ If ";
m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n";
m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"{ If ";
m_result << varToString(_cfg, _conditionalJump.condition);
m_result << "| { <0> Zero | <1> NonZero }}\" shape=Mrecord];\n";
m_result << "Block" << _id.value;
m_result << "Exit:0 -> Block" << _conditionalJump.zero.value << ";\n";
m_result << "Block" << _id.value;
m_result << "Exit:1 -> Block" << _conditionalJump.nonZero.value << ";\n";
m_result << "Block" << _functionIndex << "_" << _id.value;
m_result << "Exit:0 -> Block" << _functionIndex << "_" << _conditionalJump.zero.value << ";\n";
m_result << "Block" << _functionIndex << "_" << _id.value;
m_result << "Exit:1 -> Block" << _functionIndex << "_" << _conditionalJump.nonZero.value << ";\n";
},
[&](SSACFG::BasicBlock::JumpTable const& jt)
{
m_result << "Block" << _id.value << " -> Block" << _id.value << "Exit;\n";
m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n";
std::string options;
for(const auto& jumpCase : jt.cases)
{
Expand All @@ -187,31 +187,31 @@ class SSACFGPrinter
if (!options.empty())
options += " | ";
options += "<default> default";
m_result << fmt::format("Block{}Exit [label=\"{{ JT | {{ {} }} }}\" shape=Mrecord];\n", _id.value, options);
m_result << fmt::format("Block{}_{}Exit [label=\"{{ JT | {{ {} }} }}\" shape=Mrecord];\n", _functionIndex, _id.value, options);
for(const auto& jumpCase : jt.cases)
{
m_result << fmt::format("Block{}Exit:{} -> Block{};\n", _id.value, formatNumber(jumpCase.first), jumpCase.second.value);
m_result << fmt::format("Block{}_{}Exit:{} -> Block{}_{};\n", _functionIndex, _id.value, formatNumber(jumpCase.first), _functionIndex, jumpCase.second.value);
}
m_result << fmt::format("Block{}Exit:default -> Block{};\n", _id.value, jt.defaultCase.value);
m_result << fmt::format("Block{}_{}Exit:default -> Block{}_{};\n", _functionIndex, _id.value, _functionIndex, jt.defaultCase.value);
},
[&](SSACFG::BasicBlock::FunctionReturn const& fr)
{
m_result << "Block" << _id.value << "Exit [label=\"FunctionReturn["
m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"FunctionReturn["
<< fmt::format("{}", fmt::join(fr.returnValues | ranges::views::transform(transform), ", "))
<< "]\"];\n";
m_result << "Block" << _id.value << " -> Block" << _id.value << "Exit;\n";
m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n";
},
[&](SSACFG::BasicBlock::Terminated const&)
{
m_result << "Block" << _id.value << "Exit [label=\"Terminated\"];\n";
m_result << "Block" << _id.value << " -> Block" << _id.value << "Exit;\n";
m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"Terminated\"];\n";
m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n";
}
}, _block.exit);
}

}

void printBlock(SSACFG const& _cfg, SSACFG::BlockId const& _rootId)
void printBlock(SSACFG const& _cfg, SSACFG::BlockId const& _rootId, size_t _functionIndex)
{
std::set<SSACFG::BlockId> explored{};
explored.insert(_rootId);
Expand All @@ -224,7 +224,7 @@ class SSACFGPrinter
auto const id = toVisit.front();
toVisit.pop_front();
auto const& block = _cfg.block(id);
writeBlock(_cfg, id, block);
writeBlock(_cfg, id, block, _functionIndex);
block.forEachExit(
[&](SSACFG::BlockId const& _exitBlock)
{
Expand All @@ -238,7 +238,7 @@ class SSACFGPrinter
}
}

void printFunction(SSACFG const& _cfg, Scope::Function const& _fun)
void printFunction(SSACFG const& _cfg, size_t _functionIndex, Scope::Function const& _fun)
{
static auto constexpr returnsTransform = [](auto const& functionReturnValue) { return functionReturnValue.get().name.str(); };
static auto constexpr argsTransform = [](auto const& arg) { return fmt::format("v{}", std::get<1>(arg).value); };
Expand All @@ -248,8 +248,8 @@ class SSACFGPrinter
else
m_result << fmt::format("function {0}:\n {0}({1})", _fun.name.str(), fmt::join(_cfg.arguments | ranges::views::transform(argsTransform), ", "));
m_result << "\"];\n";
m_result << "FunctionEntry_" << _fun.name.str() << "_" << _cfg.entry.value << " -> Block" << _cfg.entry.value << ";\n";
printBlock(_cfg, _cfg.entry);
m_result << "FunctionEntry_" << _fun.name.str() << "_" << _cfg.entry.value << " -> Block" << _functionIndex << "_" << _cfg.entry.value << ";\n";
printBlock(_cfg, _cfg.entry, _functionIndex);
}

std::stringstream m_result{};
Expand All @@ -274,10 +274,11 @@ TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::st
object->code()->root()
);

output << "digraph SSACFG {\nnodesep=0.7;\nnode[shape=box];\n\n";
output << "digraph SSACFG {\nnodesep=0.7;\ngraph[fontname=\"DejaVu Sans\" ]\nnode[shape=box,fontname=\"DejaVu Sans\"];\n\n";
output << SSACFGPrinter(*controlFlow->mainGraph, SSACFG::BlockId{0});
size_t index = 1;
for (auto const& [function, functionGraph]: controlFlow->functionGraphMapping)
output << SSACFGPrinter(*functionGraph, *function);
output << SSACFGPrinter(*functionGraph, index++, *function);
output << "}\n";

m_obtainedResult = output.str();
Expand Down

0 comments on commit ac41450

Please sign in to comment.