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
6#include <algorithm>
10
11namespace jlm::hls
12{
13
14static bool
16{
17 // Keep only those entry vars that are not dead.
18 std::vector<LoopNode::ExitVar> vars = loopNode.getExitVars();
19 vars.erase(
20 std::remove_if(
21 vars.begin(),
22 vars.end(),
23 [](const LoopNode::ExitVar & var)
24 {
25 return !var.output->IsDead();
26 }),
27 vars.end());
28
29 // Remove all dead vars.
30 bool anyChanged = !vars.empty();
31 loopNode.removeExitVars(std::move(vars));
32 return anyChanged;
33}
34
35static bool
37{
38 // Keep only those entry vars that are not dead.
39 std::vector<LoopNode::EntryVar> vars = loopNode.getEntryVars();
40 vars.erase(
41 std::remove_if(
42 vars.begin(),
43 vars.end(),
44 [](const LoopNode::EntryVar & var)
45 {
46 return !var.inner->IsDead();
47 }),
48 vars.end());
49
50 // Remove all dead vars.
51 bool anyChanged = !vars.empty();
52 loopNode.removeEntryVars(std::move(vars));
53 return anyChanged;
54}
55
56static bool
58{
59 // Keep only back edge vars that have a user (instead of
60 // simply forwarding to itself).
61 std::vector<LoopNode::BackEdgeVar> vars = loopNode.getBackEdgeVars();
62 vars.erase(
63 std::remove_if(
64 vars.begin(),
65 vars.end(),
66 [](const LoopNode::BackEdgeVar & var)
67 {
68 return !(var.pre->nusers() == 1 && var.post->origin() == var.pre);
69 }),
70 vars.end());
71 // Remove all that have exactly one user, namely forward itself
72 // to next loop iteration.
73 bool anyChanged = !vars.empty();
74 loopNode.removeBackEdgeVars(std::move(vars));
75 return anyChanged;
76}
77
78static bool
80{
81 bool changed = false;
82 bool anyChanged = false;
83
84 do
85 {
86 changed = false;
87 for (auto & node : rvsdg::BottomUpTraverser(&region))
88 {
89 if (node->IsDead())
90 {
91 remove(node);
92 changed = true;
93 }
94 else if (auto loopNode = dynamic_cast<LoopNode *>(node))
95 {
100 }
101 }
103 } while (changed);
104
105 JLM_ASSERT(region.numBottomNodes() == 0);
106 return anyChanged;
107}
108
109void
111{
112 auto & rootRegion = rvsdgModule.Rvsdg().GetRootRegion();
113
114 if (rootRegion.numNodes() != 1)
115 {
116 throw util::Error("Root should have only one node now");
117 }
118
119 auto lambdaNode = dynamic_cast<const rvsdg::LambdaNode *>(rootRegion.Nodes().begin().ptr());
120 if (!lambdaNode)
121 {
122 throw util::Error("Node needs to be a lambda");
123 }
124
125 EliminateDeadNodesInRegion(*lambdaNode->subregion());
126}
127
128}
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 RemoveUnusedBackEdges(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
Variable passed between hls loop iterations.
Definition hls.hpp:752
Variable entering the hls loop.
Definition hls.hpp:722
Variable exiting the hls loop.
Definition hls.hpp:737