tint/ir: Remove value id field.

There's a few reasons for this change:
* Not all values have identifiers, and carrying redundant fields is
  inefficent.
* Not all IDs will be integers - much like LLVM IR and SPIR-V, we will
  likely want to disassemble with textual identifiers, so a uint32_t
  is not ideal, and a std::string is even more bloat for each value.
* Transforms don't use identifiers, but instead raw pointers. We don't
  want to encourage using IDs as they're simply a less-efficient way to
  refer to values.
* This makes values consistent with types and flow-control blocks, as
  they will both have their disassembly ID generated by the
  disassembler.

The next step will be to add a hashmap to the module so that
pre-declared value names can be stored out-of-band.

Bug: tint:1718
Change-Id: I80beafc165f2bde54cc44a91015776926ca952b2
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/131740
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2023-05-09 21:17:59 +00:00 committed by Dawn LUCI CQ
parent 1c56265ee1
commit a8236a5529
32 changed files with 428 additions and 472 deletions

View File

@ -19,8 +19,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Binary);
namespace tint::ir { namespace tint::ir {
Binary::Binary(uint32_t identifier, Kind kind, const type::Type* ty, Value* lhs, Value* rhs) Binary::Binary(Kind kind, const type::Type* ty, Value* lhs, Value* rhs)
: Base(identifier, ty), kind_(kind), lhs_(lhs), rhs_(rhs) { : Base(ty), kind_(kind), lhs_(lhs), rhs_(rhs) {
TINT_ASSERT(IR, lhs_); TINT_ASSERT(IR, lhs_);
TINT_ASSERT(IR, rhs_); TINT_ASSERT(IR, rhs_);
lhs_->AddUsage(this); lhs_->AddUsage(this);

View File

@ -47,12 +47,11 @@ class Binary : public utils::Castable<Binary, Instruction> {
}; };
/// Constructor /// Constructor
/// @param id the instruction id
/// @param kind the kind of binary instruction /// @param kind the kind of binary instruction
/// @param type the result type /// @param type the result type
/// @param lhs the lhs of the instruction /// @param lhs the lhs of the instruction
/// @param rhs the rhs of the instruction /// @param rhs the rhs of the instruction
Binary(uint32_t id, Kind kind, const type::Type* type, Value* lhs, Value* rhs); Binary(Kind kind, const type::Type* type, Value* lhs, Value* rhs);
Binary(const Binary& inst) = delete; Binary(const Binary& inst) = delete;
Binary(Binary&& inst) = delete; Binary(Binary&& inst) = delete;
~Binary() override; ~Binary() override;

View File

@ -19,8 +19,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Bitcast);
namespace tint::ir { namespace tint::ir {
Bitcast::Bitcast(uint32_t identifier, const type::Type* ty, Value* val) Bitcast::Bitcast(const type::Type* ty, Value* val) : Base(ty, utils::Vector{val}) {}
: Base(identifier, ty, utils::Vector{val}) {}
Bitcast::~Bitcast() = default; Bitcast::~Bitcast() = default;

View File

@ -24,10 +24,9 @@ namespace tint::ir {
class Bitcast : public utils::Castable<Bitcast, Call> { class Bitcast : public utils::Castable<Bitcast, Call> {
public: public:
/// Constructor /// Constructor
/// @param id the instruction id
/// @param type the result type /// @param type the result type
/// @param val the value being bitcast /// @param val the value being bitcast
Bitcast(uint32_t id, const type::Type* type, Value* val); Bitcast(const type::Type* type, Value* val);
Bitcast(const Bitcast& inst) = delete; Bitcast(const Bitcast& inst) = delete;
Bitcast(Bitcast&& inst) = delete; Bitcast(Bitcast&& inst) = delete;
~Bitcast() override; ~Bitcast() override;

View File

@ -109,7 +109,7 @@ void Builder::Branch(Block* from, FlowNode* to, utils::VectorRef<Value*> args) {
} }
Binary* Builder::CreateBinary(Binary::Kind kind, const type::Type* type, Value* lhs, Value* rhs) { Binary* Builder::CreateBinary(Binary::Kind kind, const type::Type* type, Value* lhs, Value* rhs) {
return ir.instructions.Create<ir::Binary>(next_inst_id(), kind, type, lhs, rhs); return ir.instructions.Create<ir::Binary>(kind, type, lhs, rhs);
} }
Binary* Builder::And(const type::Type* type, Value* lhs, Value* rhs) { Binary* Builder::And(const type::Type* type, Value* lhs, Value* rhs) {
@ -177,7 +177,7 @@ Binary* Builder::Modulo(const type::Type* type, Value* lhs, Value* rhs) {
} }
Unary* Builder::CreateUnary(Unary::Kind kind, const type::Type* type, Value* val) { Unary* Builder::CreateUnary(Unary::Kind kind, const type::Type* type, Value* val) {
return ir.instructions.Create<ir::Unary>(next_inst_id(), kind, type, val); return ir.instructions.Create<ir::Unary>(kind, type, val);
} }
Unary* Builder::AddressOf(const type::Type* type, Value* val) { Unary* Builder::AddressOf(const type::Type* type, Value* val) {
@ -201,7 +201,7 @@ Binary* Builder::Not(const type::Type* type, Value* val) {
} }
ir::Bitcast* Builder::Bitcast(const type::Type* type, Value* val) { ir::Bitcast* Builder::Bitcast(const type::Type* type, Value* val) {
return ir.instructions.Create<ir::Bitcast>(next_inst_id(), type, val); return ir.instructions.Create<ir::Bitcast>(type, val);
} }
ir::Discard* Builder::Discard() { ir::Discard* Builder::Discard() {
@ -211,23 +211,23 @@ ir::Discard* Builder::Discard() {
ir::UserCall* Builder::UserCall(const type::Type* type, ir::UserCall* Builder::UserCall(const type::Type* type,
Symbol name, Symbol name,
utils::VectorRef<Value*> args) { utils::VectorRef<Value*> args) {
return ir.instructions.Create<ir::UserCall>(next_inst_id(), type, name, std::move(args)); return ir.instructions.Create<ir::UserCall>(type, name, std::move(args));
} }
ir::Convert* Builder::Convert(const type::Type* to, ir::Convert* Builder::Convert(const type::Type* to,
const type::Type* from, const type::Type* from,
utils::VectorRef<Value*> args) { utils::VectorRef<Value*> args) {
return ir.instructions.Create<ir::Convert>(next_inst_id(), to, from, std::move(args)); return ir.instructions.Create<ir::Convert>(to, from, std::move(args));
} }
ir::Construct* Builder::Construct(const type::Type* to, utils::VectorRef<Value*> args) { ir::Construct* Builder::Construct(const type::Type* to, utils::VectorRef<Value*> args) {
return ir.instructions.Create<ir::Construct>(next_inst_id(), to, std::move(args)); return ir.instructions.Create<ir::Construct>(to, std::move(args));
} }
ir::Builtin* Builder::Builtin(const type::Type* type, ir::Builtin* Builder::Builtin(const type::Type* type,
builtin::Function func, builtin::Function func,
utils::VectorRef<Value*> args) { utils::VectorRef<Value*> args) {
return ir.instructions.Create<ir::Builtin>(next_inst_id(), type, func, args); return ir.instructions.Create<ir::Builtin>(type, func, args);
} }
ir::Store* Builder::Store(Value* to, Value* from) { ir::Store* Builder::Store(Value* to, Value* from) {
@ -237,7 +237,7 @@ ir::Store* Builder::Store(Value* to, Value* from) {
ir::Var* Builder::Declare(const type::Type* type, ir::Var* Builder::Declare(const type::Type* type,
builtin::AddressSpace address_space, builtin::AddressSpace address_space,
builtin::Access access) { builtin::Access access) {
return ir.instructions.Create<ir::Var>(next_inst_id(), type, address_space, access); return ir.instructions.Create<ir::Var>(type, address_space, access);
} }
} // namespace tint::ir } // namespace tint::ir

View File

@ -364,11 +364,6 @@ class Builder {
/// The IR module. /// The IR module.
Module ir; Module ir;
private:
uint32_t next_inst_id() { return next_instruction_id_++; }
uint32_t next_instruction_id_ = 1;
}; };
} // namespace tint::ir } // namespace tint::ir

View File

@ -53,13 +53,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundAdd) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, u32, read_write> = var private read_write %1:ref<private, u32, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ref<private, u32, read_write> = add %1:ref<private, u32, read_write>, 1u %2:ref<private, u32, read_write> = add %1:ref<private, u32, read_write>, 1u
store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write> store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
ret ret
@ -95,13 +95,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundSubtract) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, u32, read_write> = var private read_write %1:ref<private, u32, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ref<private, u32, read_write> = sub %1:ref<private, u32, read_write>, 1u %2:ref<private, u32, read_write> = sub %1:ref<private, u32, read_write>, 1u
store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write> store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
ret ret
@ -137,13 +137,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundMultiply) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, u32, read_write> = var private read_write %1:ref<private, u32, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ref<private, u32, read_write> = mul %1:ref<private, u32, read_write>, 1u %2:ref<private, u32, read_write> = mul %1:ref<private, u32, read_write>, 1u
store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write> store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
ret ret
@ -179,13 +179,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundDiv) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, u32, read_write> = var private read_write %1:ref<private, u32, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ref<private, u32, read_write> = div %1:ref<private, u32, read_write>, 1u %2:ref<private, u32, read_write> = div %1:ref<private, u32, read_write>, 1u
store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write> store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
ret ret
@ -221,13 +221,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundModulo) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, u32, read_write> = var private read_write %1:ref<private, u32, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ref<private, u32, read_write> = mod %1:ref<private, u32, read_write>, 1u %2:ref<private, u32, read_write> = mod %1:ref<private, u32, read_write>, 1u
store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write> store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
ret ret
@ -263,13 +263,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundAnd) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, bool, read_write> = var private read_write %1:ref<private, bool, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ref<private, bool, read_write> = and %1:ref<private, bool, read_write>, false %2:ref<private, bool, read_write> = and %1:ref<private, bool, read_write>, false
store %1:ref<private, bool, read_write>, %2:ref<private, bool, read_write> store %1:ref<private, bool, read_write>, %2:ref<private, bool, read_write>
ret ret
@ -305,13 +305,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundOr) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, bool, read_write> = var private read_write %1:ref<private, bool, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ref<private, bool, read_write> = or %1:ref<private, bool, read_write>, false %2:ref<private, bool, read_write> = or %1:ref<private, bool, read_write>, false
store %1:ref<private, bool, read_write>, %2:ref<private, bool, read_write> store %1:ref<private, bool, read_write>, %2:ref<private, bool, read_write>
ret ret
@ -347,13 +347,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundXor) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, u32, read_write> = var private read_write %1:ref<private, u32, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ref<private, u32, read_write> = xor %1:ref<private, u32, read_write>, 1u %2:ref<private, u32, read_write> = xor %1:ref<private, u32, read_write>, 1u
store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write> store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
ret ret
@ -371,26 +371,26 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalAnd) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = func my_func():bool EXPECT_EQ(Disassemble(m), R"(%fn1 = func my_func():bool
%fn1 = block %fn2 = block
ret true ret true
func_end func_end
%fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn3 = block %fn4 = block
%1:bool = call my_func %1:bool = call my_func
%2:bool = var function read_write %2:bool = var function read_write
store %2:bool, %1:bool store %2:bool, %1:bool
branch %fn4 branch %fn5
%fn4 = if %1:bool [t: %fn5, f: %fn6, m: %fn7] %fn5 = if %1:bool [t: %fn6, f: %fn7, m: %fn8]
# true branch # true branch
%fn5 = block %fn6 = block
store %2:bool, false store %2:bool, false
branch %fn7 branch %fn8
# if merge # if merge
%fn7 = block %fn8 = block
ret ret
func_end func_end
@ -406,27 +406,27 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalOr) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = func my_func():bool EXPECT_EQ(Disassemble(m), R"(%fn1 = func my_func():bool
%fn1 = block %fn2 = block
ret true ret true
func_end func_end
%fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn3 = block %fn4 = block
%1:bool = call my_func %1:bool = call my_func
%2:bool = var function read_write %2:bool = var function read_write
store %2:bool, %1:bool store %2:bool, %1:bool
branch %fn4 branch %fn5
%fn4 = if %1:bool [t: %fn5, f: %fn6, m: %fn7] %fn5 = if %1:bool [t: %fn6, f: %fn7, m: %fn8]
# true branch # true branch
# false branch # false branch
%fn6 = block %fn7 = block
store %2:bool, true store %2:bool, true
branch %fn7 branch %fn8
# if merge # if merge
%fn7 = block %fn8 = block
ret ret
func_end func_end
@ -568,13 +568,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundShiftLeft) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, u32, read_write> = var private read_write %1:ref<private, u32, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ref<private, u32, read_write> = shiftl %1:ref<private, u32, read_write>, 1u %2:ref<private, u32, read_write> = shiftl %1:ref<private, u32, read_write>, 1u
store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write> store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
ret ret
@ -610,13 +610,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundShiftRight) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, u32, read_write> = var private read_write %1:ref<private, u32, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ref<private, u32, read_write> = shiftr %1:ref<private, u32, read_write>, 1u %2:ref<private, u32, read_write> = shiftr %1:ref<private, u32, read_write>, 1u
store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write> store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
ret ret
@ -636,32 +636,32 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Compound) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = func my_func():f32 EXPECT_EQ(Disassemble(m), R"(%fn1 = func my_func():f32
%fn1 = block %fn2 = block
ret 0.0f ret 0.0f
func_end func_end
%fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn3 = block %fn4 = block
%1:f32 = call my_func %1:f32 = call my_func
%2:bool = lt %1:f32, 2.0f %2:bool = lt %1:f32, 2.0f
%3:bool = var function read_write %3:bool = var function read_write
store %3:bool, %2:bool store %3:bool, %2:bool
branch %fn4 branch %fn5
%fn4 = if %2:bool [t: %fn5, f: %fn6, m: %fn7] %fn5 = if %2:bool [t: %fn6, f: %fn7, m: %fn8]
# true branch # true branch
%fn5 = block %fn6 = block
%4:f32 = call my_func %4:f32 = call my_func
%5:f32 = call my_func %5:f32 = call my_func
%6:f32 = mul 2.29999995231628417969f, %5:f32 %6:f32 = mul 2.29999995231628417969f, %5:f32
%7:f32 = div %4:f32, %6:f32 %7:f32 = div %4:f32, %6:f32
%8:bool = gt 2.5f, %7:f32 %8:bool = gt 2.5f, %7:f32
store %3:bool, %8:bool store %3:bool, %8:bool
branch %fn7 branch %fn8
# if merge # if merge
%fn7 = block %fn8 = block
ret ret
func_end func_end
@ -678,13 +678,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Compound_WithConstEval) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = func my_func():bool EXPECT_EQ(Disassemble(m), R"(%fn1 = func my_func():bool
%fn1 = block %fn2 = block
ret true ret true
func_end func_end
%fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn3 = block %fn4 = block
%1:bool = call my_func, false %1:bool = call my_func, false
ret ret
func_end func_end

View File

@ -91,14 +91,14 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Convert) {
auto m = r.Move(); auto m = r.Move();
ASSERT_TRUE(r); ASSERT_TRUE(r);
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, i32, read_write> = var private read_write %1:ref<private, i32, read_write> = var private read_write
store %1:ref<private, i32, read_write>, 1i store %1:ref<private, i32, read_write>, 1i
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:f32 = convert i32, %1:ref<private, i32, read_write> %2:f32 = convert i32, %1:ref<private, i32, read_write>
ret ret
func_end func_end
@ -115,7 +115,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_ConstructEmpty) {
auto m = r.Move(); auto m = r.Move();
ASSERT_TRUE(r); ASSERT_TRUE(r);
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, vec3<f32>, read_write> = var private read_write %1:ref<private, vec3<f32>, read_write> = var private read_write
store %1:ref<private, vec3<f32>, read_write>, vec3<f32> 0.0f store %1:ref<private, vec3<f32>, read_write>, vec3<f32> 0.0f
@ -134,14 +134,14 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Construct) {
auto m = r.Move(); auto m = r.Move();
ASSERT_TRUE(r); ASSERT_TRUE(r);
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, f32, read_write> = var private read_write %1:ref<private, f32, read_write> = var private read_write
store %1:ref<private, f32, read_write>, 1.0f store %1:ref<private, f32, read_write>, 1.0f
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:vec3<f32> = construct 2.0f, 3.0f, %1:ref<private, f32, read_write> %2:vec3<f32> = construct 2.0f, 3.0f, %1:ref<private, f32, read_write>
ret ret
func_end func_end

View File

@ -35,8 +35,8 @@ TEST_F(IR_BuilderImplTest, EmitExpression_MaterializedCall) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function():f32 EXPECT_EQ(Disassemble(m), R"(%fn1 = func test_function():f32
%fn1 = block %fn2 = block
ret 2.0f ret 2.0f
func_end func_end

View File

@ -36,13 +36,13 @@ TEST_F(IR_BuilderImplTest, EmitStatement_Assign) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, u32, read_write> = var private read_write %1:ref<private, u32, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
store %1:ref<private, u32, read_write>, 4u store %1:ref<private, u32, read_write>, 4u
ret ret
func_end func_end

View File

@ -42,8 +42,8 @@ TEST_F(IR_BuilderImplTest, Func) {
EXPECT_EQ(1u, f->start_target->inbound_branches.Length()); EXPECT_EQ(1u, f->start_target->inbound_branches.Length());
EXPECT_EQ(1u, f->end_target->inbound_branches.Length()); EXPECT_EQ(1u, f->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), R"(%fn0 = func f():void EXPECT_EQ(Disassemble(m), R"(%fn1 = func f():void
%fn1 = block %fn2 = block
ret ret
func_end func_end
@ -89,21 +89,21 @@ TEST_F(IR_BuilderImplTest, IfStatement) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = if true [t: %fn3, f: %fn4, m: %fn5] %fn3 = if true [t: %fn4, f: %fn5, m: %fn6]
# true branch # true branch
%fn3 = block %fn4 = block
branch %fn5 branch %fn6
# false branch # false branch
%fn4 = block %fn5 = block
branch %fn5 branch %fn6
# if merge # if merge
%fn5 = block %fn6 = block
ret ret
func_end func_end
@ -138,20 +138,20 @@ TEST_F(IR_BuilderImplTest, IfStatement_TrueReturns) {
EXPECT_EQ(2u, func->end_target->inbound_branches.Length()); EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = if true [t: %fn3, f: %fn4, m: %fn5] %fn3 = if true [t: %fn4, f: %fn5, m: %fn6]
# true branch # true branch
%fn3 = block %fn4 = block
ret ret
# false branch # false branch
%fn4 = block %fn5 = block
branch %fn5 branch %fn6
# if merge # if merge
%fn5 = block %fn6 = block
ret ret
func_end func_end
@ -186,20 +186,20 @@ TEST_F(IR_BuilderImplTest, IfStatement_FalseReturns) {
EXPECT_EQ(2u, func->end_target->inbound_branches.Length()); EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = if true [t: %fn3, f: %fn4, m: %fn5] %fn3 = if true [t: %fn4, f: %fn5, m: %fn6]
# true branch # true branch
%fn3 = block %fn4 = block
branch %fn5 branch %fn6
# false branch # false branch
%fn4 = block %fn5 = block
ret ret
# if merge # if merge
%fn5 = block %fn6 = block
ret ret
func_end func_end
@ -234,16 +234,16 @@ TEST_F(IR_BuilderImplTest, IfStatement_BothReturn) {
EXPECT_EQ(2u, func->end_target->inbound_branches.Length()); EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = if true [t: %fn3, f: %fn4] %fn3 = if true [t: %fn4, f: %fn5]
# true branch # true branch
%fn3 = block %fn4 = block
ret ret
# false branch # false branch
%fn4 = block %fn5 = block
ret ret
func_end func_end
@ -278,30 +278,30 @@ TEST_F(IR_BuilderImplTest, IfStatement_JumpChainToMerge) {
ASSERT_NE(loop_flow->merge.target, nullptr); ASSERT_NE(loop_flow->merge.target, nullptr);
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = if true [t: %fn3, f: %fn4, m: %fn5] %fn3 = if true [t: %fn4, f: %fn5, m: %fn6]
# true branch # true branch
%fn3 = block %fn4 = block
branch %fn6 branch %fn7
%fn6 = loop [s: %fn7, m: %fn8] %fn7 = loop [s: %fn8, m: %fn9]
# loop start # loop start
%fn7 = block %fn8 = block
branch %fn8 branch %fn9
# loop merge # loop merge
%fn8 = block %fn9 = block
branch %fn5 branch %fn6
# false branch # false branch
%fn4 = block %fn5 = block
branch %fn5 branch %fn6
# if merge # if merge
%fn5 = block %fn6 = block
ret ret
func_end func_end
@ -336,17 +336,17 @@ TEST_F(IR_BuilderImplTest, Loop_WithBreak) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = loop [s: %fn3, m: %fn4] %fn3 = loop [s: %fn4, m: %fn5]
# loop start # loop start
%fn3 = block %fn4 = block
branch %fn4 branch %fn5
# loop merge # loop merge
%fn4 = block %fn5 = block
ret ret
func_end func_end
@ -395,34 +395,34 @@ TEST_F(IR_BuilderImplTest, Loop_WithContinue) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = loop [s: %fn3, c: %fn4, m: %fn5] %fn3 = loop [s: %fn4, c: %fn5, m: %fn6]
# loop start # loop start
%fn3 = block %fn4 = block
branch %fn6 branch %fn7
%fn6 = if true [t: %fn7, f: %fn8, m: %fn9] %fn7 = if true [t: %fn8, f: %fn9, m: %fn10]
# true branch # true branch
%fn7 = block %fn8 = block
branch %fn5 branch %fn6
# false branch # false branch
%fn8 = block %fn9 = block
branch %fn9 branch %fn10
# if merge # if merge
%fn9 = block %fn10 = block
branch %fn4 branch %fn5
# loop continuing # loop continuing
%fn4 = block %fn5 = block
branch %fn3 branch %fn4
# loop merge # loop merge
%fn5 = block %fn6 = block
ret ret
func_end func_end
@ -471,34 +471,34 @@ TEST_F(IR_BuilderImplTest, Loop_WithContinuing_BreakIf) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = loop [s: %fn3, c: %fn4, m: %fn5] %fn3 = loop [s: %fn4, c: %fn5, m: %fn6]
# loop start # loop start
%fn3 = block %fn4 = block
branch %fn4 branch %fn5
# loop continuing # loop continuing
%fn4 = block %fn5 = block
branch %fn6 branch %fn7
%fn6 = if true [t: %fn7, f: %fn8, m: %fn9] %fn7 = if true [t: %fn8, f: %fn9, m: %fn10]
# true branch # true branch
%fn7 = block %fn8 = block
branch %fn5 branch %fn6
# false branch # false branch
%fn8 = block %fn9 = block
branch %fn9 branch %fn10
# if merge # if merge
%fn9 = block %fn10 = block
branch %fn3 branch %fn4
# loop merge # loop merge
%fn5 = block %fn6 = block
ret ret
func_end func_end
@ -547,30 +547,30 @@ TEST_F(IR_BuilderImplTest, Loop_WithReturn) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = loop [s: %fn3, c: %fn4] %fn3 = loop [s: %fn4, c: %fn5]
# loop start # loop start
%fn3 = block %fn4 = block
branch %fn5 branch %fn6
%fn5 = if true [t: %fn6, f: %fn7, m: %fn8] %fn6 = if true [t: %fn7, f: %fn8, m: %fn9]
# true branch # true branch
%fn6 = block %fn7 = block
ret ret
# false branch # false branch
%fn7 = block %fn8 = block
branch %fn8 branch %fn9
# if merge # if merge
%fn8 = block %fn9 = block
branch %fn4 branch %fn5
# loop continuing # loop continuing
%fn4 = block %fn5 = block
branch %fn3 branch %fn4
func_end func_end
@ -605,13 +605,13 @@ TEST_F(IR_BuilderImplTest, Loop_WithOnlyReturn) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = loop [s: %fn3] %fn3 = loop [s: %fn4]
# loop start # loop start
%fn3 = block %fn4 = block
ret ret
func_end func_end
@ -668,13 +668,13 @@ TEST_F(IR_BuilderImplTest, Loop_WithOnlyReturn_ContinuingBreakIf) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = loop [s: %fn3] %fn3 = loop [s: %fn4]
# loop start # loop start
%fn3 = block %fn4 = block
ret ret
func_end func_end
@ -723,26 +723,26 @@ TEST_F(IR_BuilderImplTest, Loop_WithIf_BothBranchesBreak) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = loop [s: %fn3, m: %fn4] %fn3 = loop [s: %fn4, m: %fn5]
# loop start # loop start
%fn3 = block %fn4 = block
branch %fn5 branch %fn6
%fn5 = if true [t: %fn6, f: %fn7] %fn6 = if true [t: %fn7, f: %fn8]
# true branch # true branch
%fn6 = block %fn7 = block
branch %fn4 branch %fn5
# false branch # false branch
%fn7 = block %fn8 = block
branch %fn4 branch %fn5
# loop merge # loop merge
%fn4 = block %fn5 = block
ret ret
func_end func_end
@ -870,108 +870,108 @@ TEST_F(IR_BuilderImplTest, Loop_Nested) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = loop [s: %fn3, c: %fn4, m: %fn5] %fn3 = loop [s: %fn4, c: %fn5, m: %fn6]
# loop start # loop start
%fn3 = block %fn4 = block
branch %fn6 branch %fn7
%fn6 = loop [s: %fn7, c: %fn8, m: %fn9] %fn7 = loop [s: %fn8, c: %fn9, m: %fn10]
# loop start # loop start
%fn7 = block %fn8 = block
branch %fn10 branch %fn11
%fn10 = if true [t: %fn11, f: %fn12, m: %fn13] %fn11 = if true [t: %fn12, f: %fn13, m: %fn14]
# true branch # true branch
%fn11 = block %fn12 = block
branch %fn10
# false branch
%fn13 = block
branch %fn14
# if merge
%fn14 = block
branch %fn15
%fn15 = if true [t: %fn16, f: %fn17, m: %fn18]
# true branch
%fn16 = block
branch %fn9 branch %fn9
# false branch # false branch
%fn12 = block %fn17 = block
branch %fn13 branch %fn18
# if merge # if merge
%fn13 = block %fn18 = block
branch %fn14 branch %fn9
%fn14 = if true [t: %fn15, f: %fn16, m: %fn17]
# true branch
%fn15 = block
branch %fn8
# false branch
%fn16 = block
branch %fn17
# if merge
%fn17 = block
branch %fn8
# loop continuing # loop continuing
%fn8 = block %fn9 = block
branch %fn18 branch %fn19
%fn18 = loop [s: %fn19, m: %fn20] %fn19 = loop [s: %fn20, m: %fn21]
# loop start # loop start
%fn19 = block %fn20 = block
branch %fn20 branch %fn21
# loop merge # loop merge
%fn20 = block %fn21 = block
branch %fn21 branch %fn22
%fn21 = loop [s: %fn22, c: %fn23, m: %fn24] %fn22 = loop [s: %fn23, c: %fn24, m: %fn25]
# loop start # loop start
%fn22 = block %fn23 = block
branch %fn23 branch %fn24
# loop continuing # loop continuing
%fn23 = block %fn24 = block
branch %fn25 branch %fn26
%fn25 = if true [t: %fn26, f: %fn27, m: %fn28] %fn26 = if true [t: %fn27, f: %fn28, m: %fn29]
# true branch # true branch
%fn26 = block %fn27 = block
branch %fn24 branch %fn25
# false branch # false branch
%fn27 = block %fn28 = block
branch %fn28 branch %fn29
# if merge # if merge
%fn28 = block %fn29 = block
branch %fn22 branch %fn23
# loop merge # loop merge
%fn24 = block %fn25 = block
branch %fn7 branch %fn8
# loop merge # loop merge
%fn9 = block %fn10 = block
branch %fn29 branch %fn30
%fn29 = if true [t: %fn30, f: %fn31, m: %fn32] %fn30 = if true [t: %fn31, f: %fn32, m: %fn33]
# true branch # true branch
%fn30 = block %fn31 = block
branch %fn5 branch %fn6
# false branch # false branch
%fn31 = block %fn32 = block
branch %fn32 branch %fn33
# if merge # if merge
%fn32 = block %fn33 = block
branch %fn4 branch %fn5
# loop continuing # loop continuing
%fn4 = block %fn5 = block
branch %fn3 branch %fn4
# loop merge # loop merge
%fn5 = block %fn6 = block
ret ret
func_end func_end
@ -1015,34 +1015,34 @@ TEST_F(IR_BuilderImplTest, While) {
EXPECT_EQ(1u, if_flow->merge.target->inbound_branches.Length()); EXPECT_EQ(1u, if_flow->merge.target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = loop [s: %fn3, c: %fn4, m: %fn5] %fn3 = loop [s: %fn4, c: %fn5, m: %fn6]
# loop start # loop start
%fn3 = block %fn4 = block
branch %fn6 branch %fn7
%fn6 = if false [t: %fn7, f: %fn8, m: %fn9] %fn7 = if false [t: %fn8, f: %fn9, m: %fn10]
# true branch # true branch
%fn7 = block %fn8 = block
branch %fn9 branch %fn10
# false branch # false branch
%fn8 = block %fn9 = block
branch %fn5 branch %fn6
# if merge # if merge
%fn9 = block %fn10 = block
branch %fn4 branch %fn5
# loop continuing # loop continuing
%fn4 = block %fn5 = block
branch %fn3 branch %fn4
# loop merge # loop merge
%fn5 = block %fn6 = block
ret ret
func_end func_end
@ -1086,29 +1086,29 @@ TEST_F(IR_BuilderImplTest, While_Return) {
EXPECT_EQ(1u, if_flow->merge.target->inbound_branches.Length()); EXPECT_EQ(1u, if_flow->merge.target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = loop [s: %fn3, m: %fn4] %fn3 = loop [s: %fn4, m: %fn5]
# loop start # loop start
%fn3 = block %fn4 = block
branch %fn5 branch %fn6
%fn5 = if true [t: %fn6, f: %fn7, m: %fn8] %fn6 = if true [t: %fn7, f: %fn8, m: %fn9]
# true branch # true branch
%fn6 = block %fn7 = block
branch %fn8 branch %fn9
# false branch # false branch
%fn7 = block %fn8 = block
branch %fn4 branch %fn5
# if merge # if merge
%fn8 = block %fn9 = block
ret ret
# loop merge # loop merge
%fn4 = block %fn5 = block
ret ret
func_end func_end
@ -1194,17 +1194,17 @@ TEST_F(IR_BuilderImplTest, For_NoInitCondOrContinuing) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = loop [s: %fn3, m: %fn4] %fn3 = loop [s: %fn4, m: %fn5]
# loop start # loop start
%fn3 = block %fn4 = block
branch %fn4 branch %fn5
# loop merge # loop merge
%fn4 = block %fn5 = block
ret ret
func_end func_end
@ -1254,25 +1254,25 @@ TEST_F(IR_BuilderImplTest, Switch) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = switch 1i [c: (0i, %fn3), c: (1i, %fn4), c: (default, %fn5), m: %fn6] %fn3 = switch 1i [c: (0i, %fn4), c: (1i, %fn5), c: (default, %fn6), m: %fn7]
# case 0i # case 0i
%fn3 = block %fn4 = block
branch %fn6 branch %fn7
# case 1i # case 1i
%fn4 = block %fn5 = block
branch %fn6 branch %fn7
# case default # case default
%fn5 = block %fn6 = block
branch %fn6 branch %fn7
# switch merge # switch merge
%fn6 = block %fn7 = block
ret ret
func_end func_end
@ -1319,17 +1319,17 @@ TEST_F(IR_BuilderImplTest, Switch_MultiSelector) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = switch 1i [c: (0i 1i default, %fn3), m: %fn4] %fn3 = switch 1i [c: (0i 1i default, %fn4), m: %fn5]
# case 0i 1i default # case 0i 1i default
%fn3 = block %fn4 = block
branch %fn4 branch %fn5
# switch merge # switch merge
%fn4 = block %fn5 = block
ret ret
func_end func_end
@ -1364,17 +1364,17 @@ TEST_F(IR_BuilderImplTest, Switch_OnlyDefault) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = switch 1i [c: (default, %fn3), m: %fn4] %fn3 = switch 1i [c: (default, %fn4), m: %fn5]
# case default # case default
%fn3 = block %fn4 = block
branch %fn4 branch %fn5
# switch merge # switch merge
%fn4 = block %fn5 = block
ret ret
func_end func_end
@ -1418,21 +1418,21 @@ TEST_F(IR_BuilderImplTest, Switch_WithBreak) {
EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = switch 1i [c: (0i, %fn3), c: (default, %fn4), m: %fn5] %fn3 = switch 1i [c: (0i, %fn4), c: (default, %fn5), m: %fn6]
# case 0i # case 0i
%fn3 = block %fn4 = block
branch %fn5 branch %fn6
# case default # case default
%fn4 = block %fn5 = block
branch %fn5 branch %fn6
# switch merge # switch merge
%fn5 = block %fn6 = block
ret ret
func_end func_end
@ -1478,16 +1478,16 @@ TEST_F(IR_BuilderImplTest, Switch_AllReturn) {
EXPECT_EQ(2u, func->end_target->inbound_branches.Length()); EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
branch %fn2 branch %fn3
%fn2 = switch 1i [c: (0i, %fn3), c: (default, %fn4)] %fn3 = switch 1i [c: (0i, %fn4), c: (default, %fn5)]
# case 0i # case 0i
%fn3 = block %fn4 = block
ret ret
# case default # case default
%fn4 = block %fn5 = block
ret ret
func_end func_end

View File

@ -90,13 +90,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Unary_AddressOf) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, i32, read_write> = var private read_write %1:ref<private, i32, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ptr<private, i32, read_write> = addr_of %1:ref<private, i32, read_write> %2:ptr<private, i32, read_write> = addr_of %1:ref<private, i32, read_write>
ret ret
func_end func_end
@ -116,13 +116,13 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Unary_Indirection) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, i32, read_write> = var private read_write %1:ref<private, i32, read_write> = var private read_write
%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] %fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn2 = block %fn3 = block
%2:ptr<private, i32, read_write> = addr_of %1:ref<private, i32, read_write> %2:ptr<private, i32, read_write> = addr_of %1:ref<private, i32, read_write>
%3:i32 = indirection %2:ptr<private, i32, read_write> %3:i32 = indirection %2:ptr<private, i32, read_write>
ret ret

View File

@ -33,7 +33,7 @@ TEST_F(IR_BuilderImplTest, Emit_GlobalVar_NoInit) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, u32, read_write> = var private read_write %1:ref<private, u32, read_write> = var private read_write
@ -49,7 +49,7 @@ TEST_F(IR_BuilderImplTest, Emit_GlobalVar_Init) {
ASSERT_TRUE(r) << Error(); ASSERT_TRUE(r) << Error();
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), R"(%fn0 = block EXPECT_EQ(Disassemble(m), R"(%fn1 = block
%1:ref<private, u32, read_write> = var private read_write %1:ref<private, u32, read_write> = var private read_write
store %1:ref<private, u32, read_write>, 2u store %1:ref<private, u32, read_write>, 2u
@ -67,8 +67,8 @@ TEST_F(IR_BuilderImplTest, Emit_Var_NoInit) {
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
%1:ref<function, u32, read_write> = var function read_write %1:ref<function, u32, read_write> = var function read_write
ret ret
func_end func_end
@ -86,8 +86,8 @@ TEST_F(IR_BuilderImplTest, Emit_Var_Init) {
auto m = r.Move(); auto m = r.Move();
EXPECT_EQ(Disassemble(m), EXPECT_EQ(Disassemble(m),
R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)] R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block %fn2 = block
%1:ref<function, u32, read_write> = var function read_write %1:ref<function, u32, read_write> = var function read_write
store %1:ref<function, u32, read_write>, 2u store %1:ref<function, u32, read_write>, 2u
ret ret

View File

@ -23,11 +23,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Builtin);
// \cond DO_NOT_DOCUMENT // \cond DO_NOT_DOCUMENT
namespace tint::ir { namespace tint::ir {
Builtin::Builtin(uint32_t identifier, Builtin::Builtin(const type::Type* ty, builtin::Function func, utils::VectorRef<Value*> arguments)
const type::Type* ty, : Base(ty, std::move(arguments)), func_(func) {}
builtin::Function func,
utils::VectorRef<Value*> arguments)
: Base(identifier, ty, std::move(arguments)), func_(func) {}
Builtin::~Builtin() = default; Builtin::~Builtin() = default;

View File

@ -25,14 +25,10 @@ namespace tint::ir {
class Builtin : public utils::Castable<Builtin, Call> { class Builtin : public utils::Castable<Builtin, Call> {
public: public:
/// Constructor /// Constructor
/// @param id the instruction id
/// @param type the result type /// @param type the result type
/// @param func the builtin function /// @param func the builtin function
/// @param args the conversion arguments /// @param args the conversion arguments
Builtin(uint32_t id, Builtin(const type::Type* type, builtin::Function func, utils::VectorRef<Value*> args);
const type::Type* type,
builtin::Function func,
utils::VectorRef<Value*> args);
Builtin(const Builtin& inst) = delete; Builtin(const Builtin& inst) = delete;
Builtin(Builtin&& inst) = delete; Builtin(Builtin&& inst) = delete;
~Builtin() override; ~Builtin() override;

View File

@ -20,8 +20,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Call);
namespace tint::ir { namespace tint::ir {
Call::Call(uint32_t identifier, const type::Type* ty, utils::VectorRef<Value*> arguments) Call::Call(const type::Type* ty, utils::VectorRef<Value*> arguments)
: Base(identifier, ty), args(std::move(arguments)) { : Base(ty), args(std::move(arguments)) {
for (auto* arg : args) { for (auto* arg : args) {
arg->AddUsage(this); arg->AddUsage(this);
} }

View File

@ -37,10 +37,9 @@ class Call : public utils::Castable<Call, Instruction> {
/// Constructor /// Constructor
Call() = delete; Call() = delete;
/// Constructor /// Constructor
/// @param id the instruction id
/// @param type the result type /// @param type the result type
/// @param args the constructor arguments /// @param args the constructor arguments
Call(uint32_t id, const type::Type* type, utils::VectorRef<Value*> args); Call(const type::Type* type, utils::VectorRef<Value*> args);
}; };
} // namespace tint::ir } // namespace tint::ir

View File

@ -22,8 +22,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Construct);
namespace tint::ir { namespace tint::ir {
Construct::Construct(uint32_t identifier, const type::Type* ty, utils::VectorRef<Value*> arguments) Construct::Construct(const type::Type* ty, utils::VectorRef<Value*> arguments)
: Base(identifier, ty, std::move(arguments)) {} : Base(ty, std::move(arguments)) {}
Construct::~Construct() = default; Construct::~Construct() = default;

View File

@ -24,10 +24,9 @@ namespace tint::ir {
class Construct : public utils::Castable<Construct, Call> { class Construct : public utils::Castable<Construct, Call> {
public: public:
/// Constructor /// Constructor
/// @param id the instruction id
/// @param type the result type /// @param type the result type
/// @param args the constructor arguments /// @param args the constructor arguments
Construct(uint32_t id, const type::Type* type, utils::VectorRef<Value*> args); Construct(const type::Type* type, utils::VectorRef<Value*> args);
Construct(const Construct& inst) = delete; Construct(const Construct& inst) = delete;
Construct(Construct&& inst) = delete; Construct(Construct&& inst) = delete;
~Construct() override; ~Construct() override;

View File

@ -19,11 +19,10 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Convert);
namespace tint::ir { namespace tint::ir {
Convert::Convert(uint32_t identifier, Convert::Convert(const type::Type* to_type,
const type::Type* to_type,
const type::Type* from_type, const type::Type* from_type,
utils::VectorRef<Value*> arguments) utils::VectorRef<Value*> arguments)
: Base(identifier, to_type, arguments), from_type_(from_type) {} : Base(to_type, arguments), from_type_(from_type) {}
Convert::~Convert() = default; Convert::~Convert() = default;

View File

@ -25,12 +25,10 @@ namespace tint::ir {
class Convert : public utils::Castable<Convert, Call> { class Convert : public utils::Castable<Convert, Call> {
public: public:
/// Constructor /// Constructor
/// @param id the instruction id
/// @param result_type the result type /// @param result_type the result type
/// @param from_type the type being converted from /// @param from_type the type being converted from
/// @param args the conversion arguments /// @param args the conversion arguments
Convert(uint32_t id, Convert(const type::Type* result_type,
const type::Type* result_type,
const type::Type* from_type, const type::Type* from_type,
utils::VectorRef<Value*> args); utils::VectorRef<Value*> args);
Convert(const Convert& inst) = delete; Convert(const Convert& inst) = delete;

View File

@ -41,27 +41,29 @@ namespace tint::ir {
namespace { namespace {
class ScopedStopNode { class ScopedStopNode {
static constexpr size_t N = 32;
public: public:
ScopedStopNode(std::unordered_set<const FlowNode*>* stop_nodes, const FlowNode* node) ScopedStopNode(utils::Hashset<const FlowNode*, N>& stop_nodes, const FlowNode* node)
: stop_nodes_(stop_nodes), node_(node) { : stop_nodes_(stop_nodes), node_(node) {
stop_nodes_->insert(node_); stop_nodes_.Add(node_);
} }
~ScopedStopNode() { stop_nodes_->erase(node_); } ~ScopedStopNode() { stop_nodes_.Remove(node_); }
private: private:
std::unordered_set<const FlowNode*>* stop_nodes_; utils::Hashset<const FlowNode*, N>& stop_nodes_;
const FlowNode* node_; const FlowNode* node_;
}; };
class ScopedIndent { class ScopedIndent {
public: public:
explicit ScopedIndent(uint32_t* indent) : indent_(indent) { (*indent_) += 2; } explicit ScopedIndent(uint32_t& indent) : indent_(indent) { indent_ += 2; }
~ScopedIndent() { (*indent_) -= 2; } ~ScopedIndent() { indent_ -= 2; }
private: private:
uint32_t* indent_; uint32_t& indent_;
}; };
} // namespace } // namespace
@ -85,30 +87,28 @@ void Disassembler::EmitBlockInstructions(const Block* b) {
} }
} }
size_t Disassembler::GetIdForNode(const FlowNode* node) { size_t Disassembler::IdOf(const FlowNode* node) {
TINT_ASSERT(IR, node); TINT_ASSERT(IR, node);
return flow_node_ids_.GetOrCreate(node, [&] { return flow_node_ids_.Count(); });
}
auto it = flow_node_to_id_.find(node); std::string_view Disassembler::IdOf(const Value* value) {
if (it != flow_node_to_id_.end()) { TINT_ASSERT(IR, value);
return it->second; return value_ids_.GetOrCreate(value, [&] { return std::to_string(value_ids_.Count()); });
}
size_t id = next_node_id_++;
flow_node_to_id_[node] = id;
return id;
} }
void Disassembler::Walk(const FlowNode* node) { void Disassembler::Walk(const FlowNode* node) {
if ((visited_.count(node) > 0) || (stop_nodes_.count(node) > 0)) { if (visited_.Contains(node) || stop_nodes_.Contains(node)) {
return; return;
} }
visited_.insert(node); visited_.Add(node);
tint::Switch( tint::Switch(
node, node,
[&](const ir::Function* f) { [&](const ir::Function* f) {
TINT_SCOPED_ASSIGNMENT(in_function_, true); TINT_SCOPED_ASSIGNMENT(in_function_, true);
Indent() << "%fn" << GetIdForNode(f) << " = func " << f->name.Name() Indent() << "%fn" << IdOf(f) << " = func " << f->name.Name()
<< "():" << f->return_type->FriendlyName(); << "():" << f->return_type->FriendlyName();
if (f->pipeline_stage != Function::PipelineStage::kUndefined) { if (f->pipeline_stage != Function::PipelineStage::kUndefined) {
@ -136,8 +136,8 @@ void Disassembler::Walk(const FlowNode* node) {
out_ << std::endl; out_ << std::endl;
{ {
ScopedIndent func_indent(&indent_size_); ScopedIndent func_indent(indent_size_);
ScopedStopNode scope(&stop_nodes_, f->end_target); ScopedStopNode scope(stop_nodes_, f->end_target);
Walk(f->start_target); Walk(f->start_target);
} }
Walk(f->end_target); Walk(f->end_target);
@ -148,7 +148,7 @@ void Disassembler::Walk(const FlowNode* node) {
return; return;
} }
Indent() << "%fn" << GetIdForNode(b) << " = block" << std::endl; Indent() << "%fn" << IdOf(b) << " = block" << std::endl;
EmitBlockInstructions(b); EmitBlockInstructions(b);
if (b->branch.target->Is<FunctionTerminator>()) { if (b->branch.target->Is<FunctionTerminator>()) {
@ -157,7 +157,7 @@ void Disassembler::Walk(const FlowNode* node) {
// Nothing to do // Nothing to do
} else { } else {
Indent() << "branch " Indent() << "branch "
<< "%fn" << GetIdForNode(b->branch.target); << "%fn" << IdOf(b->branch.target);
} }
if (!b->branch.args.IsEmpty()) { if (!b->branch.args.IsEmpty()) {
out_ << " "; out_ << " ";
@ -177,7 +177,7 @@ void Disassembler::Walk(const FlowNode* node) {
Walk(b->branch.target); Walk(b->branch.target);
}, },
[&](const ir::Switch* s) { [&](const ir::Switch* s) {
Indent() << "%fn" << GetIdForNode(s) << " = switch "; Indent() << "%fn" << IdOf(s) << " = switch ";
EmitValue(s->condition); EmitValue(s->condition);
out_ << " ["; out_ << " [";
for (const auto& c : s->cases) { for (const auto& c : s->cases) {
@ -196,16 +196,16 @@ void Disassembler::Walk(const FlowNode* node) {
EmitValue(selector.val); EmitValue(selector.val);
} }
} }
out_ << ", %fn" << GetIdForNode(c.start.target) << ")"; out_ << ", %fn" << IdOf(c.start.target) << ")";
} }
if (s->merge.target->IsConnected()) { if (s->merge.target->IsConnected()) {
out_ << ", m: %fn" << GetIdForNode(s->merge.target); out_ << ", m: %fn" << IdOf(s->merge.target);
} }
out_ << "]" << std::endl; out_ << "]" << std::endl;
{ {
ScopedIndent switch_indent(&indent_size_); ScopedIndent switch_indent(indent_size_);
ScopedStopNode scope(&stop_nodes_, s->merge.target); ScopedStopNode scope(stop_nodes_, s->merge.target);
for (const auto& c : s->cases) { for (const auto& c : s->cases) {
Indent() << "# case "; Indent() << "# case ";
for (const auto& selector : c.selectors) { for (const auto& selector : c.selectors) {
@ -230,18 +230,17 @@ void Disassembler::Walk(const FlowNode* node) {
} }
}, },
[&](const ir::If* i) { [&](const ir::If* i) {
Indent() << "%fn" << GetIdForNode(i) << " = if "; Indent() << "%fn" << IdOf(i) << " = if ";
EmitValue(i->condition); EmitValue(i->condition);
out_ << " [t: %fn" << GetIdForNode(i->true_.target) << ", f: %fn" out_ << " [t: %fn" << IdOf(i->true_.target) << ", f: %fn" << IdOf(i->false_.target);
<< GetIdForNode(i->false_.target);
if (i->merge.target->IsConnected()) { if (i->merge.target->IsConnected()) {
out_ << ", m: %fn" << GetIdForNode(i->merge.target); out_ << ", m: %fn" << IdOf(i->merge.target);
} }
out_ << "]" << std::endl; out_ << "]" << std::endl;
{ {
ScopedIndent if_indent(&indent_size_); ScopedIndent if_indent(indent_size_);
ScopedStopNode scope(&stop_nodes_, i->merge.target); ScopedStopNode scope(stop_nodes_, i->merge.target);
Indent() << "# true branch" << std::endl; Indent() << "# true branch" << std::endl;
Walk(i->true_.target); Walk(i->true_.target);
@ -258,22 +257,21 @@ void Disassembler::Walk(const FlowNode* node) {
} }
}, },
[&](const ir::Loop* l) { [&](const ir::Loop* l) {
Indent() << "%fn" << GetIdForNode(l) << " = loop [s: %fn" Indent() << "%fn" << IdOf(l) << " = loop [s: %fn" << IdOf(l->start.target);
<< GetIdForNode(l->start.target);
if (l->continuing.target->IsConnected()) { if (l->continuing.target->IsConnected()) {
out_ << ", c: %fn" << GetIdForNode(l->continuing.target); out_ << ", c: %fn" << IdOf(l->continuing.target);
} }
if (l->merge.target->IsConnected()) { if (l->merge.target->IsConnected()) {
out_ << ", m: %fn" << GetIdForNode(l->merge.target); out_ << ", m: %fn" << IdOf(l->merge.target);
} }
out_ << "]" << std::endl; out_ << "]" << std::endl;
{ {
ScopedStopNode loop_scope(&stop_nodes_, l->merge.target); ScopedStopNode loop_scope(stop_nodes_, l->merge.target);
ScopedIndent loop_indent(&indent_size_); ScopedIndent loop_indent(indent_size_);
{ {
ScopedStopNode inner_scope(&stop_nodes_, l->continuing.target); ScopedStopNode inner_scope(stop_nodes_, l->continuing.target);
Indent() << "# loop start" << std::endl; Indent() << "# loop start" << std::endl;
Walk(l->start.target); Walk(l->start.target);
} }
@ -355,11 +353,7 @@ void Disassembler::EmitValue(const Value* val) {
emit(constant->value); emit(constant->value);
}, },
[&](const ir::Instruction* i) { [&](const ir::Instruction* i) {
if (i->id == ir::Instruction::kNoID) { out_ << "%" << IdOf(i);
out_ << "<no-id>";
} else {
out_ << "%" << i->id;
}
if (i->Type() != nullptr) { if (i->Type() != nullptr) {
out_ << ":" << i->Type()->FriendlyName(); out_ << ":" << i->Type()->FriendlyName();
} }

View File

@ -16,14 +16,14 @@
#define SRC_TINT_IR_DISASSEMBLER_H_ #define SRC_TINT_IR_DISASSEMBLER_H_
#include <string> #include <string>
#include <unordered_map>
#include <unordered_set>
#include "src/tint/ir/binary.h" #include "src/tint/ir/binary.h"
#include "src/tint/ir/call.h" #include "src/tint/ir/call.h"
#include "src/tint/ir/flow_node.h" #include "src/tint/ir/flow_node.h"
#include "src/tint/ir/module.h" #include "src/tint/ir/module.h"
#include "src/tint/ir/unary.h" #include "src/tint/ir/unary.h"
#include "src/tint/utils/hashmap.h"
#include "src/tint/utils/hashset.h"
#include "src/tint/utils/string_stream.h" #include "src/tint/utils/string_stream.h"
namespace tint::ir { namespace tint::ir {
@ -49,7 +49,9 @@ class Disassembler {
private: private:
utils::StringStream& Indent(); utils::StringStream& Indent();
size_t GetIdForNode(const FlowNode* node);
size_t IdOf(const FlowNode* node);
std::string_view IdOf(const Value* node);
void Walk(const FlowNode* node); void Walk(const FlowNode* node);
void EmitInstruction(const Instruction* inst); void EmitInstruction(const Instruction* inst);
@ -60,10 +62,10 @@ class Disassembler {
const Module& mod_; const Module& mod_;
utils::StringStream out_; utils::StringStream out_;
std::unordered_set<const FlowNode*> visited_; utils::Hashset<const FlowNode*, 32> visited_;
std::unordered_set<const FlowNode*> stop_nodes_; utils::Hashset<const FlowNode*, 32> stop_nodes_;
std::unordered_map<const FlowNode*, size_t> flow_node_to_id_; utils::Hashmap<const FlowNode*, size_t, 32> flow_node_ids_;
size_t next_node_id_ = 0; utils::Hashmap<const Value*, std::string, 32> value_ids_;
uint32_t indent_size_ = 0; uint32_t indent_size_ = 0;
bool in_function_ = false; bool in_function_ = false;
}; };

View File

@ -19,7 +19,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Discard);
namespace tint::ir { namespace tint::ir {
Discard::Discard() : Base(kNoID, nullptr, utils::Empty) {} Discard::Discard() : Base(nullptr, utils::Empty) {}
Discard::~Discard() = default; Discard::~Discard() = default;

View File

@ -20,7 +20,7 @@ namespace tint::ir {
Instruction::Instruction() = default; Instruction::Instruction() = default;
Instruction::Instruction(uint32_t identifier, const type::Type* ty) : id(identifier), type(ty) {} Instruction::Instruction(const type::Type* ty) : type(ty) {}
Instruction::~Instruction() = default; Instruction::~Instruction() = default;

View File

@ -23,9 +23,6 @@ namespace tint::ir {
/// An instruction in the IR. /// An instruction in the IR.
class Instruction : public utils::Castable<Instruction, Value> { class Instruction : public utils::Castable<Instruction, Value> {
public: public:
/// The identifier used by instructions that have no value.
static constexpr uint32_t kNoID = 0;
Instruction(const Instruction& inst) = delete; Instruction(const Instruction& inst) = delete;
Instruction(Instruction&& inst) = delete; Instruction(Instruction&& inst) = delete;
/// Destructor /// Destructor
@ -37,9 +34,6 @@ class Instruction : public utils::Castable<Instruction, Value> {
/// @returns the type of the value /// @returns the type of the value
const type::Type* Type() const override { return type; } const type::Type* Type() const override { return type; }
/// The instruction identifier
const uint32_t id = kNoID;
/// The instruction type /// The instruction type
const type::Type* type = nullptr; const type::Type* type = nullptr;
@ -47,9 +41,8 @@ class Instruction : public utils::Castable<Instruction, Value> {
/// Constructor /// Constructor
Instruction(); Instruction();
/// Constructor /// Constructor
/// @param id the instruction id
/// @param type the result type /// @param type the result type
Instruction(uint32_t id, const type::Type* type); explicit Instruction(const type::Type* type);
}; };
} // namespace tint::ir } // namespace tint::ir

View File

@ -19,8 +19,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Unary);
namespace tint::ir { namespace tint::ir {
Unary::Unary(uint32_t identifier, Kind kind, const type::Type* ty, Value* val) Unary::Unary(Kind kind, const type::Type* ty, Value* val) : Base(ty), kind_(kind), val_(val) {
: Base(identifier, ty), kind_(kind), val_(val) {
TINT_ASSERT(IR, val_); TINT_ASSERT(IR, val_);
val_->AddUsage(this); val_->AddUsage(this);
} }

View File

@ -32,11 +32,10 @@ class Unary : public utils::Castable<Unary, Instruction> {
}; };
/// Constructor /// Constructor
/// @param id the instruction id
/// @param kind the kind of unary instruction /// @param kind the kind of unary instruction
/// @param type the result type /// @param type the result type
/// @param val the lhs of the instruction /// @param val the lhs of the instruction
Unary(uint32_t id, Kind kind, const type::Type* type, Value* val); Unary(Kind kind, const type::Type* type, Value* val);
Unary(const Unary& inst) = delete; Unary(const Unary& inst) = delete;
Unary(Unary&& inst) = delete; Unary(Unary&& inst) = delete;
~Unary() override; ~Unary() override;

View File

@ -22,11 +22,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::UserCall);
namespace tint::ir { namespace tint::ir {
UserCall::UserCall(uint32_t identifier, UserCall::UserCall(const type::Type* ty, Symbol n, utils::VectorRef<Value*> arguments)
const type::Type* ty, : Base(ty, std::move(arguments)), name(n) {}
Symbol n,
utils::VectorRef<Value*> arguments)
: Base(identifier, ty, std::move(arguments)), name(n) {}
UserCall::~UserCall() = default; UserCall::~UserCall() = default;

View File

@ -25,11 +25,10 @@ namespace tint::ir {
class UserCall : public utils::Castable<UserCall, Call> { class UserCall : public utils::Castable<UserCall, Call> {
public: public:
/// Constructor /// Constructor
/// @param id the instruction id
/// @param type the result type /// @param type the result type
/// @param name the function name /// @param name the function name
/// @param args the function arguments /// @param args the function arguments
UserCall(uint32_t id, const type::Type* type, Symbol name, utils::VectorRef<Value*> args); UserCall(const type::Type* type, Symbol name, utils::VectorRef<Value*> args);
UserCall(const UserCall& inst) = delete; UserCall(const UserCall& inst) = delete;
UserCall(UserCall&& inst) = delete; UserCall(UserCall&& inst) = delete;
~UserCall() override; ~UserCall() override;

View File

@ -19,11 +19,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Var);
namespace tint::ir { namespace tint::ir {
Var::Var(uint32_t identifier, Var::Var(const type::Type* ty, builtin::AddressSpace addr_space, builtin::Access acc)
const type::Type* ty, : Base(ty), address_space(addr_space), access(acc) {}
builtin::AddressSpace addr_space,
builtin::Access acc)
: Base(identifier, ty), address_space(addr_space), access(acc) {}
Var::~Var() = default; Var::~Var() = default;

View File

@ -26,14 +26,10 @@ namespace tint::ir {
class Var : public utils::Castable<Var, Instruction> { class Var : public utils::Castable<Var, Instruction> {
public: public:
/// Constructor /// Constructor
/// @param id the instruction id
/// @param type the type /// @param type the type
/// @param address_space the address space of the var /// @param address_space the address space of the var
/// @param access the access mode of the var /// @param access the access mode of the var
Var(uint32_t id, Var(const type::Type* type, builtin::AddressSpace address_space, builtin::Access access);
const type::Type* type,
builtin::AddressSpace address_space,
builtin::Access access);
Var(const Var& inst) = delete; Var(const Var& inst) = delete;
Var(Var&& inst) = delete; Var(Var&& inst) = delete;
~Var() override; ~Var() override;