Convert ir::Constant over to use a constant::Value
This CL updaets the ir::Constant to store a constant::Value instead of the specific numbers themselves. Bug: tint:1718 Change-Id: I66b0a9643893b6079399daf61ee39ac5811e1eaf Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/114362 Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
dd1e4e39f2
commit
19ebcb2230
|
@ -1344,8 +1344,8 @@ int main(int argc, const char** argv) {
|
|||
} else {
|
||||
auto mod = result.Move();
|
||||
if (options.dump_ir) {
|
||||
tint::ir::Disassembler d;
|
||||
std::cout << d.Disassemble(mod) << std::endl;
|
||||
tint::ir::Disassembler d(mod);
|
||||
std::cout << d.Disassemble() << std::endl;
|
||||
}
|
||||
if (options.dump_ir_graph) {
|
||||
auto graph = tint::ir::Debug::AsDotGraph(&mod);
|
||||
|
|
|
@ -28,9 +28,9 @@ Binary::Binary(Kind kind, const Value* result, const Value* lhs, const Value* rh
|
|||
|
||||
Binary::~Binary() = default;
|
||||
|
||||
std::ostream& Binary::ToString(std::ostream& out) const {
|
||||
Result()->ToString(out) << " = ";
|
||||
lhs_->ToString(out) << " ";
|
||||
std::ostream& Binary::ToString(std::ostream& out, const SymbolTable& st) const {
|
||||
Result()->ToString(out, st) << " = ";
|
||||
lhs_->ToString(out, st) << " ";
|
||||
|
||||
switch (GetKind()) {
|
||||
case Binary::Kind::kAdd:
|
||||
|
@ -89,7 +89,7 @@ std::ostream& Binary::ToString(std::ostream& out) const {
|
|||
break;
|
||||
}
|
||||
out << " ";
|
||||
rhs_->ToString(out);
|
||||
rhs_->ToString(out, st);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "src/tint/castable.h"
|
||||
#include "src/tint/ir/instruction.h"
|
||||
#include "src/tint/ir/value.h"
|
||||
#include "src/tint/symbol_table.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
|
@ -79,8 +80,9 @@ class Binary : public Castable<Binary, Instruction> {
|
|||
|
||||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @param st the symbol table
|
||||
/// @returns the stream
|
||||
std::ostream& ToString(std::ostream& out) const override;
|
||||
std::ostream& ToString(std::ostream& out, const SymbolTable& st) const override;
|
||||
|
||||
private:
|
||||
Kind kind_;
|
||||
|
|
|
@ -20,13 +20,15 @@
|
|||
namespace tint::ir {
|
||||
namespace {
|
||||
|
||||
using namespace tint::number_suffixes; // NOLINT
|
||||
//
|
||||
using IR_InstructionTest = TestHelper;
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateAnd) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.And(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.And(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kAnd);
|
||||
|
||||
|
@ -34,17 +36,17 @@ TEST_F(IR_InstructionTest, CreateAnd) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 & 2");
|
||||
}
|
||||
|
||||
|
@ -52,7 +54,7 @@ TEST_F(IR_InstructionTest, CreateOr) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.Or(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.Or(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kOr);
|
||||
|
||||
|
@ -60,17 +62,17 @@ TEST_F(IR_InstructionTest, CreateOr) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 | 2");
|
||||
}
|
||||
|
||||
|
@ -78,7 +80,7 @@ TEST_F(IR_InstructionTest, CreateXor) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.Xor(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.Xor(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kXor);
|
||||
|
||||
|
@ -86,17 +88,17 @@ TEST_F(IR_InstructionTest, CreateXor) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 ^ 2");
|
||||
}
|
||||
|
||||
|
@ -104,8 +106,7 @@ TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr =
|
||||
b.builder.LogicalAnd(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.LogicalAnd(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kLogicalAnd);
|
||||
|
||||
|
@ -113,17 +114,17 @@ TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 && 2");
|
||||
}
|
||||
|
||||
|
@ -131,7 +132,7 @@ TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.LogicalOr(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.LogicalOr(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kLogicalOr);
|
||||
|
||||
|
@ -139,17 +140,17 @@ TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 || 2");
|
||||
}
|
||||
|
||||
|
@ -157,7 +158,7 @@ TEST_F(IR_InstructionTest, CreateEqual) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.Equal(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.Equal(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kEqual);
|
||||
|
||||
|
@ -165,17 +166,17 @@ TEST_F(IR_InstructionTest, CreateEqual) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 == 2");
|
||||
}
|
||||
|
||||
|
@ -183,7 +184,7 @@ TEST_F(IR_InstructionTest, CreateNotEqual) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.NotEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.NotEqual(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kNotEqual);
|
||||
|
||||
|
@ -191,17 +192,17 @@ TEST_F(IR_InstructionTest, CreateNotEqual) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 != 2");
|
||||
}
|
||||
|
||||
|
@ -209,7 +210,7 @@ TEST_F(IR_InstructionTest, CreateLessThan) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.LessThan(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.LessThan(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kLessThan);
|
||||
|
||||
|
@ -217,17 +218,17 @@ TEST_F(IR_InstructionTest, CreateLessThan) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 < 2");
|
||||
}
|
||||
|
||||
|
@ -235,8 +236,7 @@ TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr =
|
||||
b.builder.GreaterThan(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.GreaterThan(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kGreaterThan);
|
||||
|
||||
|
@ -244,17 +244,17 @@ TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 > 2");
|
||||
}
|
||||
|
||||
|
@ -262,8 +262,7 @@ TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr =
|
||||
b.builder.LessThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.LessThanEqual(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kLessThanEqual);
|
||||
|
||||
|
@ -271,17 +270,17 @@ TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 <= 2");
|
||||
}
|
||||
|
||||
|
@ -290,7 +289,7 @@ TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
|||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr =
|
||||
b.builder.GreaterThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
b.builder.GreaterThanEqual(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kGreaterThanEqual);
|
||||
|
||||
|
@ -298,17 +297,17 @@ TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 >= 2");
|
||||
}
|
||||
|
||||
|
@ -316,7 +315,7 @@ TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.ShiftLeft(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.ShiftLeft(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kShiftLeft);
|
||||
|
||||
|
@ -324,17 +323,17 @@ TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 << 2");
|
||||
}
|
||||
|
||||
|
@ -342,8 +341,7 @@ TEST_F(IR_InstructionTest, CreateShiftRight) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr =
|
||||
b.builder.ShiftRight(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.ShiftRight(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kShiftRight);
|
||||
|
||||
|
@ -351,17 +349,17 @@ TEST_F(IR_InstructionTest, CreateShiftRight) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 >> 2");
|
||||
}
|
||||
|
||||
|
@ -369,7 +367,7 @@ TEST_F(IR_InstructionTest, CreateAdd) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.Add(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.Add(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kAdd);
|
||||
|
||||
|
@ -377,17 +375,17 @@ TEST_F(IR_InstructionTest, CreateAdd) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 + 2");
|
||||
}
|
||||
|
||||
|
@ -395,7 +393,7 @@ TEST_F(IR_InstructionTest, CreateSubtract) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.Subtract(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.Subtract(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kSubtract);
|
||||
|
||||
|
@ -403,17 +401,17 @@ TEST_F(IR_InstructionTest, CreateSubtract) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 - 2");
|
||||
}
|
||||
|
||||
|
@ -421,7 +419,7 @@ TEST_F(IR_InstructionTest, CreateMultiply) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.Multiply(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.Multiply(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kMultiply);
|
||||
|
||||
|
@ -429,17 +427,17 @@ TEST_F(IR_InstructionTest, CreateMultiply) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 * 2");
|
||||
}
|
||||
|
||||
|
@ -447,7 +445,7 @@ TEST_F(IR_InstructionTest, CreateDivide) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.Divide(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.Divide(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kDivide);
|
||||
|
||||
|
@ -455,17 +453,17 @@ TEST_F(IR_InstructionTest, CreateDivide) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 / 2");
|
||||
}
|
||||
|
||||
|
@ -473,7 +471,7 @@ TEST_F(IR_InstructionTest, CreateModulo) {
|
|||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.Modulo(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||
const auto* instr = b.builder.Modulo(b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kModulo);
|
||||
|
||||
|
@ -481,17 +479,17 @@ TEST_F(IR_InstructionTest, CreateModulo) {
|
|||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
auto lhs = instr->LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
auto lhs = instr->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||
auto rhs = instr->RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
auto rhs = instr->RHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 % 2");
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
#ifndef SRC_TINT_IR_BUILDER_H_
|
||||
#define SRC_TINT_IR_BUILDER_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/constant/scalar.h"
|
||||
#include "src/tint/ir/binary.h"
|
||||
#include "src/tint/ir/constant.h"
|
||||
#include "src/tint/ir/function.h"
|
||||
|
@ -25,6 +28,11 @@
|
|||
#include "src/tint/ir/temp.h"
|
||||
#include "src/tint/ir/terminator.h"
|
||||
#include "src/tint/ir/value.h"
|
||||
#include "src/tint/type/bool.h"
|
||||
#include "src/tint/type/f16.h"
|
||||
#include "src/tint/type/f32.h"
|
||||
#include "src/tint/type/i32.h"
|
||||
#include "src/tint/type/u32.h"
|
||||
|
||||
// Forward Declarations
|
||||
namespace tint {
|
||||
|
@ -85,14 +93,56 @@ class Builder {
|
|||
/// @param to the node to branch too
|
||||
void Branch(Block* from, FlowNode* to);
|
||||
|
||||
/// Creates a new Constant
|
||||
/// Creates a constant::Value
|
||||
/// @param args the arguments
|
||||
/// @returns the new constant value
|
||||
template <typename T, typename... ARGS>
|
||||
traits::EnableIf<traits::IsTypeOrDerived<T, constant::Value>, const T>* create(ARGS&&... args) {
|
||||
return ir.constants.Create<T>(std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
/// Creates a new ir::Constant
|
||||
/// @param val the constant value
|
||||
/// @returns the new constant
|
||||
template <typename T>
|
||||
const ir::Constant* Constant(T val) {
|
||||
const ir::Constant* Constant(const constant::Value* val) {
|
||||
return ir.values.Create<ir::Constant>(val);
|
||||
}
|
||||
|
||||
/// Creates a ir::Constant for an i32 Scalar
|
||||
/// @param v the value
|
||||
/// @returns the new constant
|
||||
const ir::Constant* Constant(i32 v) {
|
||||
return Constant(create<constant::Scalar<i32>>(ir.types.Get<type::I32>(), v));
|
||||
}
|
||||
|
||||
/// Creates a ir::Constant for a u32 Scalar
|
||||
/// @param v the value
|
||||
/// @returns the new constant
|
||||
const ir::Constant* Constant(u32 v) {
|
||||
return Constant(create<constant::Scalar<u32>>(ir.types.Get<type::U32>(), v));
|
||||
}
|
||||
|
||||
/// Creates a ir::Constant for a f32 Scalar
|
||||
/// @param v the value
|
||||
/// @returns the new constant
|
||||
const ir::Constant* Constant(f32 v) {
|
||||
return Constant(create<constant::Scalar<f32>>(ir.types.Get<type::F32>(), v));
|
||||
}
|
||||
|
||||
/// Creates a ir::Constant for a f16 Scalar
|
||||
/// @param v the value
|
||||
/// @returns the new constant
|
||||
const ir::Constant* Constant(f16 v) {
|
||||
return Constant(create<constant::Scalar<f16>>(ir.types.Get<type::F16>(), v));
|
||||
}
|
||||
|
||||
/// Creates a ir::Constant for a bool Scalar
|
||||
/// @param v the value
|
||||
/// @returns the new constant
|
||||
const ir::Constant* Constant(bool v) {
|
||||
return Constant(create<constant::Scalar<bool>>(ir.types.Get<type::Bool>(), v));
|
||||
}
|
||||
|
||||
/// Creates a new Temporary
|
||||
/// @returns the new temporary
|
||||
const ir::Temp* Temp() { return ir.values.Create<ir::Temp>(AllocateTempId()); }
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "src/tint/ir/switch.h"
|
||||
#include "src/tint/ir/terminator.h"
|
||||
#include "src/tint/program.h"
|
||||
#include "src/tint/sem/expression.h"
|
||||
#include "src/tint/sem/module.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
@ -628,30 +629,24 @@ utils::Result<const Value*> BuilderImpl::EmitBinary(const ast::BinaryExpression*
|
|||
}
|
||||
|
||||
utils::Result<const Value*> BuilderImpl::EmitLiteral(const ast::LiteralExpression* lit) {
|
||||
return tint::Switch( //
|
||||
lit,
|
||||
[&](const ast::BoolLiteralExpression* l) {
|
||||
return utils::Result<const Value*>(builder.Constant(l->value));
|
||||
},
|
||||
[&](const ast::FloatLiteralExpression* l) {
|
||||
if (l->suffix == ast::FloatLiteralExpression::Suffix::kF) {
|
||||
return utils::Result<const Value*>(
|
||||
builder.Constant(f32(static_cast<float>(l->value))));
|
||||
}
|
||||
return utils::Result<const Value*>(builder.Constant(f16(static_cast<float>(l->value))));
|
||||
},
|
||||
[&](const ast::IntLiteralExpression* l) {
|
||||
if (l->suffix == ast::IntLiteralExpression::Suffix::kI) {
|
||||
return utils::Result<const Value*>(builder.Constant(i32(l->value)));
|
||||
}
|
||||
return utils::Result<const Value*>(builder.Constant(u32(l->value)));
|
||||
},
|
||||
[&](Default) {
|
||||
diagnostics_.add_warning(tint::diag::System::IR,
|
||||
"unknown literal type: " + std::string(lit->TypeInfo().name),
|
||||
lit->source);
|
||||
return utils::Failure;
|
||||
});
|
||||
auto* sem = builder.ir.program->Sem().Get(lit);
|
||||
if (!sem) {
|
||||
diagnostics_.add_error(
|
||||
tint::diag::System::IR,
|
||||
"Failed to get semantic information for node " + std::string(lit->TypeInfo().name),
|
||||
lit->source);
|
||||
return utils::Failure;
|
||||
}
|
||||
|
||||
auto* cv = sem->ConstantValue();
|
||||
if (!cv) {
|
||||
diagnostics_.add_error(
|
||||
tint::diag::System::IR,
|
||||
"Failed to get constant value for node " + std::string(lit->TypeInfo().name),
|
||||
lit->source);
|
||||
return utils::Failure;
|
||||
}
|
||||
return utils::Result<const Value*>(builder.Constant(cv));
|
||||
}
|
||||
|
||||
bool BuilderImpl::EmitType(const ast::Type* ty) {
|
||||
|
|
|
@ -102,9 +102,9 @@ TEST_F(IR_BuilderImplTest, IfStatement) {
|
|||
|
||||
// Check condition
|
||||
ASSERT_TRUE(flow->condition->Is<Constant>());
|
||||
auto* instr = flow->condition->As<Constant>();
|
||||
ASSERT_TRUE(instr->IsBool());
|
||||
EXPECT_TRUE(instr->AsBool());
|
||||
auto* instr = flow->condition->As<Constant>()->value;
|
||||
ASSERT_TRUE(instr->Is<constant::Scalar<bool>>());
|
||||
EXPECT_TRUE(instr->As<constant::Scalar<bool>>()->ValueAs<bool>());
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, IfStatement_TrueReturns) {
|
||||
|
@ -504,9 +504,9 @@ TEST_F(IR_BuilderImplTest, Loop_WithReturn) {
|
|||
|
||||
// Check condition
|
||||
ASSERT_TRUE(if_flow->condition->Is<Constant>());
|
||||
auto* instr = if_flow->condition->As<Constant>();
|
||||
ASSERT_TRUE(instr->IsBool());
|
||||
EXPECT_TRUE(instr->AsBool());
|
||||
auto* instr = if_flow->condition->As<Constant>()->value;
|
||||
ASSERT_TRUE(instr->Is<constant::Scalar<bool>>());
|
||||
EXPECT_TRUE(instr->As<constant::Scalar<bool>>()->ValueAs<bool>());
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, Loop_WithOnlyReturn) {
|
||||
|
@ -950,9 +950,9 @@ TEST_F(IR_BuilderImplTest, While) {
|
|||
|
||||
// Check condition
|
||||
ASSERT_TRUE(if_flow->condition->Is<Constant>());
|
||||
auto* instr = if_flow->condition->As<Constant>();
|
||||
ASSERT_TRUE(instr->IsBool());
|
||||
EXPECT_FALSE(instr->AsBool());
|
||||
auto* instr = if_flow->condition->As<Constant>()->value;
|
||||
ASSERT_TRUE(instr->Is<constant::Scalar<bool>>());
|
||||
EXPECT_FALSE(instr->As<constant::Scalar<bool>>()->ValueAs<bool>());
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, While_Return) {
|
||||
|
@ -1075,9 +1075,9 @@ TEST_F(IR_BuilderImplTest, DISABLED_For) {
|
|||
|
||||
// Check condition
|
||||
ASSERT_TRUE(if_flow->condition->Is<Constant>());
|
||||
auto* instr = if_flow->condition->As<Constant>();
|
||||
ASSERT_TRUE(instr->IsBool());
|
||||
EXPECT_FALSE(instr->AsBool());
|
||||
auto* instr = if_flow->condition->As<Constant>()->value;
|
||||
ASSERT_TRUE(instr->Is<constant::Scalar<bool>>());
|
||||
EXPECT_FALSE(instr->As<constant::Scalar<bool>>()->ValueAs<bool>());
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, For_NoInitCondOrContinuing) {
|
||||
|
@ -1176,9 +1176,9 @@ TEST_F(IR_BuilderImplTest, Switch) {
|
|||
|
||||
// Check condition
|
||||
ASSERT_TRUE(flow->condition->Is<Constant>());
|
||||
auto* instr = flow->condition->As<Constant>();
|
||||
ASSERT_TRUE(instr->IsI32());
|
||||
EXPECT_EQ(1_i, instr->AsI32());
|
||||
auto* instr = flow->condition->As<Constant>()->value;
|
||||
ASSERT_TRUE(instr->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(1_i, instr->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, Switch_OnlyDefault) {
|
||||
|
@ -1342,283 +1342,378 @@ TEST_F(IR_BuilderImplTest, Switch_AllReturn) {
|
|||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_True) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitLiteral(Expr(true));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Expr(true);
|
||||
GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate, expr);
|
||||
|
||||
auto& b = CreateBuilder();
|
||||
auto r = b.EmitLiteral(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsBool());
|
||||
EXPECT_TRUE(val->AsBool());
|
||||
auto* val = r.Get()->As<Constant>()->value;
|
||||
EXPECT_TRUE(val->Is<constant::Scalar<bool>>());
|
||||
EXPECT_TRUE(val->As<constant::Scalar<bool>>()->ValueAs<bool>());
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_False) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitLiteral(Expr(false));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Expr(false);
|
||||
GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate, expr);
|
||||
|
||||
auto& b = CreateBuilder();
|
||||
auto r = b.EmitLiteral(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsBool());
|
||||
EXPECT_FALSE(val->AsBool());
|
||||
auto* val = r.Get()->As<Constant>()->value;
|
||||
EXPECT_TRUE(val->Is<constant::Scalar<bool>>());
|
||||
EXPECT_FALSE(val->As<constant::Scalar<bool>>()->ValueAs<bool>());
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitLiteral_F32) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitLiteral(Expr(1.2_f));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Expr(1.2_f);
|
||||
GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate, expr);
|
||||
|
||||
auto& b = CreateBuilder();
|
||||
auto r = b.EmitLiteral(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsF32());
|
||||
EXPECT_EQ(1.2_f, val->AsF32());
|
||||
auto* val = r.Get()->As<Constant>()->value;
|
||||
EXPECT_TRUE(val->Is<constant::Scalar<f32>>());
|
||||
EXPECT_EQ(1.2_f, val->As<constant::Scalar<f32>>()->ValueAs<f32>());
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitLiteral_F16) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitLiteral(Expr(1.2_h));
|
||||
ASSERT_TRUE(r);
|
||||
Enable(ast::Extension::kF16);
|
||||
auto* expr = Expr(1.2_h);
|
||||
GlobalVar("a", ty.f16(), ast::AddressSpace::kPrivate, expr);
|
||||
|
||||
auto& b = CreateBuilder();
|
||||
auto r = b.EmitLiteral(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsF16());
|
||||
EXPECT_EQ(1.2_h, val->AsF16());
|
||||
auto* val = r.Get()->As<Constant>()->value;
|
||||
EXPECT_TRUE(val->Is<constant::Scalar<f16>>());
|
||||
EXPECT_EQ(1.2_h, val->As<constant::Scalar<f16>>()->ValueAs<f32>());
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitLiteral_I32) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitLiteral(Expr(-2_i));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Expr(-2_i);
|
||||
GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate, expr);
|
||||
|
||||
auto& b = CreateBuilder();
|
||||
auto r = b.EmitLiteral(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsI32());
|
||||
EXPECT_EQ(-2_i, val->AsI32());
|
||||
auto* val = r.Get()->As<Constant>()->value;
|
||||
EXPECT_TRUE(val->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(-2_i, val->As<constant::Scalar<i32>>()->ValueAs<f32>());
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitLiteral_U32) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitLiteral(Expr(2_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Expr(2_u);
|
||||
GlobalVar("a", ty.u32(), ast::AddressSpace::kPrivate, expr);
|
||||
|
||||
auto& b = CreateBuilder();
|
||||
auto r = b.EmitLiteral(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsU32());
|
||||
EXPECT_EQ(2_u, val->AsU32());
|
||||
auto* val = r.Get()->As<Constant>()->value;
|
||||
EXPECT_TRUE(val->Is<constant::Scalar<u32>>());
|
||||
EXPECT_EQ(2_u, val->As<constant::Scalar<u32>>()->ValueAs<f32>());
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Add) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(Add(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Add(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 + 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Subtract) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(Sub(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Sub(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 - 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Multiply) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(Mul(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Mul(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 * 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Div) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(Div(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Div(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 / 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Modulo) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(Mod(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Mod(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 % 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_And) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(And(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = And(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 & 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Or) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(Or(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Or(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 | 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Xor) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(Xor(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Xor(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 ^ 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalAnd) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(LogicalAnd(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = LogicalAnd(true, false);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 && 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = true && false
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalOr) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(LogicalOr(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = LogicalOr(false, true);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 || 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = false || true
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Eqaul) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(Equal(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Equal) {
|
||||
auto* expr = Equal(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 == 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_NotEqual) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(NotEqual(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = NotEqual(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 != 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThan) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(LessThan(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = LessThan(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 < 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThan) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(GreaterThan(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = GreaterThan(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 > 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThanEqual) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(LessThanEqual(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = LessThanEqual(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 <= 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThanEqual) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(GreaterThanEqual(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = GreaterThanEqual(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 >= 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftLeft) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(Shl(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Shl(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 << 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftRight) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(Shr(3_u, 4_u));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = Shr(3_u, 4_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 >> 4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Compound) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
auto r = b.EmitExpression(LogicalOr( //
|
||||
LessThan(1_u, Add(Shr(3_u, 4_u), 9_u)), GreaterThan(2.5_f, Div(6.7_f, Mul(2.3_f, 5.5_f)))));
|
||||
ASSERT_TRUE(r);
|
||||
auto* expr = LogicalOr(LessThan(1_u, Add(Shr(3_u, 4_u), 9_u)),
|
||||
GreaterThan(2.5_f, Div(6.7_f, Mul(2.3_f, 5.5_f))));
|
||||
WrapInFunction(expr);
|
||||
|
||||
Disassembler d;
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 >> 4
|
||||
%2 = %1 + 9
|
||||
%3 = 1 < %2
|
||||
%4 = 2.300000 * 5.500000
|
||||
%5 = 6.700000 / %4
|
||||
%6 = 2.500000 > %5
|
||||
%4 = 2.3 * 5.5
|
||||
%5 = 6.7 / %4
|
||||
%6 = 2.5 > %5
|
||||
%7 = %3 || %6
|
||||
)");
|
||||
}
|
||||
|
|
|
@ -16,40 +16,48 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/constant/composite.h"
|
||||
#include "src/tint/constant/scalar.h"
|
||||
#include "src/tint/constant/splat.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ir::Constant);
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
Constant::Constant(f32 f) : kind_(Kind::kF32), data_(f) {}
|
||||
|
||||
Constant::Constant(f16 f) : kind_(Kind::kF16), data_(f) {}
|
||||
|
||||
Constant::Constant(u32 u) : kind_(Kind::kU32), data_(u) {}
|
||||
|
||||
Constant::Constant(i32 i) : kind_(Kind::kI32), data_(i) {}
|
||||
|
||||
Constant::Constant(bool b) : kind_(Kind::kBool), data_(b) {}
|
||||
Constant::Constant(const constant::Value* val) : value(val) {}
|
||||
|
||||
Constant::~Constant() = default;
|
||||
|
||||
std::ostream& Constant::ToString(std::ostream& out) const {
|
||||
switch (GetKind()) {
|
||||
case Constant::Kind::kF32:
|
||||
out << std::to_string(AsF32().value);
|
||||
break;
|
||||
case Constant::Kind::kF16:
|
||||
out << std::to_string(AsF16().value);
|
||||
break;
|
||||
case Constant::Kind::kI32:
|
||||
out << std::to_string(AsI32().value);
|
||||
break;
|
||||
case Constant::Kind::kU32:
|
||||
out << std::to_string(AsU32().value);
|
||||
break;
|
||||
case Constant::Kind::kBool:
|
||||
out << (AsBool() ? "true" : "false");
|
||||
break;
|
||||
}
|
||||
std::ostream& Constant::ToString(std::ostream& out, const SymbolTable& st) const {
|
||||
std::function<void(const constant::Value*)> emit = [&](const constant::Value* c) {
|
||||
Switch(
|
||||
c,
|
||||
[&](const constant::Scalar<AFloat>* scalar) { out << scalar->ValueAs<AFloat>().value; },
|
||||
[&](const constant::Scalar<AInt>* scalar) { out << scalar->ValueAs<AInt>().value; },
|
||||
[&](const constant::Scalar<i32>* scalar) { out << scalar->ValueAs<i32>().value; },
|
||||
[&](const constant::Scalar<u32>* scalar) { out << scalar->ValueAs<u32>().value; },
|
||||
[&](const constant::Scalar<f32>* scalar) { out << scalar->ValueAs<f32>().value; },
|
||||
[&](const constant::Scalar<f16>* scalar) { out << scalar->ValueAs<f16>().value; },
|
||||
[&](const constant::Scalar<bool>* scalar) {
|
||||
out << (scalar->ValueAs<bool>() ? "true" : "false");
|
||||
},
|
||||
[&](const constant::Splat* splat) {
|
||||
out << splat->Type()->FriendlyName(st) << "(";
|
||||
emit(splat->Index(0));
|
||||
out << ")";
|
||||
},
|
||||
[&](const constant::Composite* composite) {
|
||||
out << composite->Type()->FriendlyName(st) << "(";
|
||||
for (const auto* elem : composite->elements) {
|
||||
if (elem != composite->elements[0]) {
|
||||
out << ", ";
|
||||
}
|
||||
emit(elem);
|
||||
}
|
||||
out << ")";
|
||||
});
|
||||
};
|
||||
emit(value);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,100 +16,29 @@
|
|||
#define SRC_TINT_IR_CONSTANT_H_
|
||||
|
||||
#include <ostream>
|
||||
#include <variant>
|
||||
|
||||
#include "src/tint/constant/value.h"
|
||||
#include "src/tint/ir/value.h"
|
||||
#include "src/tint/number.h"
|
||||
#include "src/tint/symbol_table.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
/// Constant in the IR. The constant can be one of several types these include, but aren't limited
|
||||
/// to, `f32`, `u32`, `bool`. The type of the constant determines the type of data stored.
|
||||
/// Constant in the IR.
|
||||
class Constant : public Castable<Constant, Value> {
|
||||
public:
|
||||
/// The type of the constant
|
||||
enum class Kind {
|
||||
/// A f32 constant
|
||||
kF32,
|
||||
/// A f16 constant
|
||||
kF16,
|
||||
/// An i32 constant
|
||||
kI32,
|
||||
/// A u32 constant
|
||||
kU32,
|
||||
/// A boolean constant
|
||||
kBool,
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
/// @param b the `bool` constant to store in the constant
|
||||
explicit Constant(bool b);
|
||||
|
||||
/// Constructor
|
||||
/// @param f the `f32` constant to store in the constant
|
||||
explicit Constant(f32 f);
|
||||
|
||||
/// Constructor
|
||||
/// @param f the `f16` constant to store in the constant
|
||||
explicit Constant(f16 f);
|
||||
|
||||
/// Constructor
|
||||
/// @param u the `u32` constant to store in the constant
|
||||
explicit Constant(u32 u);
|
||||
|
||||
/// Constructor
|
||||
/// @param i the `i32` constant to store in the constant
|
||||
explicit Constant(i32 i);
|
||||
|
||||
/// Destructor
|
||||
/// @param val the value stored in the constant
|
||||
explicit Constant(const constant::Value* val);
|
||||
~Constant() override;
|
||||
|
||||
Constant(const Constant&) = delete;
|
||||
Constant(Constant&&) = delete;
|
||||
|
||||
Constant& operator=(const Constant&) = delete;
|
||||
Constant& operator=(Constant&&) = delete;
|
||||
|
||||
/// @returns true if this is a f32 constant
|
||||
bool IsF32() const { return kind_ == Kind::kF32; }
|
||||
/// @returns true if this is a f16 constant
|
||||
bool IsF16() const { return kind_ == Kind::kF16; }
|
||||
/// @returns true if this is an i32 constant
|
||||
bool IsI32() const { return kind_ == Kind::kI32; }
|
||||
/// @returns true if this is a u32 constant
|
||||
bool IsU32() const { return kind_ == Kind::kU32; }
|
||||
/// @returns true if this is a bool constant
|
||||
bool IsBool() const { return kind_ == Kind::kBool; }
|
||||
|
||||
/// @returns the kind of constant
|
||||
Kind GetKind() const { return kind_; }
|
||||
|
||||
/// @returns the constant data as a `f32`.
|
||||
/// @note, must only be called if `IsF32()` is true
|
||||
f32 AsF32() const { return std::get<f32>(data_); }
|
||||
/// @returns the constant data as a `f16`.
|
||||
/// @note, must only be called if `IsF16()` is true
|
||||
f16 AsF16() const { return std::get<f16>(data_); }
|
||||
/// @returns the constant data as an `i32`.
|
||||
/// @note, must only be called if `IsI32()` is true
|
||||
i32 AsI32() const { return std::get<i32>(data_); }
|
||||
/// @returns the constant data as a `u32`.
|
||||
/// @note, must only be called if `IsU32()` is true
|
||||
u32 AsU32() const { return std::get<u32>(data_); }
|
||||
/// @returns the constant data as a `bool`.
|
||||
/// @note, must only be called if `IsBool()` is true
|
||||
bool AsBool() const { return std::get<bool>(data_); }
|
||||
|
||||
/// Write the constant to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @param st the symbol table
|
||||
/// @returns the stream
|
||||
std::ostream& ToString(std::ostream& out) const override;
|
||||
std::ostream& ToString(std::ostream& out, const SymbolTable& st) const override;
|
||||
|
||||
private:
|
||||
/// The type of data stored in this constant
|
||||
Kind kind_;
|
||||
/// The data stored in the constant
|
||||
std::variant<f32, f16, u32, i32, bool> data_;
|
||||
/// The constants value
|
||||
const constant::Value* const value;
|
||||
};
|
||||
|
||||
} // namespace tint::ir
|
||||
|
|
|
@ -29,17 +29,17 @@ TEST_F(IR_ConstantTest, f32) {
|
|||
|
||||
std::stringstream str;
|
||||
|
||||
auto* val = b.builder.Constant(1.2_f);
|
||||
EXPECT_EQ(1.2_f, val->AsF32());
|
||||
auto* c = b.builder.Constant(1.2_f);
|
||||
EXPECT_EQ(1.2_f, c->value->As<constant::Scalar<f32>>()->ValueAs<f32>());
|
||||
|
||||
val->ToString(str);
|
||||
EXPECT_EQ("1.200000", str.str());
|
||||
c->ToString(str, program->Symbols());
|
||||
EXPECT_EQ("1.2", str.str());
|
||||
|
||||
EXPECT_TRUE(val->IsF32());
|
||||
EXPECT_FALSE(val->IsF16());
|
||||
EXPECT_FALSE(val->IsI32());
|
||||
EXPECT_FALSE(val->IsU32());
|
||||
EXPECT_FALSE(val->IsBool());
|
||||
EXPECT_TRUE(c->value->Is<constant::Scalar<f32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<i32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<u32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<bool>>());
|
||||
}
|
||||
|
||||
TEST_F(IR_ConstantTest, f16) {
|
||||
|
@ -47,17 +47,17 @@ TEST_F(IR_ConstantTest, f16) {
|
|||
|
||||
std::stringstream str;
|
||||
|
||||
auto* val = b.builder.Constant(1.1_h);
|
||||
EXPECT_EQ(1.1_h, val->AsF16());
|
||||
auto* c = b.builder.Constant(1.1_h);
|
||||
EXPECT_EQ(1.1_h, c->value->As<constant::Scalar<f16>>()->ValueAs<f16>());
|
||||
|
||||
val->ToString(str);
|
||||
EXPECT_EQ("1.099609", str.str());
|
||||
c->ToString(str, program->Symbols());
|
||||
EXPECT_EQ("1.09961", str.str());
|
||||
|
||||
EXPECT_FALSE(val->IsF32());
|
||||
EXPECT_TRUE(val->IsF16());
|
||||
EXPECT_FALSE(val->IsI32());
|
||||
EXPECT_FALSE(val->IsU32());
|
||||
EXPECT_FALSE(val->IsBool());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
||||
EXPECT_TRUE(c->value->Is<constant::Scalar<f16>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<i32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<u32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<bool>>());
|
||||
}
|
||||
|
||||
TEST_F(IR_ConstantTest, i32) {
|
||||
|
@ -65,17 +65,17 @@ TEST_F(IR_ConstantTest, i32) {
|
|||
|
||||
std::stringstream str;
|
||||
|
||||
auto* val = b.builder.Constant(1_i);
|
||||
EXPECT_EQ(1_i, val->AsI32());
|
||||
auto* c = b.builder.Constant(1_i);
|
||||
EXPECT_EQ(1_i, c->value->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
val->ToString(str);
|
||||
c->ToString(str, program->Symbols());
|
||||
EXPECT_EQ("1", str.str());
|
||||
|
||||
EXPECT_FALSE(val->IsF32());
|
||||
EXPECT_FALSE(val->IsF16());
|
||||
EXPECT_TRUE(val->IsI32());
|
||||
EXPECT_FALSE(val->IsU32());
|
||||
EXPECT_FALSE(val->IsBool());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
|
||||
EXPECT_TRUE(c->value->Is<constant::Scalar<i32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<u32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<bool>>());
|
||||
}
|
||||
|
||||
TEST_F(IR_ConstantTest, u32) {
|
||||
|
@ -83,17 +83,17 @@ TEST_F(IR_ConstantTest, u32) {
|
|||
|
||||
std::stringstream str;
|
||||
|
||||
auto* val = b.builder.Constant(2_u);
|
||||
EXPECT_EQ(2_u, val->AsU32());
|
||||
auto* c = b.builder.Constant(2_u);
|
||||
EXPECT_EQ(2_u, c->value->As<constant::Scalar<u32>>()->ValueAs<u32>());
|
||||
|
||||
val->ToString(str);
|
||||
c->ToString(str, program->Symbols());
|
||||
EXPECT_EQ("2", str.str());
|
||||
|
||||
EXPECT_FALSE(val->IsF32());
|
||||
EXPECT_FALSE(val->IsF16());
|
||||
EXPECT_FALSE(val->IsI32());
|
||||
EXPECT_TRUE(val->IsU32());
|
||||
EXPECT_FALSE(val->IsBool());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<i32>>());
|
||||
EXPECT_TRUE(c->value->Is<constant::Scalar<u32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<bool>>());
|
||||
}
|
||||
|
||||
TEST_F(IR_ConstantTest, bool) {
|
||||
|
@ -101,24 +101,24 @@ TEST_F(IR_ConstantTest, bool) {
|
|||
|
||||
std::stringstream str;
|
||||
|
||||
auto* val = b.builder.Constant(false);
|
||||
EXPECT_FALSE(val->AsBool());
|
||||
auto* c = b.builder.Constant(false);
|
||||
EXPECT_FALSE(c->value->As<constant::Scalar<bool>>()->ValueAs<bool>());
|
||||
|
||||
val->ToString(str);
|
||||
c->ToString(str, program->Symbols());
|
||||
EXPECT_EQ("false", str.str());
|
||||
|
||||
str.str("");
|
||||
val = b.builder.Constant(true);
|
||||
EXPECT_TRUE(val->AsBool());
|
||||
c = b.builder.Constant(true);
|
||||
EXPECT_TRUE(c->value->As<constant::Scalar<bool>>()->ValueAs<bool>());
|
||||
|
||||
val->ToString(str);
|
||||
c->ToString(str, program->Symbols());
|
||||
EXPECT_EQ("true", str.str());
|
||||
|
||||
EXPECT_FALSE(val->IsF32());
|
||||
EXPECT_FALSE(val->IsF16());
|
||||
EXPECT_FALSE(val->IsI32());
|
||||
EXPECT_FALSE(val->IsU32());
|
||||
EXPECT_TRUE(val->IsBool());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<i32>>());
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<u32>>());
|
||||
EXPECT_TRUE(c->value->Is<constant::Scalar<bool>>());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -50,7 +50,7 @@ class ScopedIndent {
|
|||
|
||||
} // namespace
|
||||
|
||||
Disassembler::Disassembler() = default;
|
||||
Disassembler::Disassembler(const Module& mod) : mod_(mod) {}
|
||||
|
||||
Disassembler::~Disassembler() = default;
|
||||
|
||||
|
@ -63,7 +63,7 @@ std::ostream& Disassembler::Indent() {
|
|||
|
||||
void Disassembler::EmitBlockInstructions(const Block* b) {
|
||||
for (const auto* instr : b->instructions) {
|
||||
instr->ToString(out_) << std::endl;
|
||||
instr->ToString(out_, mod_.program->Symbols()) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,8 +144,8 @@ void Disassembler::Walk(const FlowNode* node) {
|
|||
[&](const ir::Terminator*) { Indent() << "Function end" << std::endl; });
|
||||
}
|
||||
|
||||
std::string Disassembler::Disassemble(const Module& mod) {
|
||||
for (const auto* func : mod.functions) {
|
||||
std::string Disassembler::Disassemble() {
|
||||
for (const auto* func : mod_.functions) {
|
||||
Walk(func);
|
||||
}
|
||||
return out_.str();
|
||||
|
|
|
@ -28,13 +28,13 @@ namespace tint::ir {
|
|||
class Disassembler {
|
||||
public:
|
||||
/// Constructor
|
||||
Disassembler();
|
||||
/// @param mod the module
|
||||
explicit Disassembler(const Module& mod);
|
||||
~Disassembler();
|
||||
|
||||
/// Returns the module as a string
|
||||
/// @param mod the module to emit
|
||||
/// @returns the string representation of the module
|
||||
std::string Disassemble(const Module& mod);
|
||||
std::string Disassemble();
|
||||
|
||||
/// Writes the block instructions to the stream
|
||||
/// @param b the block containing the instructions
|
||||
|
@ -47,6 +47,7 @@ class Disassembler {
|
|||
std::ostream& Indent();
|
||||
void Walk(const FlowNode* node);
|
||||
|
||||
const Module& mod_;
|
||||
std::stringstream out_;
|
||||
std::unordered_set<const FlowNode*> visited_;
|
||||
std::unordered_set<const FlowNode*> stop_nodes_;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <ostream>
|
||||
|
||||
#include "src/tint/castable.h"
|
||||
#include "src/tint/symbol_table.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
|
@ -34,8 +35,9 @@ class Instruction : public Castable<Instruction> {
|
|||
|
||||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @param st the symbol table
|
||||
/// @returns the stream
|
||||
virtual std::ostream& ToString(std::ostream& out) const = 0;
|
||||
virtual std::ostream& ToString(std::ostream& out, const SymbolTable& st) const = 0;
|
||||
|
||||
protected:
|
||||
/// Constructor
|
||||
|
|
|
@ -44,7 +44,7 @@ TEST_F(IR_BinaryTest, CreateAnd) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 & 2");
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ TEST_F(IR_BinaryTest, CreateOr) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 | 2");
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ TEST_F(IR_BinaryTest, CreateXor) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 ^ 2");
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ TEST_F(IR_BinaryTest, CreateLogicalAnd) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 && 2");
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ TEST_F(IR_BinaryTest, CreateLogicalOr) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 || 2");
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ TEST_F(IR_BinaryTest, CreateEqual) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 == 2");
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ TEST_F(IR_BinaryTest, CreateNotEqual) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 != 2");
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ TEST_F(IR_BinaryTest, CreateLessThan) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 < 2");
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ TEST_F(IR_BinaryTest, CreateGreaterThan) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 > 2");
|
||||
}
|
||||
|
||||
|
@ -281,7 +281,7 @@ TEST_F(IR_BinaryTest, CreateLessThanEqual) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 <= 2");
|
||||
}
|
||||
|
||||
|
@ -308,7 +308,7 @@ TEST_F(IR_BinaryTest, CreateGreaterThanEqual) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 >= 2");
|
||||
}
|
||||
|
||||
|
@ -334,7 +334,7 @@ TEST_F(IR_BinaryTest, CreateShiftLeft) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 << 2");
|
||||
}
|
||||
|
||||
|
@ -361,7 +361,7 @@ TEST_F(IR_BinaryTest, CreateShiftRight) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 >> 2");
|
||||
}
|
||||
|
||||
|
@ -387,7 +387,7 @@ TEST_F(IR_BinaryTest, CreateAdd) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 + 2");
|
||||
}
|
||||
|
||||
|
@ -413,7 +413,7 @@ TEST_F(IR_BinaryTest, CreateSubtract) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 - 2");
|
||||
}
|
||||
|
||||
|
@ -439,7 +439,7 @@ TEST_F(IR_BinaryTest, CreateMultiply) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 * 2");
|
||||
}
|
||||
|
||||
|
@ -465,7 +465,7 @@ TEST_F(IR_BinaryTest, CreateDivide) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 / 2");
|
||||
}
|
||||
|
||||
|
@ -491,7 +491,7 @@ TEST_F(IR_BinaryTest, CreateModulo) {
|
|||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str);
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 % 2");
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/constant/value.h"
|
||||
#include "src/tint/ir/function.h"
|
||||
#include "src/tint/ir/instruction.h"
|
||||
#include "src/tint/ir/value.h"
|
||||
#include "src/tint/type/manager.h"
|
||||
#include "src/tint/utils/block_allocator.h"
|
||||
#include "src/tint/utils/result.h"
|
||||
#include "src/tint/utils/vector.h"
|
||||
|
@ -68,6 +70,8 @@ class Module {
|
|||
|
||||
/// The flow node allocator
|
||||
utils::BlockAllocator<FlowNode> flow_nodes;
|
||||
/// The constant allocator
|
||||
utils::BlockAllocator<constant::Value> constants;
|
||||
/// The value allocator
|
||||
utils::BlockAllocator<Value> values;
|
||||
/// The instruction allocator
|
||||
|
@ -80,6 +84,9 @@ class Module {
|
|||
|
||||
/// The source ast::Program this module was constucted from
|
||||
const Program* program;
|
||||
|
||||
/// The type manager for the module
|
||||
type::Manager types;
|
||||
};
|
||||
|
||||
} // namespace tint::ir
|
||||
|
|
|
@ -24,7 +24,7 @@ Temp::Temp(Id id) : id_(id) {}
|
|||
|
||||
Temp::~Temp() = default;
|
||||
|
||||
std::ostream& Temp::ToString(std::ostream& out) const {
|
||||
std::ostream& Temp::ToString(std::ostream& out, const SymbolTable&) const {
|
||||
out << "%" << std::to_string(AsId());
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <ostream>
|
||||
|
||||
#include "src/tint/ir/value.h"
|
||||
#include "src/tint/symbol_table.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
|
@ -45,8 +46,9 @@ class Temp : public Castable<Temp, Value> {
|
|||
|
||||
/// Write the temp to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @param st the symbol table
|
||||
/// @returns the stream
|
||||
std::ostream& ToString(std::ostream& out) const override;
|
||||
std::ostream& ToString(std::ostream& out, const SymbolTable& st) const override;
|
||||
|
||||
private:
|
||||
Id id_ = 0;
|
||||
|
|
|
@ -33,7 +33,7 @@ TEST_F(IR_TempTest, id) {
|
|||
auto* val = b.builder.Temp();
|
||||
EXPECT_EQ(4u, val->AsId());
|
||||
|
||||
val->ToString(str);
|
||||
val->ToString(str, program->Symbols());
|
||||
EXPECT_EQ("%4", str.str());
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "gtest/gtest.h"
|
||||
#include "src/tint/ir/builder_impl.h"
|
||||
#include "src/tint/ir/disassembler.h"
|
||||
#include "src/tint/number.h"
|
||||
#include "src/tint/program_builder.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
@ -41,19 +42,29 @@ class TestHelperBase : public BASE, public ProgramBuilder {
|
|||
if (gen_) {
|
||||
return *gen_;
|
||||
}
|
||||
program = std::make_unique<Program>(std::move(*this));
|
||||
diag::Formatter formatter;
|
||||
|
||||
program = std::make_unique<Program>(std::move(*this));
|
||||
[&]() { ASSERT_TRUE(program->IsValid()) << formatter.format(program->Diagnostics()); }();
|
||||
gen_ = std::make_unique<BuilderImpl>(program.get());
|
||||
return *gen_;
|
||||
}
|
||||
|
||||
/// Injects a flow block into the builder
|
||||
/// @returns the injected block
|
||||
ir::Block* InjectFlowBlock() {
|
||||
auto* block = gen_->builder.CreateBlock();
|
||||
gen_->current_flow_block = block;
|
||||
return block;
|
||||
}
|
||||
|
||||
/// Creates a BuilderImpl without an originating program. This is used for testing the
|
||||
/// expressions which don't require the full builder implementation. The current flow block
|
||||
/// is initialized with an empty block.
|
||||
/// @returns the BuilderImpl for testing.
|
||||
BuilderImpl& CreateEmptyBuilder() {
|
||||
gen_ = std::make_unique<BuilderImpl>(nullptr);
|
||||
program = std::make_unique<Program>();
|
||||
gen_ = std::make_unique<BuilderImpl>(program.get());
|
||||
gen_->current_flow_block = gen_->builder.CreateBlock();
|
||||
return *gen_;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <ostream>
|
||||
|
||||
#include "src/tint/castable.h"
|
||||
#include "src/tint/symbol_table.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
|
@ -35,8 +36,9 @@ class Value : public Castable<Value> {
|
|||
|
||||
/// Write the value to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @param st the symbol table
|
||||
/// @returns the stream
|
||||
virtual std::ostream& ToString(std::ostream& out) const = 0;
|
||||
virtual std::ostream& ToString(std::ostream& out, const SymbolTable& st) const = 0;
|
||||
|
||||
protected:
|
||||
/// Constructor
|
||||
|
|
Loading…
Reference in New Issue