Jlm
ThetaConversion.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>
9 #include <jlm/rvsdg/theta.hpp>
10 #include <jlm/rvsdg/traverser.hpp>
11 
12 namespace jlm::hls
13 {
14 
15 static void
17 {
19 
20  auto loop = LoopNode::create(theta.region());
21  std::vector<jlm::rvsdg::Input *> branches;
22 
23  // Add loop variables, insert loop constant buffers for invariant variables, and populate the
24  // smap.
25  for (size_t i = 0; i < theta.ninputs(); i++)
26  {
27  auto loopvar = theta.MapInputLoopVar(*theta.input(i));
28  // Check if the input is a loop invariant such that a loop constant buffer should be created.
29  // Memory state inputs are not loop variables containting a value, so we ignor these.
30  if (ThetaLoopVarIsInvariant(loopvar)
31  && !jlm::rvsdg::is<jlm::llvm::MemoryStateType>(loopvar.input->Type()))
32  {
33  smap.insert(loopvar.pre, loop->addLoopConstant(loopvar.input->origin()));
34  branches.push_back(nullptr);
35  // The HLS loop has no output for this input. The users of the theta output is
36  // therefore redirected to the input origin, as the value is loop invariant.
37  loopvar.output->divert_users(loopvar.input->origin());
38  }
39  else
40  {
41  rvsdg::Output * buffer = nullptr;
42  loop->AddLoopVar(loopvar.input->origin(), &buffer);
43  smap.insert(loopvar.pre, buffer);
44  // buffer out is only used by branch
45  branches.push_back(&*buffer->Users().begin());
46  // divert theta outputs
47  loopvar.output->divert_users(loop->output(loop->noutputs() - 1));
48  }
49  }
50 
51  // copy contents of theta
52  theta.subregion()->copy(loop->subregion(), smap);
53 
54  // connect predicate/branches in loop to results
55  loop->set_predicate(&smap.lookup(*theta.predicate()->origin()));
56  for (size_t i = 0; i < theta.ninputs(); i++)
57  {
58  if (branches[i])
59  {
60  branches[i]->divert_to(&smap.lookup(*theta.MapInputLoopVar(*theta.input(i)).post->origin()));
61  }
62  }
63 
64  remove(&theta);
65 }
66 
67 static void
69 
70 static void
72 {
73  for (size_t n = 0; n < structuralNode.nsubregions(); n++)
74  {
75  ConvertThetaNodesInRegion(*structuralNode.subregion(n));
76  }
77 
78  if (auto thetaNode = dynamic_cast<rvsdg::ThetaNode *>(&structuralNode))
79  {
80  ConvertThetaNode(*thetaNode);
81  }
82 }
83 
84 static void
86 {
87  for (auto & node : rvsdg::TopDownTraverser(&region))
88  {
89  if (auto structuralNode = dynamic_cast<rvsdg::StructuralNode *>(node))
90  {
91  ConvertThetaNodesInStructuralNode(*structuralNode);
92  }
93  }
94 }
95 
97 
100 {}
101 
102 void
104 {
106 }
107 
108 }
static LoopNode * create(rvsdg::Region *parent, bool init=true)
Definition: hls.cpp:294
void Run(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
~ThetaNodeConversion() noexcept override
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
Output * origin() const noexcept
Definition: node.hpp:58
rvsdg::Region * region() const noexcept
Definition: node.hpp:761
size_t ninputs() const noexcept
Definition: node.hpp:609
UsersRange Users()
Definition: node.hpp:354
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
void copy(Region *target, SubstitutionMap &smap) const
Copy a region with substitutions.
Definition: region.cpp:314
Graph & Rvsdg() noexcept
Definition: RvsdgModule.hpp:57
size_t nsubregions() const noexcept
StructuralInput * input(size_t index) const noexcept
rvsdg::Region * subregion(size_t index) const noexcept
void insert(const Output *original, Output *substitute)
Output & lookup(const Output &original) const
RegionResult * predicate() const noexcept
Definition: theta.hpp:85
rvsdg::Region * subregion() const noexcept
Definition: theta.hpp:79
LoopVar MapInputLoopVar(const rvsdg::Input &input) const
Maps variable at entry to full varibale description.
Definition: theta.cpp:130
Represents an RVSDG transformation.
static void ConvertThetaNodesInRegion(rvsdg::Region &region)
static void ConvertThetaNode(rvsdg::ThetaNode &theta)
static void ConvertThetaNodesInStructuralNode(rvsdg::StructuralNode &structuralNode)
static bool ThetaLoopVarIsInvariant(const ThetaNode::LoopVar &loopVar) noexcept
Definition: theta.hpp:227
static void remove(Node *node)
Definition: region.hpp:932
rvsdg::Input * post
Variable after iteration (output result from subregion).
Definition: theta.hpp:62