Jlm
Loading...
Searching...
No Matches
DeadNodeElimination.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2021 David Metz <david.c.metz@ntnu.no>
3 * See COPYING for terms of redistribution.
4 */
5
9
10namespace jlm::hls
11{
12
13static bool
15{
16 bool anyChanged = false;
17
18 // go through in reverse because we might remove outputs
19 for (int i = loopNode.noutputs() - 1; i >= 0; --i)
20 {
21 auto output = loopNode.output(i);
22 if (output->nusers() == 0)
23 {
24 loopNode.removeLoopOutput(output);
25 anyChanged = true;
26 }
27 }
28 return anyChanged;
29}
30
31static bool
33{
34 bool anyChanged = false;
35 auto loopSubregion = loopNode.subregion();
36
37 // go through in reverse because we might remove inputs
38 for (int i = loopNode.ninputs() - 1; i >= 0; --i)
39 {
40 auto input = loopNode.input(i);
41 JLM_ASSERT(input->arguments.size() == 1);
42 auto argument = input->arguments.begin();
43
44 if (argument->nusers() == 0)
45 {
46 loopNode.removeLoopInput(input);
47 anyChanged = true;
48 }
49 }
50
51 // clean up unused arguments - only ones without an input should be left
52 // go through in reverse because we might remove some
53 for (int i = loopSubregion->narguments() - 1; i >= 0; --i)
54 {
55 auto argument = loopSubregion->argument(i);
56
57 if (auto backedgeArgument = dynamic_cast<BackEdgeArgument *>(argument))
58 {
59 auto result = backedgeArgument->result();
60 JLM_ASSERT(*result->Type() == *argument->Type());
61
62 if (argument->nusers() == 0 || (argument->nusers() == 1 && result->origin() == argument))
63 {
64 loopSubregion->RemoveResults({ result->index() });
65 loopSubregion->RemoveArguments({ argument->index() });
66 }
67 }
68 else
69 {
70 JLM_ASSERT(argument->nusers() != 0);
71 }
72 }
73
74 return anyChanged;
75}
76
77static bool
79{
80 bool changed = false;
81 bool anyChanged = false;
82
83 do
84 {
85 changed = false;
86 for (auto & node : rvsdg::BottomUpTraverser(&region))
87 {
88 if (node->IsDead())
89 {
90 remove(node);
91 changed = true;
92 }
93 else if (auto loopNode = dynamic_cast<LoopNode *>(node))
94 {
98 }
99 }
101 } while (changed);
102
103 JLM_ASSERT(region.numBottomNodes() == 0);
104 return anyChanged;
105}
106
107void
109{
110 auto & rootRegion = rvsdgModule.Rvsdg().GetRootRegion();
111
112 if (rootRegion.numNodes() != 1)
113 {
114 throw util::Error("Root should have only one node now");
115 }
116
117 auto lambdaNode = dynamic_cast<const rvsdg::LambdaNode *>(rootRegion.Nodes().begin().ptr());
118 if (!lambdaNode)
119 {
120 throw util::Error("Node needs to be a lambda");
121 }
122
124}
125
126}
Represent acyclic RVSDG subgraphs.
Definition region.hpp:213
size_t numBottomNodes() const noexcept
Definition region.hpp:528
#define JLM_ASSERT(x)
Definition common.hpp:16
static bool RemoveUnusedLoopOutputs(LoopNode &loopNode)
static bool RemoveUnusedInputs(LoopNode &loopNode)
static bool EliminateDeadNodesInRegion(rvsdg::Region &region)
void EliminateDeadNodes(llvm::LlvmRvsdgModule &rvsdgModule)
static void remove(Node *node)
Definition region.hpp:1035
detail::BottomUpTraverserGeneric< false > BottomUpTraverser
Traverser for visiting every node in a region in a bottom up order.
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872