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>
diff --git a/src/tint/cmd/main.cc b/src/tint/cmd/main.cc
index ae2e2e2..fd67617 100644
--- a/src/tint/cmd/main.cc
+++ b/src/tint/cmd/main.cc
@@ -1344,8 +1344,8 @@
} 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);
diff --git a/src/tint/ir/binary.cc b/src/tint/ir/binary.cc
index 1a35b61..ccb679b 100644
--- a/src/tint/ir/binary.cc
+++ b/src/tint/ir/binary.cc
@@ -28,9 +28,9 @@
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 @@
break;
}
out << " ";
- rhs_->ToString(out);
+ rhs_->ToString(out, st);
return out;
}
diff --git a/src/tint/ir/binary.h b/src/tint/ir/binary.h
index 755dd9c..0f7fe57 100644
--- a/src/tint/ir/binary.h
+++ b/src/tint/ir/binary.h
@@ -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 @@
/// 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_;
diff --git a/src/tint/ir/binary_test.cc b/src/tint/ir/binary_test.cc
index 81d0ada..f90661b 100644
--- a/src/tint/ir/binary_test.cc
+++ b/src/tint/ir/binary_test.cc
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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");
}
diff --git a/src/tint/ir/builder.h b/src/tint/ir/builder.h
index ceabfa6b..ca21b8d 100644
--- a/src/tint/ir/builder.h
+++ b/src/tint/ir/builder.h
@@ -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 @@
/// @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()); }
diff --git a/src/tint/ir/builder_impl.cc b/src/tint/ir/builder_impl.cc
index 042a7d5..afa56f5 100644
--- a/src/tint/ir/builder_impl.cc
+++ b/src/tint/ir/builder_impl.cc
@@ -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::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) {
diff --git a/src/tint/ir/builder_impl_test.cc b/src/tint/ir/builder_impl_test.cc
index 79e6e3f..0600a15 100644
--- a/src/tint/ir/builder_impl_test.cc
+++ b/src/tint/ir/builder_impl_test.cc
@@ -102,9 +102,9 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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, 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
)");
}
diff --git a/src/tint/ir/constant.cc b/src/tint/ir/constant.cc
index 0138190..98a5d3d 100644
--- a/src/tint/ir/constant.cc
+++ b/src/tint/ir/constant.cc
@@ -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;
}
diff --git a/src/tint/ir/constant.h b/src/tint/ir/constant.h
index 23eeb02..c5ee079 100644
--- a/src/tint/ir/constant.h
+++ b/src/tint/ir/constant.h
@@ -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
diff --git a/src/tint/ir/constant_test.cc b/src/tint/ir/constant_test.cc
index b20b424..87eec65 100644
--- a/src/tint/ir/constant_test.cc
+++ b/src/tint/ir/constant_test.cc
@@ -29,17 +29,17 @@
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 @@
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 @@
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 @@
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 @@
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
diff --git a/src/tint/ir/disassembler.cc b/src/tint/ir/disassembler.cc
index d8ee4ba..37f294c 100644
--- a/src/tint/ir/disassembler.cc
+++ b/src/tint/ir/disassembler.cc
@@ -50,7 +50,7 @@
} // namespace
-Disassembler::Disassembler() = default;
+Disassembler::Disassembler(const Module& mod) : mod_(mod) {}
Disassembler::~Disassembler() = default;
@@ -63,7 +63,7 @@
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 @@
[&](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();
diff --git a/src/tint/ir/disassembler.h b/src/tint/ir/disassembler.h
index e24524a..46b4ffd 100644
--- a/src/tint/ir/disassembler.h
+++ b/src/tint/ir/disassembler.h
@@ -28,13 +28,13 @@
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 @@
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_;
diff --git a/src/tint/ir/instruction.h b/src/tint/ir/instruction.h
index 8b68465..82842ba 100644
--- a/src/tint/ir/instruction.h
+++ b/src/tint/ir/instruction.h
@@ -18,6 +18,7 @@
#include <ostream>
#include "src/tint/castable.h"
+#include "src/tint/symbol_table.h"
namespace tint::ir {
@@ -34,8 +35,9 @@
/// 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
diff --git a/src/tint/ir/instruction_test.cc b/src/tint/ir/instruction_test.cc
index 08302ed..c9307f0 100644
--- a/src/tint/ir/instruction_test.cc
+++ b/src/tint/ir/instruction_test.cc
@@ -44,7 +44,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- instr->ToString(str);
+ instr->ToString(str, program->Symbols());
EXPECT_EQ(str.str(), "%42 = 4 % 2");
}
diff --git a/src/tint/ir/module.h b/src/tint/ir/module.h
index d95a13e..1ed9ea9 100644
--- a/src/tint/ir/module.h
+++ b/src/tint/ir/module.h
@@ -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 @@
/// 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 @@
/// The source ast::Program this module was constucted from
const Program* program;
+
+ /// The type manager for the module
+ type::Manager types;
};
} // namespace tint::ir
diff --git a/src/tint/ir/temp.cc b/src/tint/ir/temp.cc
index 30efb86..afd0921 100644
--- a/src/tint/ir/temp.cc
+++ b/src/tint/ir/temp.cc
@@ -24,7 +24,7 @@
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;
}
diff --git a/src/tint/ir/temp.h b/src/tint/ir/temp.h
index c621b5c..2db81f3 100644
--- a/src/tint/ir/temp.h
+++ b/src/tint/ir/temp.h
@@ -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 @@
/// 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;
diff --git a/src/tint/ir/temp_test.cc b/src/tint/ir/temp_test.cc
index 1dcae13..6b79a51 100644
--- a/src/tint/ir/temp_test.cc
+++ b/src/tint/ir/temp_test.cc
@@ -33,7 +33,7 @@
auto* val = b.builder.Temp();
EXPECT_EQ(4u, val->AsId());
- val->ToString(str);
+ val->ToString(str, program->Symbols());
EXPECT_EQ("%4", str.str());
}
diff --git a/src/tint/ir/test_helper.h b/src/tint/ir/test_helper.h
index 10694ee..e3d66cf 100644
--- a/src/tint/ir/test_helper.h
+++ b/src/tint/ir/test_helper.h
@@ -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 @@
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_;
}
diff --git a/src/tint/ir/value.h b/src/tint/ir/value.h
index 9c41f52..6dffc3e 100644
--- a/src/tint/ir/value.h
+++ b/src/tint/ir/value.h
@@ -18,6 +18,7 @@
#include <ostream>
#include "src/tint/castable.h"
+#include "src/tint/symbol_table.h"
namespace tint::ir {
@@ -35,8 +36,9 @@
/// 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