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  size_t n = 0;
165  std::ostringstream oss;
166  constexpr size_t maxAlternatives = 3;
167  for (auto [input, subregionId] : mapping_)
168  {
169  if (n < maxAlternatives)
170  {
171  oss << input << " -> " << subregionId << ", ";
172  n++;
173  }
174  else
175  {
176  oss << "..., ";
177  break;
178  }
179  }
180  oss << default_alternative_;
181 
182  return "MATCH[" + oss.str() + "]";
183 }
184 
185 std::unique_ptr<Operation>
187 {
188  return std::make_unique<MatchOperation>(*this);
189 }
190 
191 }
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:186
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
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
static const unop_reduction_path_t unop_reduction_none
Definition: unary.hpp:43
Output & traceOutputIntraProcedurally(Output &output)
Definition: Trace.cpp:283
static std::string strfmt(Args... args)
Definition: strfmt.hpp:35
std::size_t CombineHashes(std::size_t hash, Args... args)
Definition: Hash.hpp:63