14 #include <unordered_map>
21 EntryNode::~EntryNode() noexcept = default;
23 ExitNode::~ExitNode() noexcept = default;
28 entry_ = std::make_unique<EntryNode>(*
this);
29 exit_ = std::make_unique<ExitNode>(*
this);
30 entry_->add_outedge(exit_.get());
36 auto & cfg = nodeit->cfg();
38 for (
auto & inedge : nodeit->InEdges())
40 if (inedge.source() != &*nodeit)
41 throw util::Error(
"cannot remove node. It has still incoming edges.");
44 nodeit->remove_outedges();
45 std::unique_ptr<BasicBlock> tmp(&*nodeit);
46 auto rit =
iterator(std::next(cfg.nodes_.find(tmp)));
47 cfg.nodes_.erase(tmp);
55 auto & cfg = bb->
cfg();
67 for (
const auto & node : nodes)
69 str += labels.at(node) +
":";
70 str += (is<BasicBlock>(node) ?
"\n" :
" ");
72 if (
const auto entryNode =
dynamic_cast<const EntryNode *
>(node))
76 else if (
const auto exitNode =
dynamic_cast<const ExitNode *
>(node))
80 else if (
auto basicBlock =
dynamic_cast<const BasicBlock *
>(node))
82 str +=
ToAscii(*basicBlock, labels);
97 for (
size_t n = 0; n < entryNode.
narguments(); n++)
109 for (
size_t n = 0; n < exitNode.
nresults(); n++)
120 const std::unordered_map<ControlFlowGraphNode *, std::string> & labels)
122 auto & threeAddressCodes = basicBlock.
tacs();
125 for (
const auto & tac : threeAddressCodes)
128 if (tac != threeAddressCodes.last())
132 if (threeAddressCodes.last())
134 if (is<BranchOperation>(threeAddressCodes.last()->operation()))
150 const std::unordered_map<ControlFlowGraphNode *, std::string> & labels)
153 std::string str(
"[");
154 for (
auto & outedge : node.
OutEdges())
156 str += labels.at(outedge.sink());
165 std::unordered_map<ControlFlowGraphNode *, std::string>
168 std::unordered_map<ControlFlowGraphNode *, std::string> map;
169 for (
size_t n = 0; n < nodes.size(); n++)
171 auto node = nodes[n];
172 if (is<EntryNode>(node))
176 else if (is<ExitNode>(node))
180 else if (is<BasicBlock>(node))
193 std::vector<ControlFlowGraphNode *>
200 std::unordered_set<ControlFlowGraphNode *> &,
201 std::vector<ControlFlowGraphNode *> &)>
203 std::unordered_set<ControlFlowGraphNode *> & visited,
204 std::vector<ControlFlowGraphNode *> & nodes)
206 visited.insert(node);
210 if (visited.find(edge->sink()) == visited.end())
211 traverse(edge->sink(), visited, nodes);
214 nodes.push_back(node);
217 std::vector<ControlFlowGraphNode *> nodes;
218 std::unordered_set<ControlFlowGraphNode *> visited;
219 traverse(cfg.
entry(), visited, nodes);
224 std::vector<ControlFlowGraphNode *>
228 std::reverse(nodes.begin(), nodes.end());
232 std::vector<ControlFlowGraphNode *>
235 std::deque<ControlFlowGraphNode *> next({ cfg.
entry() });
236 std::vector<ControlFlowGraphNode *> nodes({ cfg.
entry() });
237 std::unordered_set<ControlFlowGraphNode *> visited({ cfg.
entry() });
238 while (!next.empty())
240 auto node = next.front();
243 for (
auto & outedge : node->OutEdges())
245 if (visited.find(outedge.sink()) == visited.end())
247 visited.insert(outedge.sink());
248 next.push_back(outedge.sink());
249 nodes.push_back(outedge.sink());
261 for (
auto & node : cfg)
263 if (
auto bb =
dynamic_cast<const BasicBlock *
>(&node))
264 ntacs += bb->ntacs();
~Argument() noexcept override
const ThreeAddressCodeList & tacs() const noexcept
ControlFlowGraphEdge * OutEdge(size_t n) const
ControlFlowGraph & cfg() const noexcept
outedge_iterator_range OutEdges() const
size_t NumOutEdges() const noexcept
static std::string ToAscii(const ControlFlowGraph &controlFlowGraph)
EntryNode * entry() const noexcept
static ControlFlowGraph::iterator remove_node(ControlFlowGraph::iterator &it)
ControlFlowGraph::iterator find_node(BasicBlock *bb)
static std::unordered_map< ControlFlowGraphNode *, std::string > CreateLabels(const std::vector< ControlFlowGraphNode * > &nodes)
static std::string CreateTargets(const ControlFlowGraphNode &node, const std::unordered_map< ControlFlowGraphNode *, std::string > &labels)
util::PtrIterator< BasicBlock, std::unordered_set< std::unique_ptr< BasicBlock > >::iterator > iterator
size_t narguments() const noexcept
const llvm::Argument * argument(size_t index) const
const Variable * result(size_t index) const
size_t nresults() const noexcept
static std::string ToAscii(const ThreeAddressCode &threeAddressCode)
virtual std::string debug_string() const
#define JLM_UNREACHABLE(msg)
Global memory state passed between functions.
std::vector< ControlFlowGraphNode * > breadth_first(const ControlFlowGraph &cfg)
std::vector< ControlFlowGraphNode * > postorder(const ControlFlowGraph &cfg)
size_t ntacs(const AggregationNode &root)
bool is_closed(const ControlFlowGraph &cfg)
std::vector< ControlFlowGraphNode * > reverse_postorder(const ControlFlowGraph &cfg)
static std::string strfmt(Args... args)