11 #include <unordered_map>
26 std::vector<std::unique_ptr<AggregationNode>> children;
27 for (
size_t n = 0; n < node.
children_.size(); n++)
31 if (is<LinearAggregationNode>(child.get()))
34 std::move(tmp.begin(), tmp.end(), std::back_inserter(children));
38 children.push_back(std::move(child));
45 if (is<LinearAggregationNode>(&node))
47 auto children =
reduce(node);
49 node.remove_children();
50 for (
auto & child : children)
51 node.add_child(std::move(child));
54 for (
auto & child : node)
128 return map_.find(node) !=
map_.end();
131 std::unique_ptr<AggregationNode> &
136 return map_.at(node);
142 map_[node] = std::move(anode);
151 static std::unique_ptr<AggregationMap>
154 auto exit = cfg.
exit();
155 auto entry = cfg.
entry();
156 auto map = std::make_unique<AggregationMap>();
160 for (
auto & node : cfg)
170 std::unordered_map<ControlFlowGraphNode *, std::unique_ptr<AggregationNode>>
map_;
176 return node->NumInEdges() == 1 && node->NumOutEdges() == 1;
182 return node->NumOutEdges() > 1;
188 return node->NumInEdges() > 1;
194 if (split->NumOutEdges() < 2)
197 if (split->OutEdge(0)->sink()->NumOutEdges() != 1)
200 auto join = split->OutEdge(0)->sink()->OutEdge(0)->sink();
201 for (
auto & edge : split->OutEdges())
203 if (edge.sink()->NumInEdges() != 1)
205 if (edge.sink()->NumOutEdges() != 1)
207 if (edge.sink()->OutEdge(0)->sink() != join)
217 if (node->NumOutEdges() != 1)
220 auto exit = node->OutEdge(0)->sink();
221 if (exit->NumInEdges() != 1)
227 static ControlFlowGraphNode *
228 aggregate(ControlFlowGraphNode *, ControlFlowGraphNode *, AggregationMap &);
243 redge->source()->remove_outedge(redge->index());
247 map.
insert(sese, std::move(loop));
277 static ControlFlowGraphNode *
286 for (
auto & edge : split->
OutEdges())
291 JLM_ASSERT(edge.sink()->OutEdge(0)->sink() == join);
297 sese->add_outedge(join);
300 for (
auto & edge : split->
OutEdges())
302 edge.sink()->remove_outedge(0);
303 branch->add_child(std::move(map.
lookup(edge.sink())));
307 auto & child = map.
lookup(split);
316 *entry = split == *entry ? sese : *entry;
337 static ControlFlowGraphNode *
349 for (
auto & edge : sink->OutEdges())
350 sese->add_outedge(edge.sink());
351 sink->remove_outedges();
353 auto child0 = std::move(map.
lookup(source));
354 auto child1 = std::move(map.
lookup(sink));
363 *entry = source == *entry ? sese : *entry;
364 *exit = sink == *exit ? sese : *exit;
376 for (
auto scc : sccs)
380 if (sccStructure->IsTailControlledLoop())
430 for (
auto & edge : node->
OutEdges())
478 static ControlFlowGraphNode *
488 std::unique_ptr<AggregationNode>
496 return std::move(map->lookup(root));
503 for (
auto & child : root)
507 n += bb->tacs().ntacs();
static std::unique_ptr< AggregationMap > create(ControlFlowGraph &cfg)
void remove(ControlFlowGraphNode *node)
std::unique_ptr< AggregationNode > & lookup(ControlFlowGraphNode *node)
void insert(ControlFlowGraphNode *node, std::unique_ptr< AggregationNode > anode)
bool contains(ControlFlowGraphNode *node) const
std::unordered_map< ControlFlowGraphNode *, std::unique_ptr< AggregationNode > > map_
virtual ~AggregationNode() noexcept
std::vector< std::unique_ptr< AggregationNode > > children_
static std::unique_ptr< AggregationNode > create()
~BasicBlockAggregationNode() noexcept override
static BasicBlock * create(ControlFlowGraph &cfg)
static std::unique_ptr< AggregationNode > create()
~BranchAggregationNode() noexcept override
ControlFlowGraphNode * sink() const noexcept
ControlFlowGraphEdge * OutEdge(size_t n) const
ControlFlowGraph & cfg() const noexcept
outedge_iterator_range OutEdges() const
size_t NumOutEdges() const noexcept
void divert_inedges(llvm::ControlFlowGraphNode *new_successor)
EntryNode * entry() const noexcept
ExitNode * exit() const noexcept
std::vector< llvm::Argument * > arguments_
constiterator end() const
std::string debug_string() const override
util::PtrIterator< const llvm::Argument, std::vector< llvm::Argument * >::const_iterator > constiterator
static std::unique_ptr< AggregationNode > create(const std::vector< llvm::Argument * > &arguments)
~EntryAggregationNode() noexcept override
static std::unique_ptr< AggregationNode > create(const std::vector< const Variable * > &results)
~ExitAggregationNode() noexcept override
~LinearAggregationNode() noexcept override
static std::unique_ptr< AggregationNode > create(std::unique_ptr< AggregationNode > n1, std::unique_ptr< AggregationNode > n2)
~LoopAggregationNode() noexcept override
static std::unique_ptr< AggregationNode > create(std::unique_ptr< AggregationNode > body)
Strongly Connected Component Structure.
bool IsTailControlledLoop() const noexcept
EdgeIteratorRange ExitEdges() const
NodeIteratorRange EntryNodes() const
EdgeIteratorRange RepetitionEdges() const
static std::unique_ptr< StronglyConnectedComponentStructure > Create(const StronglyConnectedComponent &scc)
#define JLM_UNREACHABLE(msg)
Global memory state passed between functions.
static void aggregate_loops(ControlFlowGraphNode *entry, ControlFlowGraphNode *exit, AggregationMap &map)
std::vector< StronglyConnectedComponent > find_sccs(const ControlFlowGraph &cfg)
static ControlFlowGraphNode * aggregate(ControlFlowGraphNode *, ControlFlowGraphNode *, AggregationMap &)
static void reduce_loop(const StronglyConnectedComponentStructure &sccstruct, AggregationMap &map)
static bool is_branch_join(const ControlFlowGraphNode *node) noexcept
static bool is_linear(const ControlFlowGraphNode *node) noexcept
static bool reduce(const ControlFlowGraph &cfg, const std::function< bool(llvm::ControlFlowGraphNode *, std::unordered_set< llvm::ControlFlowGraphNode * > &)> &f)
static ControlFlowGraphNode * reduce_branch(ControlFlowGraphNode *split, ControlFlowGraphNode **entry, AggregationMap &map)
static bool is_branch_split(const ControlFlowGraphNode *node) noexcept
static bool is_branch(const ControlFlowGraphNode *split) noexcept
static void aggregate_acyclic_sese(ControlFlowGraphNode *node, ControlFlowGraphNode **entry, ControlFlowGraphNode **exit, AggregationMap &map)
static ControlFlowGraphNode * reduce_linear(ControlFlowGraphNode *source, ControlFlowGraphNode **entry, ControlFlowGraphNode **exit, AggregationMap &map)
bool is_proper_structured(const ControlFlowGraph &cfg)
size_t ntacs(const AggregationNode &root)
static bool is_sese_basic_block(const ControlFlowGraphNode *node) noexcept