6#include <gtest/gtest.h>
17 const std::shared_ptr<const jlm::rvsdg::Type> operandType,
18 const std::shared_ptr<const jlm::rvsdg::Type> resultType,
26 const noexcept override
67 [[nodiscard]] std::string
70 return "BinaryOperation";
73 [[nodiscard]] std::unique_ptr<Operation>
83TEST(BinaryOperationTests, ReduceFlattenedBinaryReductionParallel)
88 const auto valueType = TestType::createValueType();
100 auto & node = CreateOpNode<FlattenedBinaryOperation>({ i0, i1, i2, i3 }, binaryOperation, 4);
102 auto & ex = GraphExport::Create(*node.output(0),
"");
107 FlattenedBinaryOperation::reduce(&graph, FlattenedBinaryOperation::reduction::parallel);
114 auto node0 = TryGetOwnerNode<SimpleNode>(*ex.origin());
115 EXPECT_TRUE(is<TestBinaryOperation>(node0->GetOperation()));
117 auto node1 = TryGetOwnerNode<SimpleNode>(*node0->input(0)->origin());
118 EXPECT_TRUE(is<TestBinaryOperation>(node1->GetOperation()));
120 auto node2 = TryGetOwnerNode<SimpleNode>(*node0->input(1)->origin());
121 EXPECT_TRUE(is<TestBinaryOperation>(node2->GetOperation()));
124TEST(BinaryOperationTests, ReduceFlattenedBinaryReductionLinear)
129 const auto valueType = TestType::createValueType();
141 auto & node = CreateOpNode<FlattenedBinaryOperation>({ i0, i1, i2, i3 }, binaryOperation, 4);
143 auto & ex = GraphExport::Create(*node.output(0),
"");
148 FlattenedBinaryOperation::reduce(&graph, FlattenedBinaryOperation::reduction::linear);
156 auto node0 = TryGetOwnerNode<SimpleNode>(*ex.origin());
157 EXPECT_TRUE(is<TestBinaryOperation>(node0->GetOperation()));
159 auto node1 = TryGetOwnerNode<SimpleNode>(*node0->input(0)->origin());
160 EXPECT_TRUE(is<TestBinaryOperation>(node1->GetOperation()));
162 auto node2 = TryGetOwnerNode<SimpleNode>(*node1->input(0)->origin());
163 EXPECT_TRUE(is<TestBinaryOperation>(node2->GetOperation()));
166TEST(BinaryOperationTests, FlattenAssociativeBinaryOperation_NotAssociativeBinary)
171 auto valueType = TestType::createValueType();
178 auto o1 = &CreateOpNode<TestBinaryOperation>(
183 auto o2 = &CreateOpNode<TestBinaryOperation>(
184 { o1->output(0), i2 },
189 auto & ex = GraphExport::Create(*o2->output(0),
"o2");
194 auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
195 auto success = ReduceNode<TestBinaryOperation>(FlattenAssociativeBinaryOperation, *node);
200 EXPECT_FALSE(success);
201 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex.origin()), node);
204TEST(BinaryOperationTests, FlattenAssociativeBinaryOperation_NoNewOperands)
209 auto valueType = TestType::createValueType();
215 auto u1 = &CreateOpNode<TestUnaryOperation>({ i0 }, valueType, valueType);
216 auto u2 = &CreateOpNode<TestUnaryOperation>({ i1 }, valueType, valueType);
217 auto b2 = &CreateOpNode<TestBinaryOperation>(
218 { u1->output(0), u2->output(0) },
223 auto & ex = GraphExport::Create(*b2->output(0),
"o2");
228 auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
229 auto success = ReduceNode<TestBinaryOperation>(FlattenAssociativeBinaryOperation, *node);
234 EXPECT_FALSE(success);
235 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex.origin()), node);
238TEST(BinaryOperationTests, FlattenAssociativeBinaryOperation_Success)
243 auto valueType = TestType::createValueType();
250 auto o1 = &CreateOpNode<TestBinaryOperation>(
255 auto o2 = &CreateOpNode<TestBinaryOperation>(
256 { o1->output(0), i2 },
261 auto & ex = GraphExport::Create(*o2->output(0),
"o2");
266 auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
267 auto success = ReduceNode<TestBinaryOperation>(FlattenAssociativeBinaryOperation, *node);
272 EXPECT_TRUE(success);
273 auto flattenedBinaryNode = TryGetOwnerNode<SimpleNode>(*ex.origin());
274 EXPECT_TRUE(is<FlattenedBinaryOperation>(flattenedBinaryNode->GetOperation()));
275 EXPECT_EQ(flattenedBinaryNode->ninputs(), 3u);
278TEST(BinaryOperationTests, NormalizeBinaryOperation_NoNewOperands)
283 auto valueType = TestType::createValueType();
289 auto o1 = &CreateOpNode<TestBinaryOperation>(
295 auto & ex = GraphExport::Create(*o1->output(0),
"o2");
300 auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
301 auto success = ReduceNode<TestBinaryOperation>(NormalizeBinaryOperation, *node);
306 EXPECT_FALSE(success);
309TEST(BinaryOperationTests, NormalizeBinaryOperation_SingleOperand)
314 auto valueType = TestType::createValueType();
320 auto u1 = &CreateOpNode<TestUnaryOperation>({ s0 }, valueType, valueType);
321 auto u2 = &CreateOpNode<TestUnaryOperation>({ s1 }, valueType, valueType);
323 auto o1 = &CreateOpNode<::BinaryOperation>(
324 { u1->output(0), u2->output(0) },
329 auto & ex = GraphExport::Create(*o1->output(0),
"ex");
334 auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
335 auto success = ReduceNode<::BinaryOperation>(NormalizeBinaryOperation, *node);
340 EXPECT_TRUE(success);
341 EXPECT_EQ(ex.origin(), u2->output(0));
TEST(BinaryOperationTests, ReduceFlattenedBinaryReductionParallel)
std::string debug_string() const override
enum jlm::rvsdg::BinaryOperation::flags flags() const noexcept override
enum jlm::rvsdg::BinaryOperation::flags Flags_
std::unique_ptr< Operation > copy() const override
BinaryOperation(const std::shared_ptr< const jlm::rvsdg::Type > operandType, const std::shared_ptr< const jlm::rvsdg::Type > resultType, const enum jlm::rvsdg::BinaryOperation::flags &flags)
jlm::rvsdg::Output * reduce_operand_pair(jlm::rvsdg::binop_reduction_path_t path, jlm::rvsdg::Output *, jlm::rvsdg::Output *op2) const override
bool operator==(const Operation &) const noexcept override
jlm::rvsdg::binop_reduction_path_t can_reduce_operand_pair(const jlm::rvsdg::Output *operand1, const jlm::rvsdg::Output *operand2) const noexcept override
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Region & GetRootRegion() const noexcept
size_t numNodes() const noexcept
const std::shared_ptr< const rvsdg::Type > & argument(size_t index) const noexcept
const std::shared_ptr< const rvsdg::Type > & result(size_t index) const noexcept
#define JLM_UNREACHABLE(msg)
size_t binop_reduction_path_t
std::string view(const rvsdg::Region *region)
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.