Jlm
binary.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2010 2011 2012 2014 Helge Bahmann <hcb@chaoticmind.net>
3  * Copyright 2011 2012 2013 2014 Nico Reißmann <nico.reissmann@gmail.com>
4  * See COPYING for terms of redistribution.
5  */
6 
7 #ifndef JLM_RVSDG_BINARY_HPP
8 #define JLM_RVSDG_BINARY_HPP
9 
10 #include <jlm/rvsdg/graph.hpp>
11 #include <jlm/rvsdg/operation.hpp>
12 #include <jlm/util/common.hpp>
13 
14 #include <optional>
15 
16 namespace jlm::rvsdg
17 {
18 
19 typedef size_t binop_reduction_path_t;
20 
26 {
27 public:
28  enum class flags
29  {
30  none = 0,
31  associative = 1,
32  commutative = 2
33  };
34 
35  ~BinaryOperation() noexcept override;
36 
38  const std::vector<std::shared_ptr<const jlm::rvsdg::Type>> operands,
39  std::shared_ptr<const jlm::rvsdg::Type> result)
40  : SimpleOperation(std::move(operands), { std::move(result) })
41  {}
42 
45  const noexcept = 0;
46 
47  virtual jlm::rvsdg::Output *
50  jlm::rvsdg::Output * op1,
51  jlm::rvsdg::Output * op2) const = 0;
52 
54  flags() const noexcept;
55 
56  inline bool
57  is_associative() const noexcept;
58 
59  inline bool
60  is_commutative() const noexcept;
61 };
62 
78 std::optional<std::vector<rvsdg::Output *>>
80  const BinaryOperation & operation,
81  const std::vector<rvsdg::Output *> & operands);
82 
95 std::optional<std::vector<rvsdg::Output *>>
97  const BinaryOperation & operation,
98  const std::vector<rvsdg::Output *> & operands);
99 
101 {
102 public:
103  enum class reduction
104  {
105  linear,
106  parallel
107  };
108 
109  ~FlattenedBinaryOperation() noexcept override;
110 
111  FlattenedBinaryOperation(std::unique_ptr<BinaryOperation> op, size_t narguments) noexcept
112  : SimpleOperation({ narguments, op->argument(0) }, { op->result(0) }),
113  op_(std::move(op))
114  {
115  JLM_ASSERT(op_->is_associative());
116  }
117 
119  : SimpleOperation({ narguments, op.argument(0) }, { op.result(0) }),
120  op_(std::unique_ptr<BinaryOperation>(static_cast<BinaryOperation *>(op.copy().release())))
121  {
122  JLM_ASSERT(op_->is_associative());
123  }
124 
125  bool
126  operator==(const Operation & other) const noexcept override;
127 
128  [[nodiscard]] std::string
129  debug_string() const override;
130 
131  [[nodiscard]] std::unique_ptr<Operation>
132  copy() const override;
133 
134  const BinaryOperation &
135  bin_operation() const noexcept
136  {
137  return *op_;
138  }
139 
141  reduce(
142  const FlattenedBinaryOperation::reduction & reduction,
143  const std::vector<jlm::rvsdg::Output *> & operands) const;
144 
145  static void
146  reduce(rvsdg::Region * region, const FlattenedBinaryOperation::reduction & reduction);
147 
148  static inline void
150  {
151  reduce(&graph->GetRootRegion(), reduction);
152  }
153 
154 private:
155  std::unique_ptr<BinaryOperation> op_;
156 };
157 
170 std::optional<std::vector<rvsdg::Output *>>
172  const FlattenedBinaryOperation & operation,
173  const std::vector<rvsdg::Output *> & operands);
174 
175 /* binary flags operators */
176 
177 static constexpr enum BinaryOperation::flags
179 {
180  return static_cast<enum BinaryOperation::flags>(static_cast<int>(a) | static_cast<int>(b));
181 }
182 
183 static constexpr enum BinaryOperation::flags
185 {
186  return static_cast<enum BinaryOperation::flags>(static_cast<int>(a) & static_cast<int>(b));
187 }
188 
189 /* binary methods */
190 
191 inline bool
193 {
194  return static_cast<int>(flags() & BinaryOperation::flags::associative);
195 }
196 
197 inline bool
199 {
200  return static_cast<int>(flags() & BinaryOperation::flags::commutative);
201 }
202 
204 /* both operands are constants */
206 /* can merge both operands into single (using some "simpler" operator) */
208 /* part of left operand can be folded into right */
210 /* part of right operand can be folded into left */
212 /* left operand is neutral element */
214 /* right operand is neutral element */
216 /* both operands have common form which can be factored over op */
218 
219 }
220 
221 #endif
~BinaryOperation() noexcept override
bool is_commutative() const noexcept
Definition: binary.hpp:198
bool is_associative() const noexcept
Definition: binary.hpp:192
virtual jlm::rvsdg::Output * reduce_operand_pair(binop_reduction_path_t path, jlm::rvsdg::Output *op1, jlm::rvsdg::Output *op2) const =0
BinaryOperation(const std::vector< std::shared_ptr< const jlm::rvsdg::Type >> operands, std::shared_ptr< const jlm::rvsdg::Type > result)
Definition: binary.hpp:37
virtual binop_reduction_path_t can_reduce_operand_pair(const jlm::rvsdg::Output *op1, const jlm::rvsdg::Output *op2) const noexcept=0
static void reduce(Graph *graph, const FlattenedBinaryOperation::reduction &reduction)
Definition: binary.hpp:149
FlattenedBinaryOperation(const BinaryOperation &op, size_t narguments)
Definition: binary.hpp:118
~FlattenedBinaryOperation() noexcept override
const BinaryOperation & bin_operation() const noexcept
Definition: binary.hpp:135
std::unique_ptr< BinaryOperation > op_
Definition: binary.hpp:155
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
virtual bool operator==(const Operation &other) const noexcept=0
virtual std::string debug_string() const =0
virtual std::unique_ptr< Operation > copy() const =0
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
const std::shared_ptr< const rvsdg::Type > & argument(size_t index) const noexcept
Definition: operation.cpp:23
const std::shared_ptr< const rvsdg::Type > & result(size_t index) const noexcept
Definition: operation.cpp:36
size_t narguments() const noexcept
Definition: operation.cpp:17
#define JLM_ASSERT(x)
Definition: common.hpp:16
static bool reduce(const ControlFlowGraph &cfg, const std::function< bool(llvm::ControlFlowGraphNode *, std::unordered_set< llvm::ControlFlowGraphNode * > &)> &f)
static const binop_reduction_path_t binop_reduction_lneutral
Definition: binary.hpp:213
std::optional< std::vector< rvsdg::Output * > > NormalizeBinaryOperation(const BinaryOperation &operation, const std::vector< rvsdg::Output * > &operands)
Applies the reductions implemented in the binary operations reduction functions.
Definition: binary.cpp:112
static constexpr enum BinaryOperation::flags operator|(enum BinaryOperation::flags a, enum BinaryOperation::flags b)
Definition: binary.hpp:178
static const binop_reduction_path_t binop_reduction_constants
Definition: binary.hpp:205
static constexpr enum BinaryOperation::flags operator&(enum BinaryOperation::flags a, enum BinaryOperation::flags b)
Definition: binary.hpp:184
size_t binop_reduction_path_t
Definition: binary.hpp:19
static const binop_reduction_path_t binop_reduction_rfold
Definition: binary.hpp:211
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition: node.hpp:1049
static const binop_reduction_path_t binop_reduction_factor
Definition: binary.hpp:217
static const binop_reduction_path_t binop_reduction_rneutral
Definition: binary.hpp:215
std::optional< std::vector< rvsdg::Output * > > NormalizeFlattenedBinaryOperation(const FlattenedBinaryOperation &operation, const std::vector< rvsdg::Output * > &operands)
Applies the reductions of the binary operation represented by the flattened binary operation.
Definition: binary.cpp:253
std::optional< std::vector< rvsdg::Output * > > FlattenAssociativeBinaryOperation(const BinaryOperation &operation, const std::vector< rvsdg::Output * > &operands)
Flattens a cascade of the same binary operations into a single flattened binary operation.
Definition: binary.cpp:64
static const binop_reduction_path_t binop_reduction_none
Definition: binary.hpp:203
static const binop_reduction_path_t binop_reduction_merge
Definition: binary.hpp:207
static const binop_reduction_path_t binop_reduction_lfold
Definition: binary.hpp:209