[ir] Implement EmitLiteral.

This CL fills in the EmitLiteral method. Each literal is emitted as the
appropriate type of register. The literal is not added to the current
flow block as it is not yet used.

Bug: tint:1718
Change-Id: Ic6a576bcc08dc6ea251b60d1d079929ac4d97981
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/110783
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
dan sinclair 2022-11-23 00:34:48 +00:00 committed by Dawn LUCI CQ
parent 329dfd7cbd
commit a5b73a0fde
3 changed files with 106 additions and 30 deletions

View File

@ -16,12 +16,15 @@
#include "src/tint/ast/alias.h" #include "src/tint/ast/alias.h"
#include "src/tint/ast/block_statement.h" #include "src/tint/ast/block_statement.h"
#include "src/tint/ast/bool_literal_expression.h"
#include "src/tint/ast/break_if_statement.h" #include "src/tint/ast/break_if_statement.h"
#include "src/tint/ast/break_statement.h" #include "src/tint/ast/break_statement.h"
#include "src/tint/ast/continue_statement.h" #include "src/tint/ast/continue_statement.h"
#include "src/tint/ast/float_literal_expression.h"
#include "src/tint/ast/for_loop_statement.h" #include "src/tint/ast/for_loop_statement.h"
#include "src/tint/ast/function.h" #include "src/tint/ast/function.h"
#include "src/tint/ast/if_statement.h" #include "src/tint/ast/if_statement.h"
#include "src/tint/ast/int_literal_expression.h"
#include "src/tint/ast/literal_expression.h" #include "src/tint/ast/literal_expression.h"
#include "src/tint/ast/loop_statement.h" #include "src/tint/ast/loop_statement.h"
#include "src/tint/ast/return_statement.h" #include "src/tint/ast/return_statement.h"
@ -528,17 +531,29 @@ bool BuilderImpl::EmitVariable(const ast::Variable* var) {
}); });
} }
bool BuilderImpl::EmitLiteral(const ast::LiteralExpression* lit) { utils::Result<Register> BuilderImpl::EmitLiteral(const ast::LiteralExpression* lit) {
return tint::Switch( // return tint::Switch( //
lit, lit,
// [&](const ast::BoolLiteralExpression* l) { }, [&](const ast::BoolLiteralExpression* l) {
// [&](const ast::FloatLiteralExpression* l) { }, return utils::Result<Register>{Register(l->value)};
// [&](const ast::IntLiteralExpression* l) { }, },
[&](const ast::FloatLiteralExpression* l) {
if (l->suffix == ast::FloatLiteralExpression::Suffix::kF) {
return utils::Result<Register>{Register(f32(static_cast<float>(l->value)))};
}
return utils::Result<Register>{Register(f16(static_cast<float>(l->value)))};
},
[&](const ast::IntLiteralExpression* l) {
if (l->suffix == ast::IntLiteralExpression::Suffix::kI) {
return utils::Result<Register>{Register(i32(l->value))};
}
return utils::Result<Register>{Register(u32(l->value))};
},
[&](Default) { [&](Default) {
diagnostics_.add_warning(tint::diag::System::IR, diagnostics_.add_warning(tint::diag::System::IR,
"unknown literal type: " + std::string(lit->TypeInfo().name), "unknown literal type: " + std::string(lit->TypeInfo().name),
lit->source); lit->source);
return false; return utils::Failure;
}); });
} }

View File

@ -23,6 +23,7 @@
#include "src/tint/ir/builder.h" #include "src/tint/ir/builder.h"
#include "src/tint/ir/flow_node.h" #include "src/tint/ir/flow_node.h"
#include "src/tint/ir/module.h" #include "src/tint/ir/module.h"
#include "src/tint/ir/register.h"
#include "src/tint/utils/result.h" #include "src/tint/utils/result.h"
// Forward Declarations // Forward Declarations
@ -148,7 +149,7 @@ class BuilderImpl {
/// Emits a literal expression /// Emits a literal expression
/// @param lit the literal to emit /// @param lit the literal to emit
/// @returns true if successful, false otherwise /// @returns true if successful, false otherwise
bool EmitLiteral(const ast::LiteralExpression* lit); utils::Result<Register> EmitLiteral(const ast::LiteralExpression* lit);
/// Emits a type /// Emits a type
/// @param ty the type to emit /// @param ty the type to emit

View File

@ -22,9 +22,9 @@ namespace {
using namespace tint::number_suffixes; // NOLINT using namespace tint::number_suffixes; // NOLINT
using IRBuilderImplTest = TestHelper; using IR_BuilderImplTest = TestHelper;
TEST_F(IRBuilderImplTest, Func) { TEST_F(IR_BuilderImplTest, Func) {
// func -> start -> end // func -> start -> end
Func("f", utils::Empty, ty.void_(), utils::Empty); Func("f", utils::Empty, ty.void_(), utils::Empty);
@ -47,7 +47,7 @@ TEST_F(IRBuilderImplTest, Func) {
EXPECT_EQ(f->start_target->branch_target, f->end_target); EXPECT_EQ(f->start_target->branch_target, f->end_target);
} }
TEST_F(IRBuilderImplTest, EntryPoint) { TEST_F(IR_BuilderImplTest, EntryPoint) {
Func("f", utils::Empty, ty.void_(), utils::Empty, Func("f", utils::Empty, ty.void_(), utils::Empty,
utils::Vector{Stage(ast::PipelineStage::kFragment)}); utils::Vector{Stage(ast::PipelineStage::kFragment)});
auto& b = CreateBuilder(); auto& b = CreateBuilder();
@ -60,7 +60,7 @@ TEST_F(IRBuilderImplTest, EntryPoint) {
EXPECT_EQ(m.functions[0], m.entry_points[0]); EXPECT_EQ(m.functions[0], m.entry_points[0]);
} }
TEST_F(IRBuilderImplTest, IfStatement) { TEST_F(IR_BuilderImplTest, IfStatement) {
// func -> start -> if -> true block // func -> start -> if -> true block
// -> false block // -> false block
// //
@ -103,7 +103,7 @@ TEST_F(IRBuilderImplTest, IfStatement) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, IfStatement_TrueReturns) { TEST_F(IR_BuilderImplTest, IfStatement_TrueReturns) {
// func -> start -> if -> true block // func -> start -> if -> true block
// -> false block // -> false block
// //
@ -144,7 +144,7 @@ TEST_F(IRBuilderImplTest, IfStatement_TrueReturns) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, IfStatement_FalseReturns) { TEST_F(IR_BuilderImplTest, IfStatement_FalseReturns) {
// func -> start -> if -> true block // func -> start -> if -> true block
// -> false block // -> false block
// //
@ -185,7 +185,7 @@ TEST_F(IRBuilderImplTest, IfStatement_FalseReturns) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, IfStatement_BothReturn) { TEST_F(IR_BuilderImplTest, IfStatement_BothReturn) {
// func -> start -> if -> true block // func -> start -> if -> true block
// -> false block // -> false block
// //
@ -225,7 +225,7 @@ TEST_F(IRBuilderImplTest, IfStatement_BothReturn) {
EXPECT_EQ(flow->false_target->branch_target, func->end_target); EXPECT_EQ(flow->false_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, IfStatement_JumpChainToMerge) { TEST_F(IR_BuilderImplTest, IfStatement_JumpChainToMerge) {
// if (true) { // if (true) {
// loop { // loop {
// break; // break;
@ -282,7 +282,7 @@ TEST_F(IRBuilderImplTest, IfStatement_JumpChainToMerge) {
EXPECT_EQ(if_flow->merge_target->branch_target, func->end_target); EXPECT_EQ(if_flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, Loop_WithBreak) { TEST_F(IR_BuilderImplTest, Loop_WithBreak) {
// func -> start -> loop -> loop start -> loop merge -> func end // func -> start -> loop -> loop start -> loop merge -> func end
// //
// [continuing] -> loop start // [continuing] -> loop start
@ -320,7 +320,7 @@ TEST_F(IRBuilderImplTest, Loop_WithBreak) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, Loop_WithContinue) { TEST_F(IR_BuilderImplTest, Loop_WithContinue) {
// func -> start -> loop -> loop start -> if -> true block // func -> start -> loop -> loop start -> if -> true block
// -> false block // -> false block
// //
@ -379,7 +379,7 @@ TEST_F(IRBuilderImplTest, Loop_WithContinue) {
EXPECT_EQ(loop_flow->merge_target->branch_target, func->end_target); EXPECT_EQ(loop_flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, Loop_WithContinuing_BreakIf) { TEST_F(IR_BuilderImplTest, Loop_WithContinuing_BreakIf) {
// func -> start -> loop -> loop start -> continuing // func -> start -> loop -> loop start -> continuing
// //
// [loop continuing] -> if -> true branch // [loop continuing] -> if -> true branch
@ -439,7 +439,7 @@ TEST_F(IRBuilderImplTest, Loop_WithContinuing_BreakIf) {
EXPECT_EQ(loop_flow->merge_target->branch_target, func->end_target); EXPECT_EQ(loop_flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, Loop_WithReturn) { TEST_F(IR_BuilderImplTest, Loop_WithReturn) {
// func -> start -> loop -> loop start -> if -> true block // func -> start -> loop -> loop start -> if -> true block
// -> false block // -> false block
// //
@ -499,7 +499,7 @@ TEST_F(IRBuilderImplTest, Loop_WithReturn) {
EXPECT_EQ(loop_flow->merge_target->branch_target, nullptr); EXPECT_EQ(loop_flow->merge_target->branch_target, nullptr);
} }
TEST_F(IRBuilderImplTest, Loop_WithOnlyReturn) { TEST_F(IR_BuilderImplTest, Loop_WithOnlyReturn) {
// { // {
// loop { // loop {
// return; // return;
@ -551,7 +551,7 @@ TEST_F(IRBuilderImplTest, Loop_WithOnlyReturn) {
EXPECT_EQ(func->start_target->branch_target, ir_loop); EXPECT_EQ(func->start_target->branch_target, ir_loop);
} }
TEST_F(IRBuilderImplTest, Loop_WithOnlyReturn_ContinuingBreakIf) { TEST_F(IR_BuilderImplTest, Loop_WithOnlyReturn_ContinuingBreakIf) {
// { // {
// loop { // loop {
// return; // return;
@ -622,7 +622,7 @@ TEST_F(IRBuilderImplTest, Loop_WithOnlyReturn_ContinuingBreakIf) {
EXPECT_EQ(func->start_target->branch_target, ir_loop); EXPECT_EQ(func->start_target->branch_target, ir_loop);
} }
TEST_F(IRBuilderImplTest, Loop_WithIf_BothBranchesBreak) { TEST_F(IR_BuilderImplTest, Loop_WithIf_BothBranchesBreak) {
// func -> start -> loop -> loop start -> if -> true branch // func -> start -> loop -> loop start -> if -> true branch
// -> false branch // -> false branch
// //
@ -684,7 +684,7 @@ TEST_F(IRBuilderImplTest, Loop_WithIf_BothBranchesBreak) {
EXPECT_EQ(loop_flow->merge_target->branch_target, func->end_target); EXPECT_EQ(loop_flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, Loop_Nested) { TEST_F(IR_BuilderImplTest, Loop_Nested) {
// loop { // loop_a // loop { // loop_a
// loop { // loop_b // loop { // loop_b
// if (true) { break; } // if_a // if (true) { break; } // if_a
@ -879,7 +879,7 @@ TEST_F(IRBuilderImplTest, Loop_Nested) {
EXPECT_EQ(loop_flow_a->merge_target->branch_target, func->end_target); EXPECT_EQ(loop_flow_a->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, While) { TEST_F(IR_BuilderImplTest, While) {
// { // {
// while false { // while false {
// } // }
@ -939,7 +939,7 @@ TEST_F(IRBuilderImplTest, While) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, While_Return) { TEST_F(IR_BuilderImplTest, While_Return) {
// { // {
// while true { // while true {
// return; // return;
@ -1000,7 +1000,7 @@ TEST_F(IRBuilderImplTest, While_Return) {
} }
// TODO(dsinclair): Enable when variable declarations and increment are supported // TODO(dsinclair): Enable when variable declarations and increment are supported
TEST_F(IRBuilderImplTest, DISABLED_For) { TEST_F(IR_BuilderImplTest, DISABLED_For) {
// for(var i: 0; i < 10; i++) { // for(var i: 0; i < 10; i++) {
// } // }
// //
@ -1058,7 +1058,7 @@ TEST_F(IRBuilderImplTest, DISABLED_For) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, For_NoInitCondOrContinuing) { TEST_F(IR_BuilderImplTest, For_NoInitCondOrContinuing) {
// for (;;) { // for (;;) {
// break; // break;
// } // }
@ -1096,7 +1096,7 @@ TEST_F(IRBuilderImplTest, For_NoInitCondOrContinuing) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, Switch) { TEST_F(IR_BuilderImplTest, Switch) {
// func -> switch -> case 1 // func -> switch -> case 1
// -> case 2 // -> case 2
// -> default // -> default
@ -1153,7 +1153,7 @@ TEST_F(IRBuilderImplTest, Switch) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, Switch_OnlyDefault) { TEST_F(IR_BuilderImplTest, Switch_OnlyDefault) {
// func -> switch -> default -> switch merge -> func end // func -> switch -> default -> switch merge -> func end
// //
auto* ast_switch = Switch(1_i, utils::Vector{DefaultCase(Block())}); auto* ast_switch = Switch(1_i, utils::Vector{DefaultCase(Block())});
@ -1189,7 +1189,7 @@ TEST_F(IRBuilderImplTest, Switch_OnlyDefault) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, Switch_WithBreak) { TEST_F(IR_BuilderImplTest, Switch_WithBreak) {
// { // {
// switch(1) { // switch(1) {
// case 0: { // case 0: {
@ -1248,7 +1248,7 @@ TEST_F(IRBuilderImplTest, Switch_WithBreak) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
} }
TEST_F(IRBuilderImplTest, Switch_AllReturn) { TEST_F(IR_BuilderImplTest, Switch_AllReturn) {
// { // {
// switch(1) { // switch(1) {
// case 0: { // case 0: {
@ -1313,5 +1313,65 @@ TEST_F(IRBuilderImplTest, Switch_AllReturn) {
EXPECT_EQ(flow->merge_target->branch_target, nullptr); EXPECT_EQ(flow->merge_target->branch_target, nullptr);
} }
TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_True) {
auto& b = CreateEmptyBuilder();
auto r = b.EmitLiteral(Expr(true));
ASSERT_TRUE(r);
auto reg = r.Get();
EXPECT_TRUE(reg.IsBool());
EXPECT_TRUE(reg.AsBool());
}
TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_False) {
auto& b = CreateEmptyBuilder();
auto r = b.EmitLiteral(Expr(false));
ASSERT_TRUE(r);
auto reg = r.Get();
EXPECT_TRUE(reg.IsBool());
EXPECT_FALSE(reg.AsBool());
}
TEST_F(IR_BuilderImplTest, EmitLiteral_F32) {
auto& b = CreateEmptyBuilder();
auto r = b.EmitLiteral(Expr(1.2_f));
ASSERT_TRUE(r);
auto reg = r.Get();
EXPECT_TRUE(reg.IsF32());
EXPECT_EQ(1.2_f, reg.AsF32());
}
TEST_F(IR_BuilderImplTest, EmitLiteral_F16) {
auto& b = CreateEmptyBuilder();
auto r = b.EmitLiteral(Expr(1.2_h));
ASSERT_TRUE(r);
auto reg = r.Get();
EXPECT_TRUE(reg.IsF16());
EXPECT_EQ(1.2_h, reg.AsF16());
}
TEST_F(IR_BuilderImplTest, EmitLiteral_I32) {
auto& b = CreateEmptyBuilder();
auto r = b.EmitLiteral(Expr(-2_i));
ASSERT_TRUE(r);
auto reg = r.Get();
EXPECT_TRUE(reg.IsI32());
EXPECT_EQ(-2_i, reg.AsI32());
}
TEST_F(IR_BuilderImplTest, EmitLiteral_U32) {
auto& b = CreateEmptyBuilder();
auto r = b.EmitLiteral(Expr(2_u));
ASSERT_TRUE(r);
auto reg = r.Get();
EXPECT_TRUE(reg.IsU32());
EXPECT_EQ(2_u, reg.AsU32());
}
} // namespace } // namespace
} // namespace tint::ir } // namespace tint::ir