11#include <unordered_map>
33 auto & cfg = loopEntry.
cfg();
37 if (er->sink() != &loopEntry)
47 replacement->add_outedge(ex->sink());
49 er->divert(&loopEntry);
59 auto & cfg = loop.
ne->
cfg();
64 cfg.remove_node(loop.
insert);
68static const ThreeAddressCodeVariable *
76static const ThreeAddressCodeVariable &
86static const ThreeAddressCodeVariable &
96static const ThreeAddressCodeVariable &
109 const auto numAlternatives =
110 util::assertedCast<const rvsdg::ControlType>(&operand->
type())->nalternatives();
120 const auto numAlternatives =
121 util::assertedCast<const rvsdg::ControlType>(&variable.
type())->nalternatives();
123 auto op = std::make_unique<rvsdg::ControlConstantOperation>(
136 std::unordered_map<ControlFlowGraphNode *, size_t> indices;
148 auto os = edge->sink();
149 edge->divert(newEntryNode);
181 std::unordered_map<ControlFlowGraphNode *, size_t> indices;
182 for (
auto & node : sccStructure.
ExitNodes())
191 for (
auto & edge : sccStructure.
ExitEdges())
193 auto os = edge->sink();
194 edge->divert(&newRepetitionNode);
195 auto bb = edge->split();
210 std::unordered_map<ControlFlowGraphNode *, size_t> indices;
216 auto os = edge->sink();
217 edge->divert(&newRepetitionNode);
218 auto basicBlock = edge->split();
228 if (
auto basicBlock =
dynamic_cast<BasicBlock *
>(node))
239 ControlFlowGraphNode &,
240 ControlFlowGraphNode &,
241 std::vector<TailControlledLoop> &);
249static std::unique_ptr<rvsdg::MatchOperation>
254 const size_t numBits = matchOperation.
nbits();
256 auto [oldValue, oldAlternative] = *matchOperation.
begin();
257 const auto newDefaultAlternative = oldAlternative;
258 auto newAlternative = oldDefaultAlternative;
262 { { oldValue, newAlternative } },
263 newDefaultAlternative,
281 if (repetitionEdge->index() == 1)
290 auto exitNode = util::assertedCast<BasicBlock>((*sccStructure.
ExitEdges().
begin())->source());
292 auto exitEdgeSink = exitEdge->sink();
293 auto repetitionEdgeSink = repetitionEdge->sink();
295 repetitionEdge->divert(exitEdgeSink);
296 exitEdge->divert(repetitionEdgeSink);
299 auto & threeAddressCodes = exitNode->tacs();
300 auto & branchTac = *threeAddressCodes.last();
303 auto & branchOperand = *util::assertedCast<const ThreeAddressCodeVariable>(branchTac.operand(0));
304 auto & matchTac = *branchOperand.tac();
305 JLM_ASSERT(is<rvsdg::MatchOperation>(&matchTac));
306 JLM_ASSERT(branchTac.operand(0) == matchTac.result(0));
307 auto & matchOperation = *util::assertedCast<const rvsdg::MatchOperation>(&matchTac.operation());
308 JLM_ASSERT(matchOperation.nalternatives() == 2);
311 auto newMatchOperand = matchTac.operand(0);
312 matchTac.replace(*newMatchOperation, { newMatchOperand });
319 std::vector<TailControlledLoop> & loops)
321 if (®ionEntry == ®ionExit)
324 auto & cfg = regionEntry.
cfg();
326 const auto stronglyConnectedComponents =
find_sccs(®ionEntry, ®ionExit);
327 for (
auto & scc : stronglyConnectedComponents)
331 if (sccStructure->IsTailControlledLoop())
334 auto loopEntry = *sccStructure->EntryNodes().begin();
335 auto loopExit = (*sccStructure->ExitEdges().begin())->source();
338 loops.push_back(
ExtractLoop(*loopEntry, *loopExit));
346 newRepetitionNode.add_outedge(&newExitNode);
347 newRepetitionNode.add_outedge(&newEntryNode);
350 if (sccStructure->NumEntryNodes() > 1)
361 if (sccStructure->NumExitNodes() > 1)
383 loops.push_back(
ExtractLoop(newEntryNode, newRepetitionNode));
388static ControlFlowGraphNode &
394 if (headBranch->
is_branch() || headBranch == &end)
409 std::deque toVisit(1, edge->
sink());
410 while (toVisit.size() != 0)
414 if (
nodes.Contains(node))
418 for (
auto & inedge : node->
InEdges())
420 if (!edges.Contains(&inedge))
430 for (
auto & outedge : node->
OutEdges())
432 edges.insert(&outedge);
433 toVisit.push_back(outedge.sink());
444 std::unordered_map<ControlFlowGraphEdge *, util::HashSet<ControlFlowGraphEdge *>>
edges;
452 std::unordered_map<ControlFlowGraphEdge *, util::HashSet<ControlFlowGraphNode *>> dominatorGraphs;
453 for (
auto & outedge : headBranch.
OutEdges())
457 for (
auto & outedge : headBranch.
OutEdges())
459 auto & dominatorGraph = dominatorGraphs[&outedge];
460 if (dominatorGraph.IsEmpty())
462 c.
edges[&outedge].insert(&outedge);
463 c.
points.insert(outedge.sink());
467 for (
const auto & node : dominatorGraph.Items())
469 for (
auto & outedge2 : node->OutEdges())
471 if (!dominatorGraph.Contains(outedge2.sink()))
473 c.
edges[&outedge].insert(&outedge2);
474 c.
points.insert(outedge2.sink());
486 auto & cfg = entry.
cfg();
489 if (&headBranch == &exit)
493 auto & hbb = *
static_cast<BasicBlock *
>(&headBranch);
498 if (continuationPoints.Size() == 1)
500 const auto continuationPoint = *continuationPoints.Items().begin();
501 for (
auto & outedge : headBranch.OutEdges())
503 auto continuationEdges = continuationEdgesDict[&outedge];
506 if (outedge.sink() == continuationPoint)
513 if (continuationEdges.Size() == 1)
515 const auto continuationEdge = *continuationEdges.Items().begin();
523 nullNode->add_outedge(continuationPoint);
524 for (
const auto & e : continuationEdges.Items())
538 std::unordered_map<ControlFlowGraphNode *, size_t> indices;
539 for (
const auto & cp : continuationPoints.Items())
541 continuationNode->add_outedge(cp);
542 indices.insert({ cp, indices.size() });
546 for (
auto & outedge : headBranch.OutEdges())
548 auto continuationEdges = continuationEdgesDict[&outedge];
551 nullNode->add_outedge(continuationNode);
552 for (
const auto & e : continuationEdges.Items())
556 bb->add_outedge(nullNode);
572 std::vector<TailControlledLoop> loops;
575 for (
const auto & loop : loops)
591 std::vector<TailControlledLoop> & tailControlledLoops)
602 std::vector<TailControlledLoop> loops;
605 for (
const auto & loop : loops)
std::vector< rvsdg::Node * > nodes
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *rhs, const Variable *lhs)
llvm::ThreeAddressCode * append_last(std::unique_ptr< llvm::ThreeAddressCode > tac)
ThreeAddressCode * last() const noexcept
llvm::ThreeAddressCode * insert_before_branch(std::unique_ptr< llvm::ThreeAddressCode > tac)
static BasicBlock * create(ControlFlowGraph &cfg)
static std::unique_ptr< llvm::ThreeAddressCode > create(size_t nalternatives, const Variable *operand)
ControlFlowGraphNode * sink() const noexcept
bool is_branch() const noexcept
inedge_iterator_range InEdges() const
ControlFlowGraph & cfg() const noexcept
size_t NumInEdges() const noexcept
ControlFlowGraphEdge * OutEdge(size_t n) const
outedge_iterator_range OutEdges() const
ControlFlowGraphEdge * add_outedge(ControlFlowGraphNode *sink)
size_t NumOutEdges() const noexcept
void divert_inedges(llvm::ControlFlowGraphNode *new_successor)
ExitNode * exit() const noexcept
EntryNode * entry() const noexcept
Strongly Connected Component Structure.
bool IsTailControlledLoop() const noexcept
EdgeIteratorRange ExitEdges() const
size_t NumExitEdges() const noexcept
NodeIteratorRange ExitNodes() const
NodeIteratorRange EntryNodes() const
EdgeIteratorRange RepetitionEdges() const
static std::unique_ptr< StronglyConnectedComponentStructure > Create(const StronglyConnectedComponent &scc)
EdgeIteratorRange EntryEdges() const
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands)
const ThreeAddressCodeVariable * result(size_t index) const noexcept
static jlm::rvsdg::Output * Create(rvsdg::Region ®ion, std::shared_ptr< const jlm::rvsdg::Type > type)
const jlm::rvsdg::Type & type() const noexcept
static std::shared_ptr< const ControlType > Create(std::size_t nalternatives)
Instantiates control type.
uint64_t nalternatives() const noexcept
const_iterator begin() const
size_t nbits() const noexcept
uint64_t default_alternative() const noexcept
Global memory state passed between functions.
static void RestructureLoopRepetition(const StronglyConnectedComponentStructure &sccStructure, ControlFlowGraphNode &newRepetitionNode, const ThreeAddressCodeVariable *entryVariable, const ThreeAddressCodeVariable &repetitionVariable)
std::vector< StronglyConnectedComponent > find_sccs(const ControlFlowGraph &cfg)
static void RestructureBranches(ControlFlowGraphNode &entry, ControlFlowGraphNode &exit)
static void AppendBranch(BasicBlock &basicBlock, const Variable *operand)
static Continuation ComputeContinuation(const ControlFlowGraphNode &headBranch)
static void RestructureControlFlow(ControlFlowGraphNode &, ControlFlowGraphNode &, std::vector< TailControlledLoop > &)
static void RestructureLoopExit(const StronglyConnectedComponentStructure &sccStructure, BasicBlock &newRepetitionNode, BasicBlock &newExitNode, ControlFlowGraphNode ®ionExit, const ThreeAddressCodeVariable &repetitionVariable, const ThreeAddressCodeVariable *exitVariable)
static void RestructureLoops(ControlFlowGraphNode ®ionEntry, ControlFlowGraphNode ®ionExit, std::vector< TailControlledLoop > &loops)
static void AppendConstantAssignment(BasicBlock &basicBlock, const ThreeAddressCodeVariable &variable, const size_t value)
static void ReinsertLoop(const TailControlledLoop &loop)
static const ThreeAddressCodeVariable * CreateContinuationVariable(BasicBlock &bb, std::shared_ptr< const rvsdg::ControlType > type)
static BasicBlock * GetEntryVariableBlock(ControlFlowGraphNode *node)
static util::HashSet< ControlFlowGraphNode * > ComputeDominatorGraph(const ControlFlowGraphEdge *edge)
static void adjustLoopRepetitionEdge(const StronglyConnectedComponentStructure &sccStructure)
static TailControlledLoop ExtractLoop(ControlFlowGraphNode &loopEntry, ControlFlowGraphNode &loopExit)
static const ThreeAddressCodeVariable & CreateLoopRepetitionVariable(BasicBlock &basicBlock)
static const ThreeAddressCodeVariable & CreateLoopExitVariable(BasicBlock &bb, std::shared_ptr< const rvsdg::ControlType > type)
bool is_proper_structured(const ControlFlowGraph &cfg)
static const ThreeAddressCodeVariable & CreateLoopEntryVariable(BasicBlock &bb, std::shared_ptr< const rvsdg::ControlType > type)
static std::unique_ptr< rvsdg::MatchOperation > invertMatchOperation(const rvsdg::MatchOperation &matchOperation)
bool is_closed(const ControlFlowGraph &cfg)
static bool is_acyclic(const ControlFlowGraph &cfg)
static ControlFlowGraphNode & ComputeHeadBranch(ControlFlowGraphNode &start, ControlFlowGraphNode &end)
static void RestructureLoopEntry(const StronglyConnectedComponentStructure &sccStructure, BasicBlock *newEntryNode, const ThreeAddressCodeVariable *entryVariable)
static std::string strfmt(Args... args)
util::HashSet< ControlFlowGraphNode * > points
std::unordered_map< ControlFlowGraphEdge *, util::HashSet< ControlFlowGraphEdge * > > edges
TailControlledLoop(ControlFlowGraphNode *entry, BasicBlock *i, BasicBlock *r)
ControlFlowGraphNode * ne