Jlm
control.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2010 2011 2012 2014 Helge Bahmann <hcb@chaoticmind.net>
3  * Copyright 2013 2014 Nico Reißmann <nico.reissmann@gmail.com>
4  * See COPYING for terms of redistribution.
5  */
6 
8 #include <jlm/rvsdg/control.hpp>
9 #include <jlm/rvsdg/Trace.hpp>
10 #include <jlm/util/Hash.hpp>
11 
12 namespace jlm::rvsdg
13 {
14 
15 ControlType::~ControlType() noexcept = default;
16 
17 ControlType::ControlType(size_t nalternatives)
18  : Type(),
19  nalternatives_(nalternatives)
20 {}
21 
22 std::string
24 {
25  return jlm::util::strfmt("ctl(", nalternatives_, ")");
26 }
27 
28 bool
29 ControlType::operator==(const Type & other) const noexcept
30 {
31  auto type = dynamic_cast<const ControlType *>(&other);
32  return type && type->nalternatives_ == nalternatives_;
33 }
34 
35 std::size_t
36 ControlType::ComputeHash() const noexcept
37 {
38  auto typeHash = typeid(ControlType).hash_code();
39  auto numAlternativesHash = std::hash<size_t>()(nalternatives_);
40  return util::CombineHashes(typeHash, numAlternativesHash);
41 }
42 
44 ControlType::Kind() const noexcept
45 {
46  return TypeKind::Value;
47 }
48 
49 std::shared_ptr<const ControlType>
50 ControlType::Create(std::size_t nalternatives)
51 {
52  static const ControlType static_instances[4] = {
53  // ControlType(0) is not valid, but put it in here so
54  // the static array indexing works correctly
55  ControlType(0),
56  ControlType(1),
57  ControlType(2),
58  ControlType(3)
59  };
60 
61  if (nalternatives < 4)
62  {
63  if (nalternatives == 0)
64  {
65  throw util::Error("Alternatives of a control type must be non-zero.");
66  }
67  return std::shared_ptr<const ControlType>(
68  std::shared_ptr<void>(),
69  &static_instances[nalternatives]);
70  }
71  else
72  {
73  return std::make_shared<ControlType>(nalternatives);
74  }
75 }
76 
77 ControlValueRepresentation::ControlValueRepresentation(size_t alternative, size_t nalternatives)
78  : alternative_(alternative),
79  nalternatives_(nalternatives)
80 {
82  throw util::Error("Alternative is bigger than the number of possible alternatives.");
83 }
84 
86 
88  : NullaryOperation(ControlType::Create(value.nalternatives())),
89  value_(std::move(value))
90 {}
91 
92 bool
93 ControlConstantOperation::operator==(const Operation & other) const noexcept
94 {
95  const auto operation = dynamic_cast<const ControlConstantOperation *>(&other);
96  return operation && operation->value_ == value_;
97 }
98 
99 std::string
101 {
102  return jlm::util::strfmt("CTL(", value_.alternative(), ")");
103 }
104 
105 std::unique_ptr<Operation>
107 {
108  return std::make_unique<ControlConstantOperation>(value_);
109 }
110 
111 MatchOperation::~MatchOperation() noexcept = default;
112 
114  size_t nbits,
115  const std::unordered_map<uint64_t, uint64_t> & mapping,
116  uint64_t default_alternative,
117  size_t nalternatives)
118  : UnaryOperation(BitType::Create(nbits), ControlType::Create(nalternatives)),
119  default_alternative_(default_alternative),
120  mapping_(mapping)
121 {}
122 
123 bool
124 MatchOperation::operator==(const Operation & other) const noexcept
125 {
126  auto op = dynamic_cast<const MatchOperation *>(&other);
127  return op && op->default_alternative_ == default_alternative_ && op->mapping_ == mapping_
128  && op->nbits() == nbits() && op->nalternatives() == nalternatives();
129 }
130 
133 {
134  auto & tracedOutput = traceOutputIntraProcedurally(*arg);
135  if (auto node = rvsdg::TryGetOwnerNode<SimpleNode>(tracedOutput))
136  {
137  if (dynamic_cast<const BitConstantOperation *>(&node->GetOperation()))
139  }
140 
141  return unop_reduction_none;
142 }
143 
146 {
147  if (path == unop_reduction_constant)
148  {
149  auto & tracedOutput = traceOutputIntraProcedurally(*arg);
150  auto [_, constantOperation] = TryGetSimpleNodeAndOptionalOp<BitConstantOperation>(tracedOutput);
151  JLM_ASSERT(constantOperation);
153  *arg->region(),
154  nalternatives(),
155  alternative(constantOperation->value().to_uint()));
156  }
157 
158  return nullptr;
159 }
160 
161 std::string
163 {
164  std::string str("[");
165  for (const auto & pair : mapping_)
166  str += jlm::util::strfmt(pair.first, " -> ", pair.second, ", ");
168 
169  return "MATCH" + str;
170 }
171 
172 std::unique_ptr<Operation>
174 {
175  return std::make_unique<MatchOperation>(*this);
176 }
177 
180  size_t nbits,
181  const std::unordered_map<uint64_t, uint64_t> & mapping,
182  uint64_t default_alternative,
183  size_t nalternatives,
184  jlm::rvsdg::Output * operand)
185 {
186  return CreateOpNode<MatchOperation>(
187  { operand },
188  nbits,
189  mapping,
190  default_alternative,
191  nalternatives)
192  .output(0);
193 }
194 
195 }
ControlValueRepresentation value_
Definition: control.hpp:146
~ControlConstantOperation() noexcept override
std::string debug_string() const override
Definition: control.cpp:100
std::unique_ptr< Operation > copy() const override
Definition: control.cpp:106
bool operator==(const Operation &other) const noexcept override
Definition: control.cpp:93
static Output & create(Region &region, ControlValueRepresentation value)
Definition: control.hpp:122
std::string debug_string() const override
Definition: control.cpp:23
std::size_t ComputeHash() const noexcept override
Definition: control.cpp:36
~ControlType() noexcept override
bool operator==(const jlm::rvsdg::Type &other) const noexcept override
Definition: control.cpp:29
size_t nalternatives() const noexcept
Definition: control.hpp:42
TypeKind Kind() const noexcept override
Return the kind of this type.
Definition: control.cpp:44
ControlType(size_t nalternatives)
Definition: control.cpp:17
static std::shared_ptr< const ControlType > Create(std::size_t nalternatives)
Instantiates control type.
Definition: control.cpp:50
ControlValueRepresentation(size_t alternative, size_t nalternatives)
Definition: control.cpp:77
size_t nalternatives() const noexcept
Definition: control.hpp:89
size_t alternative() const noexcept
Definition: control.hpp:83
std::unordered_map< uint64_t, uint64_t > mapping_
Definition: control.hpp:264
unop_reduction_path_t can_reduce_operand(const jlm::rvsdg::Output *arg) const noexcept override
Definition: control.cpp:132
jlm::rvsdg::Output * reduce_operand(unop_reduction_path_t path, jlm::rvsdg::Output *arg) const override
Definition: control.cpp:145
~MatchOperation() noexcept override
uint64_t alternative(uint64_t value) const noexcept
Definition: control.hpp:192
uint64_t nalternatives() const noexcept
Definition: control.hpp:186
bool operator==(const Operation &other) const noexcept override
Definition: control.cpp:124
std::unique_ptr< Operation > copy() const override
Definition: control.cpp:173
std::string debug_string() const override
Definition: control.cpp:162
Nullary operator (operator taking no formal arguments)
Definition: nullary.hpp:22
rvsdg::Region * region() const noexcept
Definition: node.cpp:151
Unary operator.
Definition: unary.hpp:26
#define JLM_ASSERT(x)
Definition: common.hpp:16
size_t unop_reduction_path_t
Definition: unary.hpp:18
static std::string type(const Node *n)
Definition: view.cpp:255
TypeKind
The kinds of types supported in rvsdg.
Definition: type.hpp:22
@ Value
Designate a value type.
static const unop_reduction_path_t unop_reduction_constant
Definition: unary.hpp:45
jlm::rvsdg::Output * match(size_t nbits, const std::unordered_map< uint64_t, uint64_t > &mapping, uint64_t default_alternative, size_t nalternatives, jlm::rvsdg::Output *operand)
Definition: control.cpp:179
static const unop_reduction_path_t unop_reduction_none
Definition: unary.hpp:43
Output & traceOutputIntraProcedurally(Output &output)
Definition: Trace.cpp:223
static std::string strfmt(Args... args)
Definition: strfmt.hpp:35
std::size_t CombineHashes(std::size_t hash, Args... args)
Definition: Hash.hpp:63