[ir] Make ir::Instruction a ir::Value.
This CL removes the `ir::Runtime` and inherits `ir::Instruction` from `ir::Value`. This means that any `Value` can be an `Instruction`. The instruction id is used for debugging purposes. Bug: tint:1895 Change-Id: I2b79cd6721268712d78a47d383a30f82aa3aa07e Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/129660 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
5e4aad952e
commit
f00679fd72
|
@ -1160,8 +1160,6 @@ libtint_source_set("libtint_ir_src") {
|
|||
"ir/loop.h",
|
||||
"ir/module.cc",
|
||||
"ir/module.h",
|
||||
"ir/runtime.cc",
|
||||
"ir/runtime.h",
|
||||
"ir/store.cc",
|
||||
"ir/store.h",
|
||||
"ir/switch.cc",
|
||||
|
@ -2122,7 +2120,6 @@ if (tint_build_unittests) {
|
|||
"ir/builder_impl_test.cc",
|
||||
"ir/constant_test.cc",
|
||||
"ir/discard_test.cc",
|
||||
"ir/runtime_test.cc",
|
||||
"ir/store_test.cc",
|
||||
"ir/test_helper.h",
|
||||
"ir/unary_test.cc",
|
||||
|
|
|
@ -738,8 +738,6 @@ if(${TINT_BUILD_IR})
|
|||
ir/loop.h
|
||||
ir/module.cc
|
||||
ir/module.h
|
||||
ir/runtime.cc
|
||||
ir/runtime.h
|
||||
ir/store.cc
|
||||
ir/store.h
|
||||
ir/switch.cc
|
||||
|
@ -1425,7 +1423,6 @@ if(TINT_BUILD_TESTS)
|
|||
ir/builder_impl_test.cc
|
||||
ir/constant_test.cc
|
||||
ir/discard_test.cc
|
||||
ir/runtime_test.cc
|
||||
ir/store_test.cc
|
||||
ir/test_helper.h
|
||||
ir/unary_test.cc
|
||||
|
|
|
@ -19,8 +19,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Binary);
|
|||
|
||||
namespace tint::ir {
|
||||
|
||||
Binary::Binary(Kind kind, Value* result, Value* lhs, Value* rhs)
|
||||
: Base(result), kind_(kind), lhs_(lhs), rhs_(rhs) {
|
||||
Binary::Binary(uint32_t id, Kind kind, const type::Type* ty, Value* lhs, Value* rhs)
|
||||
: Base(id, ty), kind_(kind), lhs_(lhs), rhs_(rhs) {
|
||||
TINT_ASSERT(IR, lhs_);
|
||||
TINT_ASSERT(IR, rhs_);
|
||||
lhs_->AddUsage(this);
|
||||
|
@ -29,9 +29,9 @@ Binary::Binary(Kind kind, Value* result, Value* lhs, Value* rhs)
|
|||
|
||||
Binary::~Binary() = default;
|
||||
|
||||
utils::StringStream& Binary::ToString(utils::StringStream& out) const {
|
||||
Result()->ToString(out) << " = ";
|
||||
lhs_->ToString(out) << " ";
|
||||
utils::StringStream& Binary::ToInstruction(utils::StringStream& out) const {
|
||||
ToValue(out) << " = ";
|
||||
lhs_->ToValue(out) << " ";
|
||||
|
||||
switch (GetKind()) {
|
||||
case Binary::Kind::kAdd:
|
||||
|
@ -90,7 +90,7 @@ utils::StringStream& Binary::ToString(utils::StringStream& out) const {
|
|||
break;
|
||||
}
|
||||
out << " ";
|
||||
rhs_->ToString(out);
|
||||
rhs_->ToValue(out);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -51,11 +51,12 @@ class Binary : public utils::Castable<Binary, Instruction> {
|
|||
};
|
||||
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param kind the kind of binary instruction
|
||||
/// @param result the result value
|
||||
/// @param type the result type
|
||||
/// @param lhs the lhs of the instruction
|
||||
/// @param rhs the rhs of the instruction
|
||||
Binary(Kind kind, Value* result, Value* lhs, Value* rhs);
|
||||
Binary(uint32_t id, Kind kind, const type::Type* type, Value* lhs, Value* rhs);
|
||||
Binary(const Binary& inst) = delete;
|
||||
Binary(Binary&& inst) = delete;
|
||||
~Binary() override;
|
||||
|
@ -75,7 +76,7 @@ class Binary : public utils::Castable<Binary, Instruction> {
|
|||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToString(utils::StringStream& out) const override;
|
||||
utils::StringStream& ToInstruction(utils::StringStream& out) const override;
|
||||
|
||||
private:
|
||||
Kind kind_;
|
||||
|
|
|
@ -20,21 +20,18 @@ 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_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.And(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i),
|
||||
b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kAnd);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
ASSERT_NE(inst->Result()->Type(), nullptr);
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
ASSERT_NE(inst->Type(), nullptr);
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
|
@ -47,22 +44,19 @@ TEST_F(IR_InstructionTest, CreateAnd) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 & 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = 4 & 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateOr) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.Or(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i),
|
||||
b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kOr);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -74,22 +68,19 @@ TEST_F(IR_InstructionTest, CreateOr) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 | 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = 4 | 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateXor) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.Xor(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i),
|
||||
b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kXor);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -101,22 +92,19 @@ TEST_F(IR_InstructionTest, CreateXor) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 ^ 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = 4 ^ 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.LogicalAnd(b.builder.ir.types.Get<type::Bool>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kLogicalAnd);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -128,22 +116,19 @@ TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 && 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(bool) = 4 && 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.LogicalOr(b.builder.ir.types.Get<type::Bool>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kLogicalOr);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -155,22 +140,19 @@ TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 || 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(bool) = 4 || 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateEqual) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.Equal(b.builder.ir.types.Get<type::Bool>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kEqual);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -182,22 +164,19 @@ TEST_F(IR_InstructionTest, CreateEqual) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 == 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(bool) = 4 == 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateNotEqual) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.NotEqual(b.builder.ir.types.Get<type::Bool>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kNotEqual);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -209,22 +188,19 @@ TEST_F(IR_InstructionTest, CreateNotEqual) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 != 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(bool) = 4 != 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateLessThan) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.LessThan(b.builder.ir.types.Get<type::Bool>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kLessThan);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -236,22 +212,19 @@ TEST_F(IR_InstructionTest, CreateLessThan) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 < 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(bool) = 4 < 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.GreaterThan(b.builder.ir.types.Get<type::Bool>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kGreaterThan);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -263,22 +236,19 @@ TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 > 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(bool) = 4 > 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.LessThanEqual(b.builder.ir.types.Get<type::Bool>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kLessThanEqual);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -290,22 +260,19 @@ TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 <= 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(bool) = 4 <= 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.GreaterThanEqual(b.builder.ir.types.Get<type::Bool>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kGreaterThanEqual);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -317,22 +284,19 @@ TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 >= 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(bool) = 4 >= 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.ShiftLeft(b.builder.ir.types.Get<type::I32>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kShiftLeft);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -344,22 +308,19 @@ TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 << 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = 4 << 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateShiftRight) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.ShiftRight(b.builder.ir.types.Get<type::I32>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kShiftRight);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -371,22 +332,19 @@ TEST_F(IR_InstructionTest, CreateShiftRight) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 >> 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = 4 >> 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateAdd) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.Add(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i),
|
||||
b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kAdd);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -398,22 +356,19 @@ TEST_F(IR_InstructionTest, CreateAdd) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 + 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = 4 + 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateSubtract) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.Subtract(b.builder.ir.types.Get<type::I32>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kSubtract);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -425,22 +380,19 @@ TEST_F(IR_InstructionTest, CreateSubtract) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 - 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = 4 - 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateMultiply) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.Multiply(b.builder.ir.types.Get<type::I32>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kMultiply);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -452,22 +404,19 @@ TEST_F(IR_InstructionTest, CreateMultiply) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 * 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = 4 * 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateDivide) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.Divide(b.builder.ir.types.Get<type::I32>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kDivide);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -479,22 +428,19 @@ TEST_F(IR_InstructionTest, CreateDivide) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 / 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = 4 / 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateModulo) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.Modulo(b.builder.ir.types.Get<type::I32>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Binary>());
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kModulo);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->LHS()->Is<Constant>());
|
||||
auto lhs = inst->LHS()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
|
@ -506,23 +452,17 @@ TEST_F(IR_InstructionTest, CreateModulo) {
|
|||
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 % 2");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = 4 % 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, Binary_Usage) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.And(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i),
|
||||
b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kAnd);
|
||||
|
||||
ASSERT_NE(inst->Result(), nullptr);
|
||||
ASSERT_EQ(inst->Result()->Usage().Length(), 1u);
|
||||
EXPECT_EQ(inst->Result()->Usage()[0], inst);
|
||||
|
||||
ASSERT_NE(inst->LHS(), nullptr);
|
||||
ASSERT_EQ(inst->LHS()->Usage().Length(), 1u);
|
||||
EXPECT_EQ(inst->LHS()->Usage()[0], inst);
|
||||
|
@ -534,18 +474,10 @@ TEST_F(IR_InstructionTest, Binary_Usage) {
|
|||
|
||||
TEST_F(IR_InstructionTest, Binary_Usage_DuplicateValue) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
auto val = b.builder.Constant(4_i);
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.And(b.builder.ir.types.Get<type::I32>(), val, val);
|
||||
|
||||
EXPECT_EQ(inst->GetKind(), Binary::Kind::kAnd);
|
||||
|
||||
ASSERT_NE(inst->Result(), nullptr);
|
||||
ASSERT_EQ(inst->Result()->Usage().Length(), 1u);
|
||||
EXPECT_EQ(inst->Result()->Usage()[0], inst);
|
||||
|
||||
ASSERT_EQ(inst->LHS(), inst->RHS());
|
||||
|
||||
ASSERT_NE(inst->LHS(), nullptr);
|
||||
|
|
|
@ -19,17 +19,16 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Bitcast);
|
|||
|
||||
namespace tint::ir {
|
||||
|
||||
Bitcast::Bitcast(Value* result, Value* val) : Base(result), val_(val) {
|
||||
Bitcast::Bitcast(uint32_t id, const type::Type* type, Value* val) : Base(id, type), val_(val) {
|
||||
TINT_ASSERT(IR, val_);
|
||||
val_->AddUsage(this);
|
||||
}
|
||||
|
||||
Bitcast::~Bitcast() = default;
|
||||
|
||||
utils::StringStream& Bitcast::ToString(utils::StringStream& out) const {
|
||||
Result()->ToString(out);
|
||||
out << " = bitcast(";
|
||||
val_->ToString(out);
|
||||
utils::StringStream& Bitcast::ToInstruction(utils::StringStream& out) const {
|
||||
ToValue(out) << " = bitcast(";
|
||||
val_->ToValue(out);
|
||||
out << ")";
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -25,9 +25,10 @@ namespace tint::ir {
|
|||
class Bitcast : public utils::Castable<Bitcast, Instruction> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param result the result value
|
||||
/// @param id the instruction id
|
||||
/// @param type the result type
|
||||
/// @param val the value being bitcast
|
||||
Bitcast(Value* result, Value* val);
|
||||
Bitcast(uint32_t id, const type::Type* type, Value* val);
|
||||
Bitcast(const Bitcast& inst) = delete;
|
||||
Bitcast(Bitcast&& inst) = delete;
|
||||
~Bitcast() override;
|
||||
|
@ -41,7 +42,7 @@ class Bitcast : public utils::Castable<Bitcast, Instruction> {
|
|||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToString(utils::StringStream& out) const override;
|
||||
utils::StringStream& ToInstruction(utils::StringStream& out) const override;
|
||||
|
||||
private:
|
||||
Value* val_ = nullptr;
|
||||
|
|
|
@ -20,19 +20,16 @@ namespace tint::ir {
|
|||
namespace {
|
||||
|
||||
using namespace tint::number_suffixes; // NOLINT
|
||||
//
|
||||
|
||||
using IR_InstructionTest = TestHelper;
|
||||
|
||||
TEST_F(IR_InstructionTest, Bitcast) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst =
|
||||
b.builder.Bitcast(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i));
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
ASSERT_NE(inst->Result()->Type(), nullptr);
|
||||
ASSERT_TRUE(inst->Is<ir::Bitcast>());
|
||||
ASSERT_NE(inst->Type(), nullptr);
|
||||
|
||||
ASSERT_TRUE(inst->Val()->Is<Constant>());
|
||||
auto val = inst->Val()->As<Constant>()->value;
|
||||
|
@ -40,21 +37,15 @@ TEST_F(IR_InstructionTest, Bitcast) {
|
|||
EXPECT_EQ(4_i, val->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = bitcast(4)");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = bitcast(4)");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, Bitcast_Usage) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst =
|
||||
b.builder.Bitcast(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i));
|
||||
|
||||
ASSERT_NE(inst->Result(), nullptr);
|
||||
ASSERT_EQ(inst->Result()->Usage().Length(), 1u);
|
||||
EXPECT_EQ(inst->Result()->Usage()[0], inst);
|
||||
|
||||
ASSERT_NE(inst->Val(), nullptr);
|
||||
ASSERT_EQ(inst->Val()->Usage().Length(), 1u);
|
||||
EXPECT_EQ(inst->Val()->Usage()[0], inst);
|
||||
|
|
|
@ -91,12 +91,8 @@ void Builder::Branch(Block* from, FlowNode* to, utils::VectorRef<Value*> args) {
|
|||
to->inbound_branches.Push(from);
|
||||
}
|
||||
|
||||
Runtime::Id Builder::AllocateRuntimeId() {
|
||||
return next_runtime_id++;
|
||||
}
|
||||
|
||||
Binary* Builder::CreateBinary(Binary::Kind kind, const type::Type* type, Value* lhs, Value* rhs) {
|
||||
return ir.instructions.Create<ir::Binary>(kind, Runtime(type), lhs, rhs);
|
||||
return ir.instructions.Create<ir::Binary>(next_inst_id(), kind, type, lhs, rhs);
|
||||
}
|
||||
|
||||
Binary* Builder::And(const type::Type* type, Value* lhs, Value* rhs) {
|
||||
|
@ -172,7 +168,7 @@ Binary* Builder::Modulo(const type::Type* type, Value* lhs, Value* rhs) {
|
|||
}
|
||||
|
||||
Unary* Builder::CreateUnary(Unary::Kind kind, const type::Type* type, Value* val) {
|
||||
return ir.instructions.Create<ir::Unary>(kind, Runtime(type), val);
|
||||
return ir.instructions.Create<ir::Unary>(next_inst_id(), kind, type, val);
|
||||
}
|
||||
|
||||
Unary* Builder::AddressOf(const type::Type* type, Value* val) {
|
||||
|
@ -196,33 +192,33 @@ Unary* Builder::Not(const type::Type* type, Value* val) {
|
|||
}
|
||||
|
||||
ir::Bitcast* Builder::Bitcast(const type::Type* type, Value* val) {
|
||||
return ir.instructions.Create<ir::Bitcast>(Runtime(type), val);
|
||||
return ir.instructions.Create<ir::Bitcast>(next_inst_id(), type, val);
|
||||
}
|
||||
|
||||
ir::Discard* Builder::Discard() {
|
||||
return ir.instructions.Create<ir::Discard>(Runtime(ir.types.Get<type::Void>()));
|
||||
return ir.instructions.Create<ir::Discard>();
|
||||
}
|
||||
|
||||
ir::UserCall* Builder::UserCall(const type::Type* type,
|
||||
Symbol name,
|
||||
utils::VectorRef<Value*> args) {
|
||||
return ir.instructions.Create<ir::UserCall>(Runtime(type), name, std::move(args));
|
||||
return ir.instructions.Create<ir::UserCall>(next_inst_id(), type, name, std::move(args));
|
||||
}
|
||||
|
||||
ir::Convert* Builder::Convert(const type::Type* to,
|
||||
const type::Type* from,
|
||||
utils::VectorRef<Value*> args) {
|
||||
return ir.instructions.Create<ir::Convert>(Runtime(to), from, std::move(args));
|
||||
return ir.instructions.Create<ir::Convert>(next_inst_id(), to, from, std::move(args));
|
||||
}
|
||||
|
||||
ir::Construct* Builder::Construct(const type::Type* to, utils::VectorRef<Value*> args) {
|
||||
return ir.instructions.Create<ir::Construct>(Runtime(to), std::move(args));
|
||||
return ir.instructions.Create<ir::Construct>(next_inst_id(), to, std::move(args));
|
||||
}
|
||||
|
||||
ir::Builtin* Builder::Builtin(const type::Type* type,
|
||||
builtin::Function func,
|
||||
utils::VectorRef<Value*> args) {
|
||||
return ir.instructions.Create<ir::Builtin>(Runtime(type), func, args);
|
||||
return ir.instructions.Create<ir::Builtin>(next_inst_id(), type, func, args);
|
||||
}
|
||||
|
||||
ir::Store* Builder::Store(Value* to, Value* from) {
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "src/tint/ir/if.h"
|
||||
#include "src/tint/ir/loop.h"
|
||||
#include "src/tint/ir/module.h"
|
||||
#include "src/tint/ir/runtime.h"
|
||||
#include "src/tint/ir/store.h"
|
||||
#include "src/tint/ir/switch.h"
|
||||
#include "src/tint/ir/terminator.h"
|
||||
|
@ -141,13 +140,6 @@ class Builder {
|
|||
return Constant(create<constant::Scalar<bool>>(ir.types.Get<type::Bool>(), v));
|
||||
}
|
||||
|
||||
/// Creates a new Runtime value
|
||||
/// @param type the type of the temporary
|
||||
/// @returns the new temporary
|
||||
ir::Runtime* Runtime(const type::Type* type) {
|
||||
return ir.values.Create<ir::Runtime>(type, AllocateRuntimeId());
|
||||
}
|
||||
|
||||
/// Creates an op for `lhs kind rhs`
|
||||
/// @param kind the kind of operation
|
||||
/// @param type the result type of the binary expression
|
||||
|
@ -366,14 +358,13 @@ class Builder {
|
|||
/// @returns the instruction
|
||||
ir::Store* Store(Value* to, Value* from);
|
||||
|
||||
/// @returns a unique runtime id
|
||||
Runtime::Id AllocateRuntimeId();
|
||||
|
||||
/// The IR module.
|
||||
Module ir;
|
||||
|
||||
/// The next temporary number to allocate
|
||||
Runtime::Id next_runtime_id = 1;
|
||||
private:
|
||||
uint32_t next_inst_id() { return next_instruction_id_++; }
|
||||
|
||||
uint32_t next_instruction_id_ = 1;
|
||||
};
|
||||
|
||||
} // namespace tint::ir
|
||||
|
|
|
@ -353,7 +353,7 @@ void BuilderImpl::EmitCompoundAssignment(const ast::CompoundAssignmentStatement*
|
|||
}
|
||||
current_flow_block->instructions.Push(inst);
|
||||
|
||||
auto store = builder.Store(lhs.Get(), inst->Result());
|
||||
auto store = builder.Store(lhs.Get(), inst);
|
||||
current_flow_block->instructions.Push(store);
|
||||
}
|
||||
|
||||
|
@ -738,7 +738,7 @@ utils::Result<Value*> BuilderImpl::EmitUnary(const ast::UnaryOpExpression* expr)
|
|||
}
|
||||
|
||||
current_flow_block->instructions.Push(inst);
|
||||
return inst->Result();
|
||||
return inst;
|
||||
}
|
||||
|
||||
utils::Result<Value*> BuilderImpl::EmitBinary(const ast::BinaryExpression* expr) {
|
||||
|
@ -817,7 +817,7 @@ utils::Result<Value*> BuilderImpl::EmitBinary(const ast::BinaryExpression* expr)
|
|||
}
|
||||
|
||||
current_flow_block->instructions.Push(inst);
|
||||
return inst->Result();
|
||||
return inst;
|
||||
}
|
||||
|
||||
utils::Result<Value*> BuilderImpl::EmitBitcast(const ast::BitcastExpression* expr) {
|
||||
|
@ -831,7 +831,7 @@ utils::Result<Value*> BuilderImpl::EmitBitcast(const ast::BitcastExpression* exp
|
|||
auto* inst = builder.Bitcast(ty, val.Get());
|
||||
|
||||
current_flow_block->instructions.Push(inst);
|
||||
return inst->Result();
|
||||
return inst;
|
||||
}
|
||||
|
||||
void BuilderImpl::EmitCall(const ast::CallStatement* stmt) {
|
||||
|
@ -896,7 +896,7 @@ utils::Result<Value*> BuilderImpl::EmitCall(const ast::CallExpression* expr) {
|
|||
return utils::Failure;
|
||||
}
|
||||
current_flow_block->instructions.Push(inst);
|
||||
return inst->Result();
|
||||
return inst;
|
||||
}
|
||||
|
||||
utils::Result<Value*> BuilderImpl::EmitLiteral(const ast::LiteralExpression* lit) {
|
||||
|
|
|
@ -1564,7 +1564,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Add) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 + 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(u32) = 3 + 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1580,7 +1580,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Subtract) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 - 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(u32) = 3 - 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1596,7 +1596,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Multiply) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 * 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(u32) = 3 * 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1612,7 +1612,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Div) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 / 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(u32) = 3 / 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1628,7 +1628,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Modulo) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 % 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(u32) = 3 % 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1644,7 +1644,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_And) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 & 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(u32) = 3 & 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1660,7 +1660,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Or) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 | 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(u32) = 3 | 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1676,7 +1676,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Xor) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 ^ 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(u32) = 3 ^ 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1692,7 +1692,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalAnd) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = true && false
|
||||
EXPECT_EQ(d.AsString(), R"(%1(bool) = true && false
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1708,7 +1708,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalOr) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = false || true
|
||||
EXPECT_EQ(d.AsString(), R"(%1(bool) = false || true
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1724,7 +1724,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Equal) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 == 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(bool) = 3 == 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1740,7 +1740,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_NotEqual) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 != 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(bool) = 3 != 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1756,7 +1756,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThan) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 < 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(bool) = 3 < 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1772,7 +1772,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThan) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 > 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(bool) = 3 > 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1788,7 +1788,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThanEqual) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 <= 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(bool) = 3 <= 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1804,7 +1804,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThanEqual) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 >= 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(bool) = 3 >= 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1820,7 +1820,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftLeft) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 << 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(u32) = 3 << 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1836,7 +1836,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftRight) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 >> 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1(u32) = 3 >> 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1853,13 +1853,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Compound) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 >> 4
|
||||
%2 (u32) = %1 (u32) + 9
|
||||
%3 (bool) = 1 < %2 (u32)
|
||||
%4 (f32) = 2.29999995231628417969 * 5.5
|
||||
%5 (f32) = 6.69999980926513671875 / %4 (f32)
|
||||
%6 (bool) = 2.5 > %5 (f32)
|
||||
%7 (bool) = %3 (bool) && %6 (bool)
|
||||
EXPECT_EQ(d.AsString(), R"(%1(u32) = 3 >> 4
|
||||
%2(u32) = %1(u32) + 9
|
||||
%3(bool) = 1 < %2(u32)
|
||||
%4(f32) = 2.29999995231628417969 * 5.5
|
||||
%5(f32) = 6.69999980926513671875 / %4(f32)
|
||||
%6(bool) = 2.5 > %5(f32)
|
||||
%7(bool) = %3(bool) && %6(bool)
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1875,7 +1875,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Bitcast) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (f32) = bitcast(3)
|
||||
EXPECT_EQ(d.AsString(), R"(%1(f32) = bitcast(3)
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1893,7 +1893,7 @@ TEST_F(IR_BuilderImplTest, EmitStatement_Discard) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (void) = discard
|
||||
EXPECT_EQ(d.AsString(), R"(discard
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1910,8 +1910,8 @@ TEST_F(IR_BuilderImplTest, EmitStatement_UserFunction) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (f32) = 2.0 * 3.0
|
||||
%2 (void) = call(my_func, %1 (f32))
|
||||
EXPECT_EQ(d.AsString(), R"(%1(f32) = 2.0 * 3.0
|
||||
%2(void) = call(my_func, %1(f32))
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1930,7 +1930,7 @@ TEST_F(IR_BuilderImplTest, DISABLED_EmitExpression_ConstructEmpty) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (vec3<f32>) = construct(vec3<f32>)
|
||||
EXPECT_EQ(d.AsString(), R"(%1(vec3<f32>) = construct()
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1948,7 +1948,7 @@ TEST_F(IR_BuilderImplTest, DISABLED_EmitExpression_Construct) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%2 (vec3<f32>) = construct(vec3<f32>, 2.0, 3.0, %1 (void))
|
||||
EXPECT_EQ(d.AsString(), R"(%2(vec3<f32>) = construct(2.0, 3.0, %1(void))
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1966,7 +1966,7 @@ TEST_F(IR_BuilderImplTest, DISABLED_EmitExpression_Convert) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%2 (f32) = convert(f32, i32, %1 (void))
|
||||
EXPECT_EQ(d.AsString(), R"(%2(f32) = convert(i32, %1(void))
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -2001,7 +2001,7 @@ TEST_F(IR_BuilderImplTest, DISABLED_EmitExpression_Builtin) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
|
||||
EXPECT_EQ(d.AsString(), R"(%2 (f32) = asin(%1 (void))
|
||||
EXPECT_EQ(d.AsString(), R"(%2(f32) = asin(%1(void))
|
||||
)");
|
||||
}
|
||||
|
||||
|
|
|
@ -20,14 +20,16 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Builtin);
|
|||
// \cond DO_NOT_DOCUMENT
|
||||
namespace tint::ir {
|
||||
|
||||
Builtin::Builtin(Value* result, builtin::Function func, utils::VectorRef<Value*> args)
|
||||
: Base(result, args), func_(func) {}
|
||||
Builtin::Builtin(uint32_t id,
|
||||
const type::Type* type,
|
||||
builtin::Function func,
|
||||
utils::VectorRef<Value*> args)
|
||||
: Base(id, type, args), func_(func) {}
|
||||
|
||||
Builtin::~Builtin() = default;
|
||||
|
||||
utils::StringStream& Builtin::ToString(utils::StringStream& out) const {
|
||||
Result()->ToString(out);
|
||||
out << " = " << builtin::str(func_) << "(";
|
||||
utils::StringStream& Builtin::ToInstruction(utils::StringStream& out) const {
|
||||
ToValue(out) << " = " << builtin::str(func_) << "(";
|
||||
EmitArgs(out);
|
||||
out << ")";
|
||||
return out;
|
||||
|
|
|
@ -26,10 +26,14 @@ namespace tint::ir {
|
|||
class Builtin : public utils::Castable<Builtin, Call> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param result the result value
|
||||
/// @param id the instruction id
|
||||
/// @param type the result type
|
||||
/// @param func the builtin function
|
||||
/// @param args the conversion arguments
|
||||
Builtin(Value* result, builtin::Function func, utils::VectorRef<Value*> args);
|
||||
Builtin(uint32_t id,
|
||||
const type::Type* type,
|
||||
builtin::Function func,
|
||||
utils::VectorRef<Value*> args);
|
||||
Builtin(const Builtin& inst) = delete;
|
||||
Builtin(Builtin&& inst) = delete;
|
||||
~Builtin() override;
|
||||
|
@ -43,7 +47,7 @@ class Builtin : public utils::Castable<Builtin, Call> {
|
|||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToString(utils::StringStream& out) const override;
|
||||
utils::StringStream& ToInstruction(utils::StringStream& out) const override;
|
||||
|
||||
private:
|
||||
const builtin::Function func_;
|
||||
|
|
|
@ -18,7 +18,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Call);
|
|||
|
||||
namespace tint::ir {
|
||||
|
||||
Call::Call(Value* result, utils::VectorRef<Value*> args) : Base(result), args_(args) {
|
||||
Call::Call(uint32_t id, const type::Type* type, utils::VectorRef<Value*> args)
|
||||
: Base(id, type), args_(args) {
|
||||
for (auto* arg : args) {
|
||||
arg->AddUsage(this);
|
||||
}
|
||||
|
@ -33,7 +34,7 @@ void Call::EmitArgs(utils::StringStream& out) const {
|
|||
out << ", ";
|
||||
}
|
||||
first = false;
|
||||
arg->ToString(out);
|
||||
arg->ToValue(out);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,9 +25,10 @@ namespace tint::ir {
|
|||
class Call : public utils::Castable<Call, Instruction> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param result the result value
|
||||
/// @param id the instruction id
|
||||
/// @param type the result type
|
||||
/// @param args the constructor arguments
|
||||
Call(Value* result, utils::VectorRef<Value*> args);
|
||||
Call(uint32_t id, const type::Type* type, utils::VectorRef<Value*> args);
|
||||
Call(const Call& inst) = delete;
|
||||
Call(Call&& inst) = delete;
|
||||
~Call() override;
|
||||
|
|
|
@ -29,7 +29,7 @@ Constant::Constant(const constant::Value* val) : value(val) {}
|
|||
|
||||
Constant::~Constant() = default;
|
||||
|
||||
utils::StringStream& Constant::ToString(utils::StringStream& out) const {
|
||||
utils::StringStream& Constant::ToValue(utils::StringStream& out) const {
|
||||
std::function<void(const constant::Value*)> emit = [&](const constant::Value* c) {
|
||||
Switch(
|
||||
c,
|
||||
|
|
|
@ -35,7 +35,7 @@ class Constant : public utils::Castable<Constant, Value> {
|
|||
/// Write the constant to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToString(utils::StringStream& out) const override;
|
||||
utils::StringStream& ToValue(utils::StringStream& out) const override;
|
||||
|
||||
/// The constants value
|
||||
const constant::Value* const value;
|
||||
|
|
|
@ -31,7 +31,7 @@ TEST_F(IR_ConstantTest, f32) {
|
|||
auto* c = b.builder.Constant(1.2_f);
|
||||
EXPECT_EQ(1.2_f, c->value->As<constant::Scalar<f32>>()->ValueAs<f32>());
|
||||
|
||||
c->ToString(str);
|
||||
c->ToValue(str);
|
||||
EXPECT_EQ("1.20000004768371582031", str.str());
|
||||
|
||||
EXPECT_TRUE(c->value->Is<constant::Scalar<f32>>());
|
||||
|
@ -49,7 +49,7 @@ TEST_F(IR_ConstantTest, f16) {
|
|||
auto* c = b.builder.Constant(1.1_h);
|
||||
EXPECT_EQ(1.1_h, c->value->As<constant::Scalar<f16>>()->ValueAs<f16>());
|
||||
|
||||
c->ToString(str);
|
||||
c->ToValue(str);
|
||||
EXPECT_EQ("1.099609375", str.str());
|
||||
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
||||
|
@ -67,7 +67,7 @@ TEST_F(IR_ConstantTest, i32) {
|
|||
auto* c = b.builder.Constant(1_i);
|
||||
EXPECT_EQ(1_i, c->value->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
c->ToString(str);
|
||||
c->ToValue(str);
|
||||
EXPECT_EQ("1", str.str());
|
||||
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
||||
|
@ -85,7 +85,7 @@ TEST_F(IR_ConstantTest, u32) {
|
|||
auto* c = b.builder.Constant(2_u);
|
||||
EXPECT_EQ(2_u, c->value->As<constant::Scalar<u32>>()->ValueAs<u32>());
|
||||
|
||||
c->ToString(str);
|
||||
c->ToValue(str);
|
||||
EXPECT_EQ("2", str.str());
|
||||
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
||||
|
@ -104,7 +104,7 @@ TEST_F(IR_ConstantTest, bool) {
|
|||
auto* c = b.builder.Constant(false);
|
||||
EXPECT_FALSE(c->value->As<constant::Scalar<bool>>()->ValueAs<bool>());
|
||||
|
||||
c->ToString(str);
|
||||
c->ToValue(str);
|
||||
EXPECT_EQ("false", str.str());
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ TEST_F(IR_ConstantTest, bool) {
|
|||
auto c = b.builder.Constant(true);
|
||||
EXPECT_TRUE(c->value->As<constant::Scalar<bool>>()->ValueAs<bool>());
|
||||
|
||||
c->ToString(str);
|
||||
c->ToValue(str);
|
||||
EXPECT_EQ("true", str.str());
|
||||
|
||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
||||
|
|
|
@ -19,13 +19,13 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Construct);
|
|||
|
||||
namespace tint::ir {
|
||||
|
||||
Construct::Construct(Value* result, utils::VectorRef<Value*> args) : Base(result, args) {}
|
||||
Construct::Construct(uint32_t id, const type::Type* type, utils::VectorRef<Value*> args)
|
||||
: Base(id, type, args) {}
|
||||
|
||||
Construct::~Construct() = default;
|
||||
|
||||
utils::StringStream& Construct::ToString(utils::StringStream& out) const {
|
||||
Result()->ToString(out);
|
||||
out << " = construct(" << Result()->Type()->FriendlyName();
|
||||
utils::StringStream& Construct::ToInstruction(utils::StringStream& out) const {
|
||||
ToValue(out) << " = construct(";
|
||||
if (!Args().IsEmpty()) {
|
||||
out << ", ";
|
||||
EmitArgs(out);
|
||||
|
|
|
@ -25,9 +25,10 @@ namespace tint::ir {
|
|||
class Construct : public utils::Castable<Construct, Call> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param result the result value
|
||||
/// @param id the instruction id
|
||||
/// @param type the result type
|
||||
/// @param args the constructor arguments
|
||||
Construct(Value* result, utils::VectorRef<Value*> args);
|
||||
Construct(uint32_t id, const type::Type* type, utils::VectorRef<Value*> args);
|
||||
Construct(const Construct& inst) = delete;
|
||||
Construct(Construct&& inst) = delete;
|
||||
~Construct() override;
|
||||
|
@ -38,7 +39,7 @@ class Construct : public utils::Castable<Construct, Call> {
|
|||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToString(utils::StringStream& out) const override;
|
||||
utils::StringStream& ToInstruction(utils::StringStream& out) const override;
|
||||
};
|
||||
|
||||
} // namespace tint::ir
|
||||
|
|
|
@ -19,15 +19,16 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Convert);
|
|||
|
||||
namespace tint::ir {
|
||||
|
||||
Convert::Convert(Value* result, const type::Type* from, utils::VectorRef<Value*> args)
|
||||
: Base(result, args), from_(from) {}
|
||||
Convert::Convert(uint32_t id,
|
||||
const type::Type* to_type,
|
||||
const type::Type* from_type,
|
||||
utils::VectorRef<Value*> args)
|
||||
: Base(id, to_type, args), from_type_(from_type) {}
|
||||
|
||||
Convert::~Convert() = default;
|
||||
|
||||
utils::StringStream& Convert::ToString(utils::StringStream& out) const {
|
||||
Result()->ToString(out);
|
||||
out << " = convert(" << Result()->Type()->FriendlyName() << ", " << from_->FriendlyName()
|
||||
<< ", ";
|
||||
utils::StringStream& Convert::ToInstruction(utils::StringStream& out) const {
|
||||
ToValue(out) << " = convert(" << from_type_->FriendlyName() << ", ";
|
||||
EmitArgs(out);
|
||||
out << ")";
|
||||
return out;
|
||||
|
|
|
@ -26,10 +26,14 @@ namespace tint::ir {
|
|||
class Convert : public utils::Castable<Convert, Call> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param result the result value
|
||||
/// @param from the type being converted from
|
||||
/// @param id the instruction id
|
||||
/// @param result_type the result type
|
||||
/// @param from_type the type being converted from
|
||||
/// @param args the conversion arguments
|
||||
Convert(Value* result, const type::Type* from, utils::VectorRef<Value*> args);
|
||||
Convert(uint32_t id,
|
||||
const type::Type* result_type,
|
||||
const type::Type* from_type,
|
||||
utils::VectorRef<Value*> args);
|
||||
Convert(const Convert& inst) = delete;
|
||||
Convert(Convert&& inst) = delete;
|
||||
~Convert() override;
|
||||
|
@ -38,17 +42,17 @@ class Convert : public utils::Castable<Convert, Call> {
|
|||
Convert& operator=(Convert&& inst) = delete;
|
||||
|
||||
/// @returns the from type
|
||||
const type::Type* From() const { return from_; }
|
||||
const type::Type* FromType() const { return from_type_; }
|
||||
/// @returns the to type
|
||||
const type::Type* To() const { return Result()->Type(); }
|
||||
const type::Type* ToType() const { return Type(); }
|
||||
|
||||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToString(utils::StringStream& out) const override;
|
||||
utils::StringStream& ToInstruction(utils::StringStream& out) const override;
|
||||
|
||||
private:
|
||||
const type::Type* from_ = nullptr;
|
||||
const type::Type* from_type_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace tint::ir
|
||||
|
|
|
@ -64,7 +64,7 @@ utils::StringStream& Disassembler::Indent() {
|
|||
void Disassembler::EmitBlockInstructions(const Block* b) {
|
||||
for (const auto* inst : b->instructions) {
|
||||
Indent();
|
||||
inst->ToString(out_) << std::endl;
|
||||
inst->ToInstruction(out_) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ void Disassembler::Walk(const FlowNode* node) {
|
|||
if (v != b->branch.args.Front()) {
|
||||
out_ << ", ";
|
||||
}
|
||||
v->ToString(out_);
|
||||
v->ToValue(out_);
|
||||
}
|
||||
out_ << ")" << std::endl;
|
||||
|
||||
|
@ -131,7 +131,7 @@ void Disassembler::Walk(const FlowNode* node) {
|
|||
},
|
||||
[&](const ir::Switch* s) {
|
||||
Indent() << "%bb" << GetIdForNode(s) << " = Switch (";
|
||||
s->condition->ToString(out_);
|
||||
s->condition->ToValue(out_);
|
||||
out_ << ")" << std::endl;
|
||||
|
||||
{
|
||||
|
@ -147,7 +147,7 @@ void Disassembler::Walk(const FlowNode* node) {
|
|||
if (selector.IsDefault()) {
|
||||
out_ << "default";
|
||||
} else {
|
||||
selector.val->ToString(out_);
|
||||
selector.val->ToValue(out_);
|
||||
}
|
||||
}
|
||||
out_ << std::endl;
|
||||
|
@ -160,7 +160,7 @@ void Disassembler::Walk(const FlowNode* node) {
|
|||
},
|
||||
[&](const ir::If* i) {
|
||||
Indent() << "%bb" << GetIdForNode(i) << " = if (";
|
||||
i->condition->ToString(out_);
|
||||
i->condition->ToValue(out_);
|
||||
out_ << ")" << std::endl;
|
||||
|
||||
{
|
||||
|
|
|
@ -19,13 +19,12 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Discard);
|
|||
|
||||
namespace tint::ir {
|
||||
|
||||
Discard::Discard(Value* result) : Base(result) {}
|
||||
Discard::Discard() : Base() {}
|
||||
|
||||
Discard::~Discard() = default;
|
||||
|
||||
utils::StringStream& Discard::ToString(utils::StringStream& out) const {
|
||||
Result()->ToString(out);
|
||||
out << " = discard";
|
||||
utils::StringStream& Discard::ToInstruction(utils::StringStream& out) const {
|
||||
out << "discard";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef SRC_TINT_IR_DISCARD_H_
|
||||
#define SRC_TINT_IR_DISCARD_H_
|
||||
|
||||
#include "src/tint/debug.h"
|
||||
#include "src/tint/ir/instruction.h"
|
||||
#include "src/tint/utils/castable.h"
|
||||
#include "src/tint/utils/string_stream.h"
|
||||
|
@ -25,8 +26,7 @@ namespace tint::ir {
|
|||
class Discard : public utils::Castable<Discard, Instruction> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param result the result id
|
||||
explicit Discard(Value* result);
|
||||
Discard();
|
||||
Discard(const Discard& inst) = delete;
|
||||
Discard(Discard&& inst) = delete;
|
||||
~Discard() override;
|
||||
|
@ -37,7 +37,7 @@ class Discard : public utils::Castable<Discard, Instruction> {
|
|||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToString(utils::StringStream& out) const override;
|
||||
utils::StringStream& ToInstruction(utils::StringStream& out) const override;
|
||||
};
|
||||
|
||||
} // namespace tint::ir
|
||||
|
|
|
@ -24,17 +24,12 @@ using IR_InstructionTest = TestHelper;
|
|||
TEST_F(IR_InstructionTest, Discard) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst = b.builder.Discard();
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
ASSERT_NE(inst->Result()->Type(), nullptr);
|
||||
ASSERT_NE(inst->Result()->Type()->As<type::Void>(), nullptr);
|
||||
ASSERT_TRUE(inst->Is<ir::Discard>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (void) = discard");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "discard");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -18,10 +18,9 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Instruction);
|
|||
|
||||
namespace tint::ir {
|
||||
|
||||
Instruction::Instruction(Value* result) : result_(result) {
|
||||
TINT_ASSERT(IR, result_);
|
||||
result_->AddUsage(this);
|
||||
}
|
||||
Instruction::Instruction() = default;
|
||||
|
||||
Instruction::Instruction(uint32_t id, const type::Type* ty) : id_(id), type_(ty) {}
|
||||
|
||||
Instruction::~Instruction() = default;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
namespace tint::ir {
|
||||
|
||||
/// An instruction in the IR.
|
||||
class Instruction : public utils::Castable<Instruction> {
|
||||
class Instruction : public utils::Castable<Instruction, Value> {
|
||||
public:
|
||||
Instruction(const Instruction& inst) = delete;
|
||||
Instruction(Instruction&& inst) = delete;
|
||||
|
@ -32,21 +32,36 @@ class Instruction : public utils::Castable<Instruction> {
|
|||
Instruction& operator=(const Instruction& inst) = delete;
|
||||
Instruction& operator=(Instruction&& inst) = delete;
|
||||
|
||||
/// @returns the result value for the instruction
|
||||
Value* Result() const { return result_; }
|
||||
/// @returns the type of the value
|
||||
const type::Type* Type() const override { return type_; }
|
||||
|
||||
/// Write the value to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToValue(utils::StringStream& out) const override {
|
||||
out << "%" << std::to_string(id_);
|
||||
if (type_ != nullptr) {
|
||||
out << "(" << Type()->FriendlyName() << ")";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
virtual utils::StringStream& ToString(utils::StringStream& out) const = 0;
|
||||
virtual utils::StringStream& ToInstruction(utils::StringStream& out) const = 0;
|
||||
|
||||
protected:
|
||||
/// Constructor
|
||||
/// @param result the result value
|
||||
explicit Instruction(Value* result);
|
||||
Instruction();
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param type the result type
|
||||
Instruction(uint32_t id, const type::Type* type);
|
||||
|
||||
private:
|
||||
Value* result_ = nullptr;
|
||||
uint32_t id_ = 0;
|
||||
const type::Type* type_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace tint::ir
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/tint/ir/runtime.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ir::Runtime);
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
Runtime::Runtime(const type::Type* type, Id id) : type_(type), id_(id) {}
|
||||
|
||||
Runtime::~Runtime() = default;
|
||||
|
||||
utils::StringStream& Runtime::ToString(utils::StringStream& out) const {
|
||||
out << "%" << std::to_string(AsId()) << " (" << type_->FriendlyName() << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace tint::ir
|
|
@ -1,61 +0,0 @@
|
|||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_TINT_IR_RUNTIME_H_
|
||||
#define SRC_TINT_IR_RUNTIME_H_
|
||||
|
||||
#include "src/tint/ir/value.h"
|
||||
#include "src/tint/utils/string_stream.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
/// Runtime value in the IR.
|
||||
class Runtime : public utils::Castable<Runtime, Value> {
|
||||
public:
|
||||
/// A value id.
|
||||
using Id = uint32_t;
|
||||
|
||||
/// Constructor
|
||||
/// @param type the type of the value
|
||||
/// @param id the id for the value
|
||||
Runtime(const type::Type* type, Id id);
|
||||
|
||||
/// Destructor
|
||||
~Runtime() override;
|
||||
|
||||
Runtime(const Runtime&) = delete;
|
||||
Runtime(Runtime&&) = delete;
|
||||
|
||||
Runtime& operator=(const Runtime&) = delete;
|
||||
Runtime& operator=(Runtime&&) = delete;
|
||||
|
||||
/// @returns the value data as an `Id`.
|
||||
Id AsId() const { return id_; }
|
||||
|
||||
/// @returns the type of the value
|
||||
const type::Type* Type() const override { return type_; }
|
||||
|
||||
/// Write the id to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToString(utils::StringStream& out) const override;
|
||||
|
||||
private:
|
||||
const type::Type* type_ = nullptr;
|
||||
Id id_ = 0;
|
||||
};
|
||||
|
||||
} // namespace tint::ir
|
||||
|
||||
#endif // SRC_TINT_IR_RUNTIME_H_
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/tint/ir/runtime.h"
|
||||
#include "src/tint/ir/test_helper.h"
|
||||
#include "src/tint/utils/string_stream.h"
|
||||
|
||||
namespace tint::ir {
|
||||
namespace {
|
||||
|
||||
using namespace tint::number_suffixes; // NOLINT
|
||||
|
||||
using IR_RuntimeTest = TestHelper;
|
||||
|
||||
TEST_F(IR_RuntimeTest, id) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
utils::StringStream str;
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(4);
|
||||
auto* val = b.builder.Runtime(b.builder.ir.types.Get<type::I32>());
|
||||
EXPECT_EQ(4u, val->AsId());
|
||||
|
||||
val->ToString(str);
|
||||
EXPECT_EQ("%4 (i32)", str.str());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::ir
|
|
@ -19,17 +19,19 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Store);
|
|||
|
||||
namespace tint::ir {
|
||||
|
||||
Store::Store(Value* to, Value* from) : Base(to), from_(from) {
|
||||
Store::Store(Value* to, Value* from) : Base(), to_(to), from_(from) {
|
||||
TINT_ASSERT(IR, to_);
|
||||
TINT_ASSERT(IR, from_);
|
||||
to_->AddUsage(this);
|
||||
from_->AddUsage(this);
|
||||
}
|
||||
|
||||
Store::~Store() = default;
|
||||
|
||||
utils::StringStream& Store::ToString(utils::StringStream& out) const {
|
||||
Result()->ToString(out);
|
||||
out << " = ";
|
||||
from_->ToString(out);
|
||||
utils::StringStream& Store::ToInstruction(utils::StringStream& out) const {
|
||||
out << "store(";
|
||||
to_->ToValue(out) << ", ";
|
||||
from_->ToValue(out) << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,15 +35,18 @@ class Store : public utils::Castable<Store, Instruction> {
|
|||
Store& operator=(const Store& inst) = delete;
|
||||
Store& operator=(Store&& inst) = delete;
|
||||
|
||||
/// @returns the value being stored too
|
||||
const Value* to() const { return to_; }
|
||||
/// @returns the value being stored
|
||||
const Value* from() const { return from_; }
|
||||
|
||||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToString(utils::StringStream& out) const override;
|
||||
utils::StringStream& ToInstruction(utils::StringStream& out) const override;
|
||||
|
||||
private:
|
||||
Value* to_ = nullptr;
|
||||
Value* from_ = nullptr;
|
||||
};
|
||||
|
||||
|
|
|
@ -26,14 +26,13 @@ using IR_InstructionTest = TestHelper;
|
|||
TEST_F(IR_InstructionTest, CreateStore) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
// TODO(dsinclair): This is wrong, but we don't have anything correct to store too at the
|
||||
// moment.
|
||||
auto* to = b.builder.Discard();
|
||||
const auto* inst = b.builder.Store(to, b.builder.Constant(4_i));
|
||||
|
||||
auto* rt = b.builder.Runtime(b.builder.ir.types.Get<type::I32>());
|
||||
const auto* inst = b.builder.Store(rt, b.builder.Constant(4_i));
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
ASSERT_NE(inst->Result()->Type(), nullptr);
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
ASSERT_TRUE(inst->Is<Store>());
|
||||
ASSERT_EQ(inst->to(), to);
|
||||
|
||||
ASSERT_TRUE(inst->from()->Is<Constant>());
|
||||
auto lhs = inst->from()->As<Constant>()->value;
|
||||
|
@ -41,20 +40,19 @@ TEST_F(IR_InstructionTest, CreateStore) {
|
|||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "store(%0, 4)");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, Store_Usage) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
auto* rt = b.builder.Runtime(b.builder.ir.types.Get<type::I32>());
|
||||
const auto* inst = b.builder.Store(rt, b.builder.Constant(4_i));
|
||||
auto* to = b.builder.Discard();
|
||||
const auto* inst = b.builder.Store(to, b.builder.Constant(4_i));
|
||||
|
||||
ASSERT_NE(inst->Result(), nullptr);
|
||||
ASSERT_EQ(inst->Result()->Usage().Length(), 1u);
|
||||
EXPECT_EQ(inst->Result()->Usage()[0], inst);
|
||||
ASSERT_NE(inst->to(), nullptr);
|
||||
ASSERT_EQ(inst->to()->Usage().Length(), 1u);
|
||||
EXPECT_EQ(inst->to()->Usage()[0], inst);
|
||||
|
||||
ASSERT_NE(inst->from(), nullptr);
|
||||
ASSERT_EQ(inst->from()->Usage().Length(), 1u);
|
||||
|
|
|
@ -19,15 +19,16 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Unary);
|
|||
|
||||
namespace tint::ir {
|
||||
|
||||
Unary::Unary(Kind kind, Value* result, Value* val) : Base(result), kind_(kind), val_(val) {
|
||||
Unary::Unary(uint32_t id, Kind kind, const type::Type* type, Value* val)
|
||||
: Base(id, type), kind_(kind), val_(val) {
|
||||
TINT_ASSERT(IR, val_);
|
||||
val_->AddUsage(this);
|
||||
}
|
||||
|
||||
Unary::~Unary() = default;
|
||||
|
||||
utils::StringStream& Unary::ToString(utils::StringStream& out) const {
|
||||
Result()->ToString(out) << " = ";
|
||||
utils::StringStream& Unary::ToInstruction(utils::StringStream& out) const {
|
||||
ToValue(out) << " = ";
|
||||
switch (GetKind()) {
|
||||
case Unary::Kind::kAddressOf:
|
||||
out << "&";
|
||||
|
@ -45,8 +46,7 @@ utils::StringStream& Unary::ToString(utils::StringStream& out) const {
|
|||
out << "!";
|
||||
break;
|
||||
}
|
||||
val_->ToString(out);
|
||||
|
||||
val_->ToValue(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,10 +34,11 @@ class Unary : public utils::Castable<Unary, Instruction> {
|
|||
};
|
||||
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param kind the kind of unary instruction
|
||||
/// @param result the result value
|
||||
/// @param type the result type
|
||||
/// @param val the lhs of the instruction
|
||||
Unary(Kind kind, Value* result, Value* val);
|
||||
Unary(uint32_t id, Kind kind, const type::Type* type, Value* val);
|
||||
Unary(const Unary& inst) = delete;
|
||||
Unary(Unary&& inst) = delete;
|
||||
~Unary() override;
|
||||
|
@ -54,7 +55,7 @@ class Unary : public utils::Castable<Unary, Instruction> {
|
|||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToString(utils::StringStream& out) const override;
|
||||
utils::StringStream& ToInstruction(utils::StringStream& out) const override;
|
||||
|
||||
private:
|
||||
Kind kind_;
|
||||
|
|
|
@ -26,7 +26,6 @@ using IR_InstructionTest = TestHelper;
|
|||
TEST_F(IR_InstructionTest, CreateAddressOf) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
// TODO(dsinclair): This would be better as an identifier, but works for now.
|
||||
const auto* inst =
|
||||
b.builder.AddressOf(b.builder.ir.types.Get<type::Pointer>(
|
||||
|
@ -34,11 +33,10 @@ TEST_F(IR_InstructionTest, CreateAddressOf) {
|
|||
builtin::AddressSpace::kPrivate, builtin::Access::kReadWrite),
|
||||
b.builder.Constant(4_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Unary>());
|
||||
EXPECT_EQ(inst->GetKind(), Unary::Kind::kAddressOf);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
ASSERT_NE(inst->Result()->Type(), nullptr);
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
ASSERT_NE(inst->Type(), nullptr);
|
||||
|
||||
ASSERT_TRUE(inst->Val()->Is<Constant>());
|
||||
auto lhs = inst->Val()->As<Constant>()->value;
|
||||
|
@ -46,112 +44,91 @@ TEST_F(IR_InstructionTest, CreateAddressOf) {
|
|||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (ptr<private, i32, read_write>) = &4");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(ptr<private, i32, read_write>) = &4");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateComplement) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst =
|
||||
b.builder.Complement(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Unary>());
|
||||
EXPECT_EQ(inst->GetKind(), Unary::Kind::kComplement);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->Val()->Is<Constant>());
|
||||
auto lhs = inst->Val()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = ~4");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = ~4");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateIndirection) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
// TODO(dsinclair): This would be better as an identifier, but works for now.
|
||||
const auto* inst =
|
||||
b.builder.Indirection(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Unary>());
|
||||
EXPECT_EQ(inst->GetKind(), Unary::Kind::kIndirection);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->Val()->Is<Constant>());
|
||||
auto lhs = inst->Val()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = *4");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = *4");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateNegation) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst =
|
||||
b.builder.Negation(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Unary>());
|
||||
EXPECT_EQ(inst->GetKind(), Unary::Kind::kNegation);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->Val()->Is<Constant>());
|
||||
auto lhs = inst->Val()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = -4");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(i32) = -4");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateNot) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst =
|
||||
b.builder.Not(b.builder.ir.types.Get<type::Bool>(), b.builder.Constant(true));
|
||||
|
||||
ASSERT_TRUE(inst->Is<Unary>());
|
||||
EXPECT_EQ(inst->GetKind(), Unary::Kind::kNot);
|
||||
|
||||
ASSERT_TRUE(inst->Result()->Is<Runtime>());
|
||||
EXPECT_EQ(Runtime::Id(42), inst->Result()->As<Runtime>()->AsId());
|
||||
|
||||
ASSERT_TRUE(inst->Val()->Is<Constant>());
|
||||
auto lhs = inst->Val()->As<Constant>()->value;
|
||||
ASSERT_TRUE(lhs->Is<constant::Scalar<bool>>());
|
||||
EXPECT_TRUE(lhs->As<constant::Scalar<bool>>()->ValueAs<bool>());
|
||||
|
||||
utils::StringStream str;
|
||||
inst->ToString(str);
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = !true");
|
||||
inst->ToInstruction(str);
|
||||
EXPECT_EQ(str.str(), "%1(bool) = !true");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, Unary_Usage) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_runtime_id = Runtime::Id(42);
|
||||
const auto* inst =
|
||||
b.builder.Negation(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i));
|
||||
|
||||
EXPECT_EQ(inst->GetKind(), Unary::Kind::kNegation);
|
||||
|
||||
ASSERT_NE(inst->Result(), nullptr);
|
||||
ASSERT_EQ(inst->Result()->Usage().Length(), 1u);
|
||||
EXPECT_EQ(inst->Result()->Usage()[0], inst);
|
||||
|
||||
ASSERT_NE(inst->Val(), nullptr);
|
||||
ASSERT_EQ(inst->Val()->Usage().Length(), 1u);
|
||||
EXPECT_EQ(inst->Val()->Usage()[0], inst);
|
||||
|
|
|
@ -19,15 +19,13 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::UserCall);
|
|||
|
||||
namespace tint::ir {
|
||||
|
||||
UserCall::UserCall(Value* result, Symbol name, utils::VectorRef<Value*> args)
|
||||
: Base(result, args), name_(name) {}
|
||||
UserCall::UserCall(uint32_t id, const type::Type* type, Symbol name, utils::VectorRef<Value*> args)
|
||||
: Base(id, type, args), name_(name) {}
|
||||
|
||||
UserCall::~UserCall() = default;
|
||||
|
||||
utils::StringStream& UserCall::ToString(utils::StringStream& out) const {
|
||||
Result()->ToString(out);
|
||||
out << " = call(";
|
||||
out << name_.Name() << ", ";
|
||||
utils::StringStream& UserCall::ToInstruction(utils::StringStream& out) const {
|
||||
ToValue(out) << " = call(" << name_.Name() << ", ";
|
||||
EmitArgs(out);
|
||||
out << ")";
|
||||
return out;
|
||||
|
|
|
@ -26,10 +26,11 @@ namespace tint::ir {
|
|||
class UserCall : public utils::Castable<UserCall, Call> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param result the result value
|
||||
/// @param id the instruction id
|
||||
/// @param type the result type
|
||||
/// @param name the function name
|
||||
/// @param args the function arguments
|
||||
UserCall(Value* result, Symbol name, utils::VectorRef<Value*> args);
|
||||
UserCall(uint32_t id, const type::Type* type, Symbol name, utils::VectorRef<Value*> args);
|
||||
UserCall(const UserCall& inst) = delete;
|
||||
UserCall(UserCall&& inst) = delete;
|
||||
~UserCall() override;
|
||||
|
@ -43,7 +44,7 @@ class UserCall : public utils::Castable<UserCall, Call> {
|
|||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
utils::StringStream& ToString(utils::StringStream& out) const override;
|
||||
utils::StringStream& ToInstruction(utils::StringStream& out) const override;
|
||||
|
||||
private:
|
||||
Symbol name_{};
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "src/tint/ir/value.h"
|
||||
|
||||
#include "src/tint/ir/constant.h"
|
||||
#include "src/tint/ir/runtime.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ir::Value);
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ class Value : public utils::Castable<Value> {
|
|||
/// Write the value to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @returns the stream
|
||||
virtual utils::StringStream& ToString(utils::StringStream& out) const = 0;
|
||||
virtual utils::StringStream& ToValue(utils::StringStream& out) const = 0;
|
||||
|
||||
protected:
|
||||
/// Constructor
|
||||
|
|
Loading…
Reference in New Issue