Jlm
check-rhls.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 
9 #include <jlm/hls/ir/hls.hpp>
11 #include <jlm/rvsdg/traverser.hpp>
12 
13 namespace jlm::hls
14 {
15 
16 static void
18 {
19  auto [addrQueueNode, addrQueueOperation] =
20  rvsdg::TryGetSimpleNodeAndOptionalOp<AddressQueueOperation>(*node->output(0));
21  JLM_ASSERT(rvsdg::is<AddressQueueOperation>(node));
22  // Ensure that there is no buffer between state_gate and addr_queue enq.
23  // This is SG1 in the paper. Otherwise, there might be a race condition in the disambiguation
24  JLM_ASSERT(
25  rvsdg::IsOwnerNodeOperation<StateGateOperation>(*FindSourceNode(node->input(1)->origin())));
26  // make sure there is enough buffer space on the output, so there can be no race condition with
27  // SG3
28  auto [bufferNode, bufferOperation] =
29  rvsdg::TryGetSimpleNodeAndOptionalOp<BufferOperation>(*node->output(0)->Users().begin());
30  JLM_ASSERT(bufferOperation && bufferOperation->Capacity() >= addrQueueOperation->capacity);
31 }
32 
33 static void
35 {
36  for (auto & node : rvsdg::TopDownTraverser(sr))
37  {
38  if (rvsdg::is<rvsdg::StructuralOperation>(node))
39  {
40  if (auto ln = dynamic_cast<LoopNode *>(node))
41  {
42  check_rhls(ln->subregion());
43  }
44  else
45  {
46  throw util::Error("There should be only simple nodes and loop nodes");
47  }
48  }
49  for (size_t i = 0; i < node->noutputs(); i++)
50  {
51  if (node->output(i)->nusers() == 0)
52  {
53  throw util::Error("Output has no users");
54  }
55  else if (node->output(i)->nusers() > 1)
56  {
57  throw util::Error("Output has more than one user");
58  }
59  }
60  if (rvsdg::is<AddressQueueOperation>(node))
61  {
62  CheckAddrQueue(node);
63  }
64  }
65 }
66 
67 static void
69 {
70  auto & graph = rm.Rvsdg();
71  auto root = &graph.GetRootRegion();
72  if (root->numNodes() != 1)
73  {
74  throw util::Error("Root should have only one node now");
75  }
76  auto ln = dynamic_cast<const rvsdg::LambdaNode *>(root->Nodes().begin().ptr());
77  if (!ln)
78  {
79  throw util::Error("Node needs to be a lambda");
80  }
81  check_rhls(ln->subregion());
82 }
83 
84 RhlsVerification::~RhlsVerification() noexcept = default;
85 
88 {}
89 
90 void
92 {
93  check_rhls(rvsdgModule);
94 }
95 
96 }
~RhlsVerification() noexcept override
void Run(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
Definition: check-rhls.cpp:91
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
Output * origin() const noexcept
Definition: node.hpp:58
Lambda node.
Definition: lambda.hpp:83
NodeInput * input(size_t index) const noexcept
Definition: node.hpp:615
NodeOutput * output(size_t index) const noexcept
Definition: node.hpp:650
UsersRange Users()
Definition: node.hpp:354
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
Graph & Rvsdg() noexcept
Definition: RvsdgModule.hpp:57
Represents an RVSDG transformation.
#define JLM_ASSERT(x)
Definition: common.hpp:16
rvsdg::Output * FindSourceNode(rvsdg::Output *out)
static void check_rhls(rvsdg::Region *sr)
Definition: check-rhls.cpp:34
static void CheckAddrQueue(rvsdg::Node *node)
Definition: check-rhls.cpp:17