Jlm
remove-redundant-buf.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 
10 namespace jlm::hls
11 {
12 
14 
15 void
16 RedundantBufferElimination::Run(rvsdg::RvsdgModule & module, util::StatisticsCollector &)
17 {
18  HandleRegion(module.Rvsdg().GetRootRegion());
19 }
20 
21 void
23  rvsdg::RvsdgModule & module,
24  util::StatisticsCollector & statisticsCollector)
25 {
26  RedundantBufferElimination redundantBufferElimination;
27  redundantBufferElimination.Run(module, statisticsCollector);
28 }
29 
30 void
32 {
33  for (auto & node : region.Nodes())
34  {
35  // Handle innermost regions first
36  if (auto structuralNode = dynamic_cast<rvsdg::StructuralNode *>(&node))
37  {
38  for (auto & subregion : structuralNode->Subregions())
39  {
40  HandleRegion(subregion);
41  }
42  continue;
43  }
44 
45  auto bufferOperation = dynamic_cast<const BufferOperation *>(&node.GetOperation());
46  if (!bufferOperation)
47  continue;
48 
49  if (!rvsdg::is<llvm::MemoryStateType>(node.input(0)->Type()))
50  continue;
51 
52  if (bufferOperation->IsPassThrough())
53  continue;
54 
55  if (!CanTraceToLoadOrStore(*node.input(0)->origin()))
56  continue;
57 
58  // Replace the BufferOperation node with a passthrough BufferOperation node
59  auto result =
60  BufferOperation::create(*node.input(0)->origin(), bufferOperation->Capacity(), true)[0];
61  node.output(0)->divert_users(result);
62  }
63 
64  // Prune dead nodes
65  region.prune(false);
66 }
67 
68 bool
70 {
71  JLM_ASSERT(rvsdg::is<llvm::MemoryStateType>(output.Type()));
72 
73  if (rvsdg::IsOwnerNodeOperation<LoadOperation>(output))
74  return true;
75 
76  if (rvsdg::IsOwnerNodeOperation<LocalLoadOperation>(output))
77  return true;
78 
79  if (rvsdg::IsOwnerNodeOperation<StoreOperation>(output))
80  return true;
81 
82  if (rvsdg::IsOwnerNodeOperation<LocalStoreOperation>(output))
83  return true;
84 
85  auto [forkNode, forkOperation] = rvsdg::TryGetSimpleNodeAndOptionalOp<ForkOperation>(output);
86  if (forkNode && forkOperation)
87  return CanTraceToLoadOrStore(*forkNode->input(0)->origin());
88 
89  auto [branchNode, branchOperation] =
90  rvsdg::TryGetSimpleNodeAndOptionalOp<BranchOperation>(output);
91  if (branchNode && branchOperation)
92  return CanTraceToLoadOrStore(*branchNode->input(1)->origin());
93 
94  return false;
95 }
96 
97 } // namespace jlm::hls
static std::vector< jlm::rvsdg::Output * > create(jlm::rvsdg::Output &value, size_t capacity, bool pass_through=false)
Definition: hls.hpp:438
static void HandleRegion(rvsdg::Region &region)
~RedundantBufferElimination() noexcept override
static bool CanTraceToLoadOrStore(const rvsdg::Output &output)
static void CreateAndRun(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector)
void Run(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition: node.hpp:366
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
void prune(bool recursive)
Definition: region.cpp:323
NodeRange Nodes() noexcept
Definition: region.hpp:328
#define JLM_ASSERT(x)
Definition: common.hpp:16