Jlm
Loading...
Searching...
No Matches
GammaConversion.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
7#include <jlm/hls/ir/hls.hpp>
8#include <jlm/rvsdg/gamma.hpp>
10#include <jlm/rvsdg/theta.hpp>
12
13namespace jlm::hls
14{
15
16static void
18{
20
21 // create a branch for each gamma input and map the corresponding argument of each subregion to an
22 // output of the branch
23 for (const auto & entryvar : gammaNode.GetEntryVars())
24 {
25 auto branchResults =
26 BranchOperation::create(*gammaNode.predicate()->origin(), *entryvar.input->origin());
27
28 for (size_t s = 0; s < gammaNode.nsubregions(); s++)
29 {
30 substitutionMap.insert(entryvar.branchArgument[s], branchResults[s]);
31 }
32 }
33
34 for (size_t s = 0; s < gammaNode.nsubregions(); s++)
35 {
36 gammaNode.subregion(s)->copy(gammaNode.region(), substitutionMap);
37 }
38
39 for (const auto & ex : gammaNode.GetExitVars())
40 {
41 std::vector<rvsdg::Output *> alternatives;
42 for (size_t s = 0; s < gammaNode.nsubregions(); s++)
43 {
44 alternatives.push_back(&substitutionMap.lookup(*ex.branchResult[s]->origin()));
45 }
46 // create mux nodes for each gamma output
47 // use mux instead of merge in case of paths with different delay - otherwise one could overtake
48 // the other see https://ieeexplore.ieee.org/abstract/document/9515491
49 auto mux = MuxOperation::create(*gammaNode.predicate()->origin(), alternatives, false);
50
51 ex.output->divert_users(mux[0]);
52 }
53
54 remove(&gammaNode);
55}
56
57static void
59{
61
62 // Map arguments to origins of inputs. Forks will automatically be created later
63 for (const auto & entryvar : gammaNode.GetEntryVars())
64 {
65 for (size_t s = 0; s < gammaNode.nsubregions(); s++)
66 {
67 substitutionMap.insert(entryvar.branchArgument[s], entryvar.input->origin());
68 }
69 }
70
71 for (size_t s = 0; s < gammaNode.nsubregions(); s++)
72 {
73 gammaNode.subregion(s)->copy(gammaNode.region(), substitutionMap);
74 }
75
76 for (const auto & ex : gammaNode.GetExitVars())
77 {
78 std::vector<rvsdg::Output *> alternatives;
79 for (size_t s = 0; s < gammaNode.nsubregions(); s++)
80 {
81 alternatives.push_back(&substitutionMap.lookup(*ex.branchResult[s]->origin()));
82 }
83
84 // create discarding mux for each gamma output
85 auto merge = MuxOperation::create(*gammaNode.predicate()->origin(), alternatives, true);
86
87 ex.output->divert_users(merge[0]);
88 }
89
90 remove(&gammaNode);
91}
92
93static bool
95{
96 for (size_t i = 0; i < gammaNode.noutputs(); ++i)
97 {
98 auto gammaOutput = gammaNode.output(i);
99 if (gammaOutput->Type()->Kind() == rvsdg::TypeKind::State)
100 {
101 // don't allow state outputs since they imply operations with side effects
102 return false;
103 }
104 }
105
106 for (size_t i = 0; i < gammaNode.nsubregions(); ++i)
107 {
108 for (auto & node : gammaNode.subregion(i)->Nodes())
109 {
110 if (dynamic_cast<const rvsdg::ThetaNode *>(&node) || dynamic_cast<const LoopNode *>(&node))
111 {
112 // don't allow thetas or loops since they could potentially block forever
113 return false;
114 }
115 else if (auto innerGammaNode = dynamic_cast<rvsdg::GammaNode *>(&node))
116 {
118 {
119 // only allow gammas that can also be speculated on
120 return false;
121 }
122 }
124 {
125 throw util::Error("Unexpected structural node: " + node.DebugString());
126 }
127 }
128 }
129
130 return true;
131}
132
133static void
135
136static void
138{
139 for (size_t n = 0; n < structuralNode.nsubregions(); n++)
140 {
142 }
143
144 if (auto gammaNode = dynamic_cast<rvsdg::GammaNode *>(&structuralNode))
145 {
146 if (CanGammaNodeBeSpeculative(*gammaNode))
147 {
149 }
150 else
151 {
153 }
154 }
155}
156
157static void
159{
160 for (auto & node : rvsdg::TopDownTraverser(&region))
161 {
162 if (auto structuralNode = dynamic_cast<rvsdg::StructuralNode *>(node))
163 {
165 }
166 }
167}
168
170
174
175void
180
181}
static std::vector< jlm::rvsdg::Output * > create(jlm::rvsdg::Output &predicate, jlm::rvsdg::Output &value, bool loop=false)
Definition hls.hpp:68
void Run(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
~GammaNodeConversion() noexcept override
static std::vector< jlm::rvsdg::Output * > create(jlm::rvsdg::Output &predicate, const std::vector< jlm::rvsdg::Output * > &alternatives, bool discarding, bool loop=false)
Definition hls.hpp:235
Conditional operator / pattern matching.
Definition gamma.hpp:99
std::vector< ExitVar > GetExitVars() const
Gets all exit variables for this gamma.
Definition gamma.cpp:381
std::vector< EntryVar > GetEntryVars() const
Gets all entry variables for this gamma.
Definition gamma.cpp:305
rvsdg::Input * predicate() const noexcept
Definition gamma.hpp:487
Output * origin() const noexcept
Definition node.hpp:58
rvsdg::Region * region() const noexcept
Definition node.hpp:761
size_t noutputs() const noexcept
Definition node.hpp:644
Represent acyclic RVSDG subgraphs.
Definition region.hpp:213
void copy(Region *target, SubstitutionMap &smap) const
Copy a region with substitutions.
Definition region.cpp:317
NodeRange Nodes() noexcept
Definition region.hpp:375
rvsdg::Region * subregion(size_t index) const noexcept
size_t nsubregions() const noexcept
StructuralOutput * output(size_t index) const noexcept
void insert(const Output *original, Output *substitute)
Represents an RVSDG transformation.
static void ConvertGammaNodeWithoutSpeculation(rvsdg::GammaNode &gammaNode)
static void ConvertGammaNodeWithSpeculation(rvsdg::GammaNode &gammaNode)
static void ConvertGammaNodesInStructuralNode(rvsdg::StructuralNode &structuralNode)
static bool CanGammaNodeBeSpeculative(const rvsdg::GammaNode &gammaNode)
static void ConvertGammaNodesInRegion(rvsdg::Region &region)
static void remove(Node *node)
Definition region.hpp:1035
@ State
Designate a state type.
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872
detail::TopDownTraverserGeneric< false > TopDownTraverser
Traverser for visiting every node in a region in a top down order.