Jlm
add-forks.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 
9 namespace jlm::hls
10 {
11 
12 ForkInsertion::~ForkInsertion() noexcept = default;
13 
14 void
15 ForkInsertion::Run(rvsdg::RvsdgModule & module, util::StatisticsCollector &)
16 {
17  AddForksToRegion(module.Rvsdg().GetRootRegion());
18 }
19 
20 void
22  rvsdg::RvsdgModule & module,
23  util::StatisticsCollector & statisticsCollector)
24 {
25  ForkInsertion forkInsertion;
26  forkInsertion.Run(module, statisticsCollector);
27 }
28 
29 void
31 {
32  // Add forks to region arguments
33  for (const auto argument : region.Arguments())
34  {
35  if (argument->nusers() > 1)
36  AddForkToOutput(*argument);
37  }
38 
39  for (auto & node : region.Nodes())
40  {
41  // Add forks to subregions of structural nodes
42  if (const auto structuralNode = dynamic_cast<rvsdg::StructuralNode *>(&node))
43  {
44  for (auto & subregion : structuralNode->Subregions())
45  {
46  AddForksToRegion(subregion);
47  }
48  }
49 
50  // Add forks to outputs of nodes
51  for (size_t n = 0; n < node.noutputs(); n++)
52  {
53  const auto output = node.output(n);
54  if (output->nusers() > 1)
55  {
56  AddForkToOutput(*output);
57  }
58  }
59  }
60 }
61 
62 void
64 {
65  JLM_ASSERT(output.nusers() > 1);
66 
67  const auto isConstant = IsConstantFork(output);
68  const auto & forkNode = ForkOperation::CreateNode(output.nusers(), output, isConstant);
69 
70  size_t currentForkOutput = 0;
71  while (output.nusers() != 1) // The fork node should be the only user left in the end
72  {
73  auto userIt = output.Users().begin();
74  if (&*userIt == forkNode.input(0))
75  {
76  // Ignore the added fork node
77  userIt = std::next(userIt);
78  }
79 
80  JLM_ASSERT(currentForkOutput < forkNode.noutputs());
81  userIt->divert_to(forkNode.output(currentForkOutput));
82  currentForkOutput++;
83  }
84 
85  JLM_ASSERT(currentForkOutput == forkNode.noutputs());
86 }
87 
88 bool
90 {
91  const auto node = rvsdg::TryGetOwnerNode<rvsdg::Node>(output);
92  return node != nullptr ? node->ninputs() == 0 : false;
93 }
94 
95 }
void Run(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
Definition: add-forks.cpp:15
static bool IsConstantFork(const rvsdg::Output &output)
Definition: add-forks.cpp:89
static void CreateAndRun(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector)
Definition: add-forks.cpp:21
~ForkInsertion() noexcept override
static void AddForksToRegion(rvsdg::Region &region)
Definition: add-forks.cpp:30
static void AddForkToOutput(rvsdg::Output &output)
Definition: add-forks.cpp:63
static rvsdg::Node & CreateNode(const size_t numResults, rvsdg::Output &operand, const bool isConstant=false)
Definition: hls.hpp:177
UsersRange Users()
Definition: node.hpp:354
size_t nusers() const noexcept
Definition: node.hpp:280
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
RegionArgumentRange Arguments() noexcept
Definition: region.hpp:272
NodeRange Nodes() noexcept
Definition: region.hpp:328
#define JLM_ASSERT(x)
Definition: common.hpp:16