From 31e0850560d3cd937833c3111a41750eb49e585e Mon Sep 17 00:00:00 2001 From: dan sinclair Date: Tue, 29 Nov 2022 23:29:47 +0000 Subject: [PATCH] [ir] Convert instruction to a pointer This CL updates the instruction class to be a `Castable` and allocated from an Arena. Uses are updated to store the const pointer. Bug: tint:1718 Change-Id: Ie0b8353cb0c6fe6e2ba6e01bcd45871891aef903 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112045 Commit-Queue: Dan Sinclair Reviewed-by: Ben Clayton Kokoro: Kokoro --- src/tint/ir/block.h | 2 +- src/tint/ir/builder.cc | 42 ++-- src/tint/ir/builder.h | 40 ++-- src/tint/ir/builder_impl.cc | 5 +- src/tint/ir/disassembler.cc | 4 +- src/tint/ir/instruction.cc | 2 + src/tint/ir/instruction.h | 3 +- src/tint/ir/instruction_test.cc | 401 ++++++++++++++++---------------- src/tint/ir/module.h | 3 + 9 files changed, 258 insertions(+), 244 deletions(-) diff --git a/src/tint/ir/block.h b/src/tint/ir/block.h index d27fdf4d64..ac9028bfb0 100644 --- a/src/tint/ir/block.h +++ b/src/tint/ir/block.h @@ -34,7 +34,7 @@ class Block : public Castable { const FlowNode* branch_target = nullptr; /// The instructions in the block - utils::Vector instructions; + utils::Vector instructions; }; } // namespace tint::ir diff --git a/src/tint/ir/builder.cc b/src/tint/ir/builder.cc index 6f5e9c692f..5c55b91a47 100644 --- a/src/tint/ir/builder.cc +++ b/src/tint/ir/builder.cc @@ -97,79 +97,81 @@ Temp::Id Builder::AllocateTempId() { return next_temp_id++; } -Instruction Builder::CreateInstruction(Instruction::Kind kind, const Value* lhs, const Value* rhs) { - return Instruction(kind, Temp(), lhs, rhs); +const Instruction* Builder::CreateInstruction(Instruction::Kind kind, + const Value* lhs, + const Value* rhs) { + return ir.instructions.Create(kind, Temp(), lhs, rhs); } -Instruction Builder::And(const Value* lhs, const Value* rhs) { +const Instruction* Builder::And(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kAnd, lhs, rhs); } -Instruction Builder::Or(const Value* lhs, const Value* rhs) { +const Instruction* Builder::Or(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kOr, lhs, rhs); } -Instruction Builder::Xor(const Value* lhs, const Value* rhs) { +const Instruction* Builder::Xor(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kXor, lhs, rhs); } -Instruction Builder::LogicalAnd(const Value* lhs, const Value* rhs) { +const Instruction* Builder::LogicalAnd(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kLogicalAnd, lhs, rhs); } -Instruction Builder::LogicalOr(const Value* lhs, const Value* rhs) { +const Instruction* Builder::LogicalOr(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kLogicalOr, lhs, rhs); } -Instruction Builder::Equal(const Value* lhs, const Value* rhs) { +const Instruction* Builder::Equal(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kEqual, lhs, rhs); } -Instruction Builder::NotEqual(const Value* lhs, const Value* rhs) { +const Instruction* Builder::NotEqual(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kNotEqual, lhs, rhs); } -Instruction Builder::LessThan(const Value* lhs, const Value* rhs) { +const Instruction* Builder::LessThan(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kLessThan, lhs, rhs); } -Instruction Builder::GreaterThan(const Value* lhs, const Value* rhs) { +const Instruction* Builder::GreaterThan(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kGreaterThan, lhs, rhs); } -Instruction Builder::LessThanEqual(const Value* lhs, const Value* rhs) { +const Instruction* Builder::LessThanEqual(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kLessThanEqual, lhs, rhs); } -Instruction Builder::GreaterThanEqual(const Value* lhs, const Value* rhs) { +const Instruction* Builder::GreaterThanEqual(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kGreaterThanEqual, lhs, rhs); } -Instruction Builder::ShiftLeft(const Value* lhs, const Value* rhs) { +const Instruction* Builder::ShiftLeft(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kShiftLeft, lhs, rhs); } -Instruction Builder::ShiftRight(const Value* lhs, const Value* rhs) { +const Instruction* Builder::ShiftRight(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kShiftRight, lhs, rhs); } -Instruction Builder::Add(const Value* lhs, const Value* rhs) { +const Instruction* Builder::Add(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kAdd, lhs, rhs); } -Instruction Builder::Subtract(const Value* lhs, const Value* rhs) { +const Instruction* Builder::Subtract(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kSubtract, lhs, rhs); } -Instruction Builder::Multiply(const Value* lhs, const Value* rhs) { +const Instruction* Builder::Multiply(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kMultiply, lhs, rhs); } -Instruction Builder::Divide(const Value* lhs, const Value* rhs) { +const Instruction* Builder::Divide(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kDivide, lhs, rhs); } -Instruction Builder::Modulo(const Value* lhs, const Value* rhs) { +const Instruction* Builder::Modulo(const Value* lhs, const Value* rhs) { return CreateInstruction(Instruction::Kind::kModulo, lhs, rhs); } diff --git a/src/tint/ir/builder.h b/src/tint/ir/builder.h index bc30a951b5..d5065b8e30 100644 --- a/src/tint/ir/builder.h +++ b/src/tint/ir/builder.h @@ -102,115 +102,117 @@ class Builder { /// @param lhs the left-hand-side of the operation /// @param rhs the right-hand-side of the operation /// @returns the operation - Instruction CreateInstruction(Instruction::Kind kind, const Value* lhs, const Value* rhs); + const Instruction* CreateInstruction(Instruction::Kind kind, + const Value* lhs, + const Value* rhs); /// Creates an And operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction And(const Value* lhs, const Value* rhs); + const Instruction* And(const Value* lhs, const Value* rhs); /// Creates an Or operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction Or(const Value* lhs, const Value* rhs); + const Instruction* Or(const Value* lhs, const Value* rhs); /// Creates an Xor operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction Xor(const Value* lhs, const Value* rhs); + const Instruction* Xor(const Value* lhs, const Value* rhs); /// Creates an LogicalAnd operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction LogicalAnd(const Value* lhs, const Value* rhs); + const Instruction* LogicalAnd(const Value* lhs, const Value* rhs); /// Creates an LogicalOr operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction LogicalOr(const Value* lhs, const Value* rhs); + const Instruction* LogicalOr(const Value* lhs, const Value* rhs); /// Creates an Equal operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction Equal(const Value* lhs, const Value* rhs); + const Instruction* Equal(const Value* lhs, const Value* rhs); /// Creates an NotEqual operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction NotEqual(const Value* lhs, const Value* rhs); + const Instruction* NotEqual(const Value* lhs, const Value* rhs); /// Creates an LessThan operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction LessThan(const Value* lhs, const Value* rhs); + const Instruction* LessThan(const Value* lhs, const Value* rhs); /// Creates an GreaterThan operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction GreaterThan(const Value* lhs, const Value* rhs); + const Instruction* GreaterThan(const Value* lhs, const Value* rhs); /// Creates an LessThanEqual operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction LessThanEqual(const Value* lhs, const Value* rhs); + const Instruction* LessThanEqual(const Value* lhs, const Value* rhs); /// Creates an GreaterThanEqual operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction GreaterThanEqual(const Value* lhs, const Value* rhs); + const Instruction* GreaterThanEqual(const Value* lhs, const Value* rhs); /// Creates an ShiftLeft operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction ShiftLeft(const Value* lhs, const Value* rhs); + const Instruction* ShiftLeft(const Value* lhs, const Value* rhs); /// Creates an ShiftRight operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction ShiftRight(const Value* lhs, const Value* rhs); + const Instruction* ShiftRight(const Value* lhs, const Value* rhs); /// Creates an Add operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction Add(const Value* lhs, const Value* rhs); + const Instruction* Add(const Value* lhs, const Value* rhs); /// Creates an Subtract operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction Subtract(const Value* lhs, const Value* rhs); + const Instruction* Subtract(const Value* lhs, const Value* rhs); /// Creates an Multiply operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction Multiply(const Value* lhs, const Value* rhs); + const Instruction* Multiply(const Value* lhs, const Value* rhs); /// Creates an Divide operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction Divide(const Value* lhs, const Value* rhs); + const Instruction* Divide(const Value* lhs, const Value* rhs); /// Creates an Modulo operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Instruction Modulo(const Value* lhs, const Value* rhs); + const Instruction* Modulo(const Value* lhs, const Value* rhs); /// @returns a unique temp id Temp::Id AllocateTempId(); diff --git a/src/tint/ir/builder_impl.cc b/src/tint/ir/builder_impl.cc index 7700512e09..2286bf43ec 100644 --- a/src/tint/ir/builder_impl.cc +++ b/src/tint/ir/builder_impl.cc @@ -562,7 +562,7 @@ utils::Result BuilderImpl::EmitBinary(const ast::BinaryExpression* return utils::Failure; } - Instruction instr; + const Instruction* instr = nullptr; switch (expr->op) { case ast::BinaryOp::kAnd: instr = builder.And(lhs.Get(), rhs.Get()); @@ -623,9 +623,8 @@ utils::Result BuilderImpl::EmitBinary(const ast::BinaryExpression* return utils::Failure; } - auto* result = instr.Result(); current_flow_block->instructions.Push(instr); - return utils::Result(result); + return utils::Result(instr->Result()); } utils::Result BuilderImpl::EmitLiteral(const ast::LiteralExpression* lit) { diff --git a/src/tint/ir/disassembler.cc b/src/tint/ir/disassembler.cc index f98950fac0..e2749a1760 100644 --- a/src/tint/ir/disassembler.cc +++ b/src/tint/ir/disassembler.cc @@ -62,8 +62,8 @@ std::ostream& Disassembler::Indent() { } void Disassembler::EmitBlockInstructions(const Block* b) { - for (const auto& instr : b->instructions) { - out_ << instr << std::endl; + for (const auto* instr : b->instructions) { + out_ << *instr << std::endl; } } diff --git a/src/tint/ir/instruction.cc b/src/tint/ir/instruction.cc index a46d17ceab..6c0f1767e4 100644 --- a/src/tint/ir/instruction.cc +++ b/src/tint/ir/instruction.cc @@ -14,6 +14,8 @@ #include "src/tint/ir/instruction.h" +TINT_INSTANTIATE_TYPEINFO(tint::ir::Instruction); + namespace tint::ir { Instruction::Instruction() {} diff --git a/src/tint/ir/instruction.h b/src/tint/ir/instruction.h index 17351155ea..461b1f707b 100644 --- a/src/tint/ir/instruction.h +++ b/src/tint/ir/instruction.h @@ -17,6 +17,7 @@ #include +#include "src/tint/castable.h" #include "src/tint/debug.h" #include "src/tint/ir/value.h" #include "src/tint/utils/vector.h" @@ -24,7 +25,7 @@ namespace tint::ir { /// An instruction in the IR. -class Instruction { +class Instruction : public Castable { public: /// The kind of instruction. enum class Kind { diff --git a/src/tint/ir/instruction_test.cc b/src/tint/ir/instruction_test.cc index d6c8d8a0c7..0957903cf3 100644 --- a/src/tint/ir/instruction_test.cc +++ b/src/tint/ir/instruction_test.cc @@ -26,27 +26,27 @@ TEST_F(IR_InstructionTest, CreateAnd) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.And(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.And(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kAnd); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kAnd); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 & 2"); } @@ -54,27 +54,27 @@ TEST_F(IR_InstructionTest, CreateOr) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.Or(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.Or(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kOr); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kOr); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 | 2"); } @@ -82,27 +82,27 @@ TEST_F(IR_InstructionTest, CreateXor) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.Xor(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.Xor(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kXor); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kXor); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 ^ 2"); } @@ -110,27 +110,28 @@ TEST_F(IR_InstructionTest, CreateLogicalAnd) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.LogicalAnd(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = + b.builder.LogicalAnd(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLogicalAnd); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kLogicalAnd); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 && 2"); } @@ -138,27 +139,27 @@ TEST_F(IR_InstructionTest, CreateLogicalOr) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.LogicalOr(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.LogicalOr(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLogicalOr); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kLogicalOr); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 || 2"); } @@ -166,27 +167,27 @@ TEST_F(IR_InstructionTest, CreateEqual) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.Equal(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.Equal(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kEqual); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kEqual); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 == 2"); } @@ -194,27 +195,27 @@ TEST_F(IR_InstructionTest, CreateNotEqual) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.NotEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.NotEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kNotEqual); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kNotEqual); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 != 2"); } @@ -222,27 +223,27 @@ TEST_F(IR_InstructionTest, CreateLessThan) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.LessThan(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.LessThan(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLessThan); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kLessThan); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 < 2"); } @@ -250,27 +251,28 @@ TEST_F(IR_InstructionTest, CreateGreaterThan) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.GreaterThan(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = + b.builder.GreaterThan(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kGreaterThan); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kGreaterThan); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 > 2"); } @@ -278,27 +280,28 @@ TEST_F(IR_InstructionTest, CreateLessThanEqual) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.LessThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = + b.builder.LessThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLessThanEqual); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kLessThanEqual); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 <= 2"); } @@ -306,27 +309,28 @@ TEST_F(IR_InstructionTest, CreateGreaterThanEqual) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.GreaterThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = + b.builder.GreaterThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kGreaterThanEqual); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kGreaterThanEqual); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 >= 2"); } @@ -334,27 +338,27 @@ TEST_F(IR_InstructionTest, CreateShiftLeft) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.ShiftLeft(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.ShiftLeft(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kShiftLeft); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kShiftLeft); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 << 2"); } @@ -362,27 +366,28 @@ TEST_F(IR_InstructionTest, CreateShiftRight) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.ShiftRight(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = + b.builder.ShiftRight(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kShiftRight); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kShiftRight); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 >> 2"); } @@ -390,27 +395,27 @@ TEST_F(IR_InstructionTest, CreateAdd) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.Add(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.Add(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kAdd); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kAdd); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 + 2"); } @@ -418,27 +423,27 @@ TEST_F(IR_InstructionTest, CreateSubtract) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.Subtract(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.Subtract(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kSubtract); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kSubtract); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 - 2"); } @@ -446,27 +451,27 @@ TEST_F(IR_InstructionTest, CreateMultiply) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.Multiply(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.Multiply(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kMultiply); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kMultiply); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 * 2"); } @@ -474,27 +479,27 @@ TEST_F(IR_InstructionTest, CreateDivide) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.Divide(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.Divide(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kDivide); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kDivide); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 / 2"); } @@ -502,27 +507,27 @@ TEST_F(IR_InstructionTest, CreateModulo) { auto& b = CreateEmptyBuilder(); b.builder.next_temp_id = Temp::Id(42); - auto instr = b.builder.Modulo(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); + const auto* instr = b.builder.Modulo(b.builder.Constant(i32(4)), b.builder.Constant(i32(2))); - EXPECT_EQ(instr.GetKind(), Instruction::Kind::kModulo); + EXPECT_EQ(instr->GetKind(), Instruction::Kind::kModulo); - ASSERT_TRUE(instr.Result()->Is()); - EXPECT_EQ(Temp::Id(42), instr.Result()->As()->AsId()); + ASSERT_TRUE(instr->Result()->Is()); + EXPECT_EQ(Temp::Id(42), instr->Result()->As()->AsId()); - ASSERT_TRUE(instr.HasLHS()); - ASSERT_TRUE(instr.LHS()->Is()); - auto lhs = instr.LHS()->As(); + ASSERT_TRUE(instr->HasLHS()); + ASSERT_TRUE(instr->LHS()->Is()); + auto lhs = instr->LHS()->As(); ASSERT_TRUE(lhs->IsI32()); EXPECT_EQ(i32(4), lhs->AsI32()); - ASSERT_TRUE(instr.HasRHS()); - ASSERT_TRUE(instr.RHS()->Is()); - auto rhs = instr.RHS()->As(); + ASSERT_TRUE(instr->HasRHS()); + ASSERT_TRUE(instr->RHS()->Is()); + auto rhs = instr->RHS()->As(); ASSERT_TRUE(rhs->IsI32()); EXPECT_EQ(i32(2), rhs->AsI32()); std::stringstream str; - str << instr; + str << *instr; EXPECT_EQ(str.str(), "%42 = 4 % 2"); } diff --git a/src/tint/ir/module.h b/src/tint/ir/module.h index 1e2f8b091c..d95a13e1cc 100644 --- a/src/tint/ir/module.h +++ b/src/tint/ir/module.h @@ -18,6 +18,7 @@ #include #include "src/tint/ir/function.h" +#include "src/tint/ir/instruction.h" #include "src/tint/ir/value.h" #include "src/tint/utils/block_allocator.h" #include "src/tint/utils/result.h" @@ -69,6 +70,8 @@ class Module { utils::BlockAllocator flow_nodes; /// The value allocator utils::BlockAllocator values; + /// The instruction allocator + utils::BlockAllocator instructions; /// List of functions in the program utils::Vector functions;