Jlm
delta.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <jlm/rvsdg/delta.hpp>
8 #include <jlm/util/strfmt.hpp>
9 
10 namespace jlm::rvsdg
11 {
12 
13 DeltaOperation::~DeltaOperation() noexcept = default;
14 
15 DeltaNode::ContextVar
16 DeltaNode::AddContextVar(rvsdg::Output & origin)
17 {
18  const auto input =
19  addInput(std::make_unique<StructuralInput>(this, &origin, origin.Type()), true);
20  const auto argument = &RegionArgument::Create(*subregion(), input, origin.Type());
21  return ContextVar{ input, argument };
22 }
23 
24 [[nodiscard]] DeltaNode::ContextVar
25 DeltaNode::MapInputContextVar(const rvsdg::Input & input) const noexcept
26 {
27  JLM_ASSERT(rvsdg::TryGetOwnerNode<DeltaNode>(input) == this);
28  return ContextVar{ const_cast<rvsdg::Input *>(&input), subregion()->argument(input.index()) };
29 }
30 
31 [[nodiscard]] DeltaNode::ContextVar
32 DeltaNode::MapBinderContextVar(const rvsdg::Output & output) const noexcept
33 {
34  JLM_ASSERT(rvsdg::TryGetOwnerRegion(output) == subregion());
35  return ContextVar{ input(output.index()), const_cast<rvsdg::Output *>(&output) };
36 }
37 
38 std::vector<DeltaNode::ContextVar>
39 DeltaNode::GetContextVars() const noexcept
40 {
41  std::vector<ContextVar> vars;
42  for (size_t n = 0; n < ninputs(); ++n)
43  {
44  vars.push_back(ContextVar{ input(n), subregion()->argument(n) });
45  }
46  return vars;
47 }
48 
49 std::string
51 {
52  return util::strfmt("DELTA");
53 }
54 
55 std::unique_ptr<rvsdg::Operation>
57 {
58  return std::make_unique<DeltaOperation>(*this);
59 }
60 
61 bool
62 DeltaOperation::operator==(const Operation & other) const noexcept
63 {
64  auto op = dynamic_cast<const DeltaOperation *>(&other);
65  return op && op->constant_ == constant_ && *op->type_ == *type_;
66 }
67 
68 DeltaNode::~DeltaNode() noexcept = default;
69 
70 const DeltaOperation &
71 DeltaNode::GetOperation() const noexcept
72 {
73  return *Operation_;
74 }
75 
76 DeltaNode *
77 DeltaNode::copy(rvsdg::Region * region, const std::vector<jlm::rvsdg::Output *> & operands) const
78 {
79  return static_cast<DeltaNode *>(rvsdg::Node::copy(region, operands));
80 }
81 
82 DeltaNode *
84 {
85  auto delta = Create(
86  region,
87  std::unique_ptr<DeltaOperation>(static_cast<DeltaOperation *>(Operation_->copy().release())));
88 
89  // add context variables
90  rvsdg::SubstitutionMap subregionmap;
91  for (auto & cv : GetContextVars())
92  {
93  auto origin = &smap.lookup(*cv.input->origin());
94  auto newCtxVar = delta->AddContextVar(*origin);
95  subregionmap.insert(cv.inner, newCtxVar.inner);
96  }
97 
98  // copy subregion
99  subregion()->copy(delta->subregion(), subregionmap);
100 
101  // finalize delta
102  auto result = &subregionmap.lookup(*delta->result().origin());
103  auto o = &delta->finalize(result);
104  smap.insert(&output(), o);
105 
106  return delta;
107 }
108 
110 DeltaNode::output() const noexcept
111 {
112  return *StructuralNode::output(0);
113 }
114 
115 rvsdg::Input &
116 DeltaNode::result() const noexcept
117 {
118  return *subregion()->result(0);
119 }
120 
123 {
124  // check if finalized was already called
125  if (noutputs() > 0)
126  {
127  JLM_ASSERT(noutputs() == 1);
128  return output();
129  }
130 
131  auto & expected = Type();
132  auto & received = *origin->Type();
133  if (*expected != received)
134  throw util::Error("Expected " + expected->debug_string() + ", got " + received.debug_string());
135 
136  if (origin->region() != subregion())
137  throw util::Error("Invalid operand region.");
138 
139  rvsdg::RegionResult::Create(*origin->region(), *origin, nullptr, origin->Type());
140 
141  return *addOutput(std::make_unique<StructuralOutput>(this, Operation_->ReferenceType()));
142 }
143 
144 }
Delta node.
Definition: delta.hpp:129
ContextVar MapInputContextVar(const rvsdg::Input &input) const noexcept
Maps input to context variable.
Definition: delta.cpp:25
rvsdg::Input & result() const noexcept
Definition: delta.cpp:116
std::vector< ContextVar > GetContextVars() const noexcept
Gets all bound context variables.
Definition: delta.cpp:39
ContextVar MapBinderContextVar(const rvsdg::Output &output) const noexcept
Maps bound variable reference to context variable.
Definition: delta.cpp:32
~DeltaNode() noexcept override
rvsdg::Region * subregion() const noexcept
Definition: delta.hpp:234
std::unique_ptr< DeltaOperation > Operation_
Definition: delta.hpp:329
static DeltaNode * Create(rvsdg::Region *parent, std::unique_ptr< DeltaOperation > op)
Definition: delta.hpp:313
rvsdg::Output & finalize(rvsdg::Output *result)
Definition: delta.cpp:122
rvsdg::Output & output() const noexcept
Definition: delta.cpp:110
DeltaNode * copy(rvsdg::Region *region, const std::vector< jlm::rvsdg::Output * > &operands) const override
Definition: delta.cpp:77
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition: delta.hpp:243
Delta operation.
Definition: delta.hpp:18
~DeltaOperation() noexcept override
std::string debug_string() const override
Definition: delta.cpp:50
bool operator==(const Operation &other) const noexcept override
Definition: delta.cpp:62
std::unique_ptr< Operation > copy() const override
Definition: delta.cpp:56
rvsdg::Region * region() const noexcept
Definition: node.hpp:761
size_t ninputs() const noexcept
Definition: node.hpp:609
size_t noutputs() const noexcept
Definition: node.hpp:644
virtual Node * copy(rvsdg::Region *region, const std::vector< jlm::rvsdg::Output * > &operands) const
Definition: node.cpp:369
rvsdg::Region * region() const noexcept
Definition: node.cpp:151
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition: node.hpp:366
static RegionArgument & Create(rvsdg::Region &region, StructuralInput *input, std::shared_ptr< const rvsdg::Type > type)
Creates region entry argument.
Definition: region.cpp:62
static RegionResult & Create(rvsdg::Region &region, rvsdg::Output &origin, StructuralOutput *output, std::shared_ptr< const rvsdg::Type > type)
Create region exit result.
Definition: region.cpp:111
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
RegionResult * result(size_t index) const noexcept
Definition: region.hpp:471
void copy(Region *target, SubstitutionMap &smap) const
Copy a region with substitutions.
Definition: region.cpp:314
RegionArgument * argument(size_t index) const noexcept
Definition: region.hpp:437
StructuralOutput * addOutput(std::unique_ptr< StructuralOutput > input)
StructuralOutput * output(size_t index) const noexcept
StructuralInput * input(size_t index) const noexcept
void insert(const Output *original, Output *substitute)
Output & lookup(const Output &original) const
#define JLM_ASSERT(x)
Definition: common.hpp:16
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition: node.hpp:1049
Region * TryGetOwnerRegion(const rvsdg::Input &input) noexcept
Definition: node.hpp:1021
static std::string strfmt(Args... args)
Definition: strfmt.hpp:35
Bound context variable.
Definition: delta.hpp:149