Jlm
Loading...
Searching...
No Matches
jlm
hls
backend
rvsdg2rhls
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>
7
#include <
jlm/hls/backend/rvsdg2rhls/DeadNodeElimination.hpp
>
8
#include <
jlm/llvm/ir/operators/lambda.hpp
>
9
#include <
jlm/rvsdg/traverser.hpp
>
10
11
namespace
jlm::hls
12
{
13
14
static
bool
15
RemoveUnusedLoopOutputs
(
LoopNode
&
loopNode
)
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
35
static
bool
36
RemoveUnusedInputs
(
LoopNode
&
loopNode
)
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
56
static
bool
57
RemoveUnusedBackEdges
(
LoopNode
&
loopNode
)
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
78
static
bool
79
EliminateDeadNodesInRegion
(
rvsdg::Region
& region)
80
{
81
bool
changed
=
false
;
82
bool
anyChanged
=
false
;
83
84
do
85
{
86
changed
=
false
;
87
for
(
auto
& node :
rvsdg::BottomUpTraverser
(®ion))
88
{
89
if
(node->IsDead())
90
{
91
remove
(node);
92
changed
=
true
;
93
}
94
else
if
(
auto
loopNode
=
dynamic_cast<
LoopNode
*
>
(node))
95
{
96
changed
|=
RemoveUnusedLoopOutputs
(*
loopNode
);
97
changed
|=
RemoveUnusedInputs
(*
loopNode
);
98
changed
|=
RemoveUnusedBackEdges
(*
loopNode
);
99
changed
|=
EliminateDeadNodesInRegion
(*
loopNode
->subregion());
100
}
101
}
102
anyChanged
|=
changed
;
103
}
while
(
changed
);
104
105
JLM_ASSERT
(region.
numBottomNodes
() == 0);
106
return
anyChanged
;
107
}
108
109
void
110
EliminateDeadNodes
(
llvm::LlvmRvsdgModule
&
rvsdgModule
)
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
}
jlm::hls::LoopNode
Definition
hls.hpp:708
jlm::llvm::LlvmRvsdgModule
Definition
RvsdgModule.hpp:203
jlm::rvsdg::LambdaNode
Lambda node.
Definition
lambda.hpp:83
jlm::rvsdg::Region
Represent acyclic RVSDG subgraphs.
Definition
region.hpp:213
jlm::rvsdg::Region::numBottomNodes
size_t numBottomNodes() const noexcept
Definition
region.hpp:528
jlm::util::Error
Definition
common.hpp:57
JLM_ASSERT
#define JLM_ASSERT(x)
Definition
common.hpp:16
DeadNodeElimination.hpp
lambda.hpp
jlm::hls
Definition
FirrtlToVerilogConverter.cpp:18
jlm::hls::RemoveUnusedLoopOutputs
static bool RemoveUnusedLoopOutputs(LoopNode &loopNode)
Definition
DeadNodeElimination.cpp:15
jlm::hls::RemoveUnusedBackEdges
static bool RemoveUnusedBackEdges(LoopNode &loopNode)
Definition
DeadNodeElimination.cpp:57
jlm::hls::RemoveUnusedInputs
static bool RemoveUnusedInputs(LoopNode &loopNode)
Definition
DeadNodeElimination.cpp:36
jlm::hls::EliminateDeadNodesInRegion
static bool EliminateDeadNodesInRegion(rvsdg::Region ®ion)
Definition
DeadNodeElimination.cpp:79
jlm::hls::EliminateDeadNodes
void EliminateDeadNodes(llvm::LlvmRvsdgModule &rvsdgModule)
Definition
DeadNodeElimination.cpp:110
jlm::rvsdg::remove
static void remove(Node *node)
Definition
region.hpp:1035
jlm::rvsdg::BottomUpTraverser
detail::BottomUpTraverserGeneric< false > BottomUpTraverser
Traverser for visiting every node in a region in a bottom up order.
Definition
traverser.hpp:320
jlm::rvsdg::TryGetOwnerNode
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition
node.hpp:872
jlm::hls::LoopNode::BackEdgeVar
Variable passed between hls loop iterations.
Definition
hls.hpp:752
jlm::hls::LoopNode::EntryVar
Variable entering the hls loop.
Definition
hls.hpp:722
jlm::hls::LoopNode::ExitVar
Variable exiting the hls loop.
Definition
hls.hpp:737
traverser.hpp
Generated by
1.9.8