lriggs commented on code in PR #50372:
URL: https://github.com/apache/arrow/pull/50372#discussion_r3546772791
##########
cpp/src/gandiva/tests/projector_test.cc:
##########
@@ -388,6 +423,195 @@ TEST_F(TestProjector, TestAllIntTypes) {
TestArithmeticOpsForType<arrow::Int64Type, int64_t>(pool_);
}
+TEST_F(TestProjector, TestCommonSubexpressionEliminationIR) {
+ auto field0 = arrow::field("cse_f0", arrow::int32());
+ auto field1 = arrow::field("cse_f1", arrow::int32());
+ auto schema = arrow::schema({field0, field1});
+
+ auto left_sum = TreeExprBuilder::MakeFunction(
+ "add", {TreeExprBuilder::MakeField(field0),
TreeExprBuilder::MakeField(field1)},
+ arrow::int32());
+ auto right_sum = TreeExprBuilder::MakeFunction(
+ "add", {TreeExprBuilder::MakeField(field0),
TreeExprBuilder::MakeField(field1)},
+ arrow::int32());
+ auto square =
+ TreeExprBuilder::MakeFunction("multiply", {left_sum, right_sum},
arrow::int32());
+ auto expr =
+ TreeExprBuilder::MakeExpression(square, arrow::field("cse_out",
arrow::int32()));
+
+ auto configuration = std::make_shared<Configuration>(
+ true, gandiva::default_function_registry(), /*dump_ir=*/true);
+ std::shared_ptr<Projector> projector;
+ ASSERT_OK(Projector::Make(schema, {expr}, configuration, &projector));
+
+ const auto unoptimized_expr_ir =
+ ExtractFunctionIR(projector->DumpUnoptimizedIR(), "expr_0_0");
+ const auto optimized_expr_ir = ExtractFunctionIR(projector->DumpIR(),
"expr_0_0");
+ ASSERT_FALSE(unoptimized_expr_ir.empty());
+ ASSERT_FALSE(optimized_expr_ir.empty());
+
+ EXPECT_EQ(2, CountOccurrences(unoptimized_expr_ir, "call i32
@add_int32_int32"));
+ EXPECT_EQ(1, CountOccurrences(unoptimized_expr_ir, "call i32
@multiply_int32_int32"));
+ EXPECT_EQ(0, CountOccurrences(optimized_expr_ir, "call i32
@add_int32_int32"));
+ EXPECT_EQ(0, CountOccurrences(optimized_expr_ir, "call i32
@multiply_int32_int32"));
+ EXPECT_EQ(1, CountInt32AddInstructions(optimized_expr_ir));
+}
+
+TEST_F(TestProjector, TestNestedCommonSubexpressionEliminationIR) {
+ auto field0 = arrow::field("nested_cse_f0", arrow::int32());
+ auto field1 = arrow::field("nested_cse_f1", arrow::int32());
+ auto schema = arrow::schema({field0, field1});
+
+ auto make_sum = [&]() {
+ return TreeExprBuilder::MakeFunction(
+ "add", {TreeExprBuilder::MakeField(field0),
TreeExprBuilder::MakeField(field1)},
+ arrow::int32());
+ };
+ auto make_square = [&]() {
+ return TreeExprBuilder::MakeFunction("multiply", {make_sum(), make_sum()},
+ arrow::int32());
+ };
+ auto nested = TreeExprBuilder::MakeFunction("add", {make_square(),
make_square()},
+ arrow::int32());
+ auto expr = TreeExprBuilder::MakeExpression(
+ nested, arrow::field("nested_cse_out", arrow::int32()));
+
+ auto configuration = std::make_shared<Configuration>(
+ true, gandiva::default_function_registry(), /*dump_ir=*/true);
+ std::shared_ptr<Projector> projector;
+ ASSERT_OK(Projector::Make(schema, {expr}, configuration, &projector));
+
+ const auto unoptimized_expr_ir =
+ ExtractFunctionIR(projector->DumpUnoptimizedIR(), "expr_0_0");
+ const auto optimized_expr_ir = ExtractFunctionIR(projector->DumpIR(),
"expr_0_0");
+ ASSERT_FALSE(unoptimized_expr_ir.empty());
+ ASSERT_FALSE(optimized_expr_ir.empty());
+
+ EXPECT_EQ(5, CountOccurrences(unoptimized_expr_ir, "call i32
@add_int32_int32"));
+ EXPECT_EQ(2, CountOccurrences(unoptimized_expr_ir, "call i32
@multiply_int32_int32"));
+ EXPECT_EQ(0, CountOccurrences(optimized_expr_ir, "call i32
@add_int32_int32"));
+ EXPECT_EQ(0, CountOccurrences(optimized_expr_ir, "call i32
@multiply_int32_int32"));
+}
+
+TEST_F(TestProjector, TestGeneratedIfCommonSubexpressionEliminationIR) {
+ auto condition_field = arrow::field("generated_if_cond", arrow::boolean());
+ auto value_field = arrow::field("generated_if_value", arrow::int32());
+ auto schema = arrow::schema({condition_field, value_field});
+
+ auto condition = TreeExprBuilder::MakeField(condition_field);
+ auto then_node = TreeExprBuilder::MakeField(value_field);
+ auto else_node = TreeExprBuilder::MakeField(value_field);
+ auto if_node = TreeExprBuilder::MakeIf(condition, then_node, else_node,
arrow::int32());
+ auto expr = TreeExprBuilder::MakeExpression(
+ if_node, arrow::field("generated_if_out", arrow::int32()));
+
+ auto configuration = std::make_shared<Configuration>(
+ true, gandiva::default_function_registry(), /*dump_ir=*/true);
+ std::shared_ptr<Projector> projector;
+ ASSERT_OK(Projector::Make(schema, {expr}, configuration, &projector));
+
+ const auto unoptimized_expr_ir =
+ ExtractFunctionIR(projector->DumpUnoptimizedIR(), "expr_0_0");
+ const auto optimized_expr_ir = ExtractFunctionIR(projector->DumpIR(),
"expr_0_0");
+ ASSERT_FALSE(unoptimized_expr_ir.empty());
+ ASSERT_FALSE(optimized_expr_ir.empty());
+
+ EXPECT_NE(std::string::npos, unoptimized_expr_ir.find("generated_if_value"));
+ EXPECT_EQ(std::string::npos, unoptimized_expr_ir.find("generated_if_cond"));
+ EXPECT_EQ(std::string::npos, unoptimized_expr_ir.find("then:"));
+ EXPECT_EQ(std::string::npos, unoptimized_expr_ir.find("else:"));
+ EXPECT_EQ(std::string::npos, unoptimized_expr_ir.find("validAndMatch"));
+ EXPECT_EQ(std::string::npos, unoptimized_expr_ir.find("res_value = phi"));
+ EXPECT_NE(std::string::npos, optimized_expr_ir.find("generated_if_value"));
+ EXPECT_EQ(std::string::npos, optimized_expr_ir.find("generated_if_cond"));
+ EXPECT_EQ(std::string::npos, optimized_expr_ir.find("validAndMatch"));
+ EXPECT_EQ(std::string::npos, optimized_expr_ir.find("res_value = phi"));
+}
+
+TEST_F(TestProjector, TestGeneratedBooleanCommonSubexpressionEliminationIR) {
+ auto field0 = arrow::field("generated_bool_f0", arrow::boolean());
+ auto field1 = arrow::field("generated_bool_f1", arrow::boolean());
+ auto schema = arrow::schema({field0, field1});
+
+ auto make_and = [&]() {
+ return TreeExprBuilder::MakeAnd(
+ {TreeExprBuilder::MakeField(field0),
TreeExprBuilder::MakeField(field1)});
+ };
+ auto bool_expr = TreeExprBuilder::MakeOr({make_and(), make_and()});
+ auto expr = TreeExprBuilder::MakeExpression(
+ bool_expr, arrow::field("generated_bool_out", arrow::boolean()));
+
+ auto configuration = std::make_shared<Configuration>(
+ true, gandiva::default_function_registry(), /*dump_ir=*/true);
+ std::shared_ptr<Projector> projector;
+ ASSERT_OK(Projector::Make(schema, {expr}, configuration, &projector));
+
+ const auto unoptimized_expr_ir =
+ ExtractFunctionIR(projector->DumpUnoptimizedIR(), "expr_0_0");
+ const auto optimized_expr_ir = ExtractFunctionIR(projector->DumpIR(),
"expr_0_0");
+ ASSERT_FALSE(unoptimized_expr_ir.empty());
+ ASSERT_FALSE(optimized_expr_ir.empty());
+
+ EXPECT_GT(CountOccurrences(unoptimized_expr_ir, "short_circuit"), 0);
+ EXPECT_GT(CountOccurrences(unoptimized_expr_ir, "non_short_circuit"), 0);
+ EXPECT_GT(CountOccurrences(unoptimized_expr_ir, "res_value = phi"), 0);
+ EXPECT_GT(CountOccurrences(unoptimized_expr_ir, "\"0_lbmap\""), 0);
+ EXPECT_EQ(0, CountOccurrences(unoptimized_expr_ir, "\"1_lbmap\""));
+ EXPECT_EQ(0, CountOccurrences(unoptimized_expr_ir, "\"2_lbmap\""));
+ EXPECT_GT(CountOccurrences(optimized_expr_ir, "generated_bool_f0"), 0);
+ EXPECT_GT(CountOccurrences(optimized_expr_ir, "generated_bool_f1"), 0);
+ EXPECT_GT(CountOccurrences(optimized_expr_ir, "\"0_lbmap\""), 0);
+ EXPECT_EQ(0, CountOccurrences(optimized_expr_ir, "\"1_lbmap\""));
+ EXPECT_EQ(0, CountOccurrences(optimized_expr_ir, "\"2_lbmap\""));
+}
+
+TEST_F(TestProjector, TestNestedBetweenCommonSubexpressionFoldIR) {
Review Comment:
It would be nice to have a few tests which check the expected results from
the expression. Just to make sure nothing changes in the results.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]