[ir] Make Value a pointer stored in the module.

This CL moves the Value class to pointers stored in the module.

Bug: tint:1718
Change-Id: I0441e898c011b34b0fe2f8ca716ea26c9c566bd7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112043
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
dan sinclair 2022-11-29 20:36:59 +00:00 committed by Dawn LUCI CQ
parent 028092a843
commit 2d108ae5ed
14 changed files with 273 additions and 281 deletions

View File

@ -97,79 +97,79 @@ Value::Id Builder::AllocateValue() {
return next_value_id++; return next_value_id++;
} }
Instruction Builder::CreateInstruction(Instruction::Kind kind, Value lhs, Value rhs) { Instruction Builder::CreateInstruction(Instruction::Kind kind, const Value* lhs, const Value* rhs) {
return Instruction(kind, Value(AllocateValue()), lhs, rhs); return Instruction(kind, MkValue(AllocateValue()), lhs, rhs);
} }
Instruction Builder::And(Value lhs, Value rhs) { Instruction Builder::And(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kAnd, lhs, rhs); return CreateInstruction(Instruction::Kind::kAnd, lhs, rhs);
} }
Instruction Builder::Or(Value lhs, Value rhs) { Instruction Builder::Or(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kOr, lhs, rhs); return CreateInstruction(Instruction::Kind::kOr, lhs, rhs);
} }
Instruction Builder::Xor(Value lhs, Value rhs) { Instruction Builder::Xor(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kXor, lhs, rhs); return CreateInstruction(Instruction::Kind::kXor, lhs, rhs);
} }
Instruction Builder::LogicalAnd(Value lhs, Value rhs) { Instruction Builder::LogicalAnd(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kLogicalAnd, lhs, rhs); return CreateInstruction(Instruction::Kind::kLogicalAnd, lhs, rhs);
} }
Instruction Builder::LogicalOr(Value lhs, Value rhs) { Instruction Builder::LogicalOr(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kLogicalOr, lhs, rhs); return CreateInstruction(Instruction::Kind::kLogicalOr, lhs, rhs);
} }
Instruction Builder::Equal(Value lhs, Value rhs) { Instruction Builder::Equal(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kEqual, lhs, rhs); return CreateInstruction(Instruction::Kind::kEqual, lhs, rhs);
} }
Instruction Builder::NotEqual(Value lhs, Value rhs) { Instruction Builder::NotEqual(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kNotEqual, lhs, rhs); return CreateInstruction(Instruction::Kind::kNotEqual, lhs, rhs);
} }
Instruction Builder::LessThan(Value lhs, Value rhs) { Instruction Builder::LessThan(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kLessThan, lhs, rhs); return CreateInstruction(Instruction::Kind::kLessThan, lhs, rhs);
} }
Instruction Builder::GreaterThan(Value lhs, Value rhs) { Instruction Builder::GreaterThan(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kGreaterThan, lhs, rhs); return CreateInstruction(Instruction::Kind::kGreaterThan, lhs, rhs);
} }
Instruction Builder::LessThanEqual(Value lhs, Value rhs) { Instruction Builder::LessThanEqual(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kLessThanEqual, lhs, rhs); return CreateInstruction(Instruction::Kind::kLessThanEqual, lhs, rhs);
} }
Instruction Builder::GreaterThanEqual(Value lhs, Value rhs) { Instruction Builder::GreaterThanEqual(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kGreaterThanEqual, lhs, rhs); return CreateInstruction(Instruction::Kind::kGreaterThanEqual, lhs, rhs);
} }
Instruction Builder::ShiftLeft(Value lhs, Value rhs) { Instruction Builder::ShiftLeft(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kShiftLeft, lhs, rhs); return CreateInstruction(Instruction::Kind::kShiftLeft, lhs, rhs);
} }
Instruction Builder::ShiftRight(Value lhs, Value rhs) { Instruction Builder::ShiftRight(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kShiftRight, lhs, rhs); return CreateInstruction(Instruction::Kind::kShiftRight, lhs, rhs);
} }
Instruction Builder::Add(Value lhs, Value rhs) { Instruction Builder::Add(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kAdd, lhs, rhs); return CreateInstruction(Instruction::Kind::kAdd, lhs, rhs);
} }
Instruction Builder::Subtract(Value lhs, Value rhs) { Instruction Builder::Subtract(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kSubtract, lhs, rhs); return CreateInstruction(Instruction::Kind::kSubtract, lhs, rhs);
} }
Instruction Builder::Multiply(Value lhs, Value rhs) { Instruction Builder::Multiply(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kMultiply, lhs, rhs); return CreateInstruction(Instruction::Kind::kMultiply, lhs, rhs);
} }
Instruction Builder::Divide(Value lhs, Value rhs) { Instruction Builder::Divide(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kDivide, lhs, rhs); return CreateInstruction(Instruction::Kind::kDivide, lhs, rhs);
} }
Instruction Builder::Modulo(Value lhs, Value rhs) { Instruction Builder::Modulo(const Value* lhs, const Value* rhs) {
return CreateInstruction(Instruction::Kind::kModulo, lhs, rhs); return CreateInstruction(Instruction::Kind::kModulo, lhs, rhs);
} }

View File

@ -83,120 +83,128 @@ class Builder {
/// @param to the node to branch too /// @param to the node to branch too
void Branch(Block* from, FlowNode* to); void Branch(Block* from, FlowNode* to);
/// Creates a new Value
/// @param val the value
/// @returns the new Value
template <typename T>
const Value* MkValue(T val) {
return ir.values.Create<Value>(val);
}
/// Creates an op for `lhs kind rhs` /// Creates an op for `lhs kind rhs`
/// @param kind the kind of operation /// @param kind the kind of operation
/// @param lhs the left-hand-side of the operation /// @param lhs the left-hand-side of the operation
/// @param rhs the right-hand-side of the operation /// @param rhs the right-hand-side of the operation
/// @returns the operation /// @returns the operation
Instruction CreateInstruction(Instruction::Kind kind, Value lhs, Value rhs); Instruction CreateInstruction(Instruction::Kind kind, const Value* lhs, const Value* rhs);
/// Creates an And operation /// Creates an And operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction And(Value lhs, Value rhs); Instruction And(const Value* lhs, const Value* rhs);
/// Creates an Or operation /// Creates an Or operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction Or(Value lhs, Value rhs); Instruction Or(const Value* lhs, const Value* rhs);
/// Creates an Xor operation /// Creates an Xor operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction Xor(Value lhs, Value rhs); Instruction Xor(const Value* lhs, const Value* rhs);
/// Creates an LogicalAnd operation /// Creates an LogicalAnd operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction LogicalAnd(Value lhs, Value rhs); Instruction LogicalAnd(const Value* lhs, const Value* rhs);
/// Creates an LogicalOr operation /// Creates an LogicalOr operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction LogicalOr(Value lhs, Value rhs); Instruction LogicalOr(const Value* lhs, const Value* rhs);
/// Creates an Equal operation /// Creates an Equal operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction Equal(Value lhs, Value rhs); Instruction Equal(const Value* lhs, const Value* rhs);
/// Creates an NotEqual operation /// Creates an NotEqual operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction NotEqual(Value lhs, Value rhs); Instruction NotEqual(const Value* lhs, const Value* rhs);
/// Creates an LessThan operation /// Creates an LessThan operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction LessThan(Value lhs, Value rhs); Instruction LessThan(const Value* lhs, const Value* rhs);
/// Creates an GreaterThan operation /// Creates an GreaterThan operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction GreaterThan(Value lhs, Value rhs); Instruction GreaterThan(const Value* lhs, const Value* rhs);
/// Creates an LessThanEqual operation /// Creates an LessThanEqual operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction LessThanEqual(Value lhs, Value rhs); Instruction LessThanEqual(const Value* lhs, const Value* rhs);
/// Creates an GreaterThanEqual operation /// Creates an GreaterThanEqual operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction GreaterThanEqual(Value lhs, Value rhs); Instruction GreaterThanEqual(const Value* lhs, const Value* rhs);
/// Creates an ShiftLeft operation /// Creates an ShiftLeft operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction ShiftLeft(Value lhs, Value rhs); Instruction ShiftLeft(const Value* lhs, const Value* rhs);
/// Creates an ShiftRight operation /// Creates an ShiftRight operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction ShiftRight(Value lhs, Value rhs); Instruction ShiftRight(const Value* lhs, const Value* rhs);
/// Creates an Add operation /// Creates an Add operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction Add(Value lhs, Value rhs); Instruction Add(const Value* lhs, const Value* rhs);
/// Creates an Subtract operation /// Creates an Subtract operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction Subtract(Value lhs, Value rhs); Instruction Subtract(const Value* lhs, const Value* rhs);
/// Creates an Multiply operation /// Creates an Multiply operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction Multiply(Value lhs, Value rhs); Instruction Multiply(const Value* lhs, const Value* rhs);
/// Creates an Divide operation /// Creates an Divide operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction Divide(Value lhs, Value rhs); Instruction Divide(const Value* lhs, const Value* rhs);
/// Creates an Modulo operation /// Creates an Modulo operation
/// @param lhs the lhs of the add /// @param lhs the lhs of the add
/// @param rhs the rhs of the add /// @param rhs the rhs of the add
/// @returns the operation /// @returns the operation
Instruction Modulo(Value lhs, Value rhs); Instruction Modulo(const Value* lhs, const Value* rhs);
/// @returns a unique Value id /// @returns a unique Value id
Value::Id AllocateValue(); Value::Id AllocateValue();

View File

@ -516,7 +516,7 @@ bool BuilderImpl::EmitBreakIf(const ast::BreakIfStatement* stmt) {
return true; return true;
} }
utils::Result<Value> BuilderImpl::EmitExpression(const ast::Expression* expr) { utils::Result<const Value*> BuilderImpl::EmitExpression(const ast::Expression* expr) {
return tint::Switch( return tint::Switch(
expr, expr,
// [&](const ast::IndexAccessorExpression* a) { return EmitIndexAccessor(a); }, // [&](const ast::IndexAccessorExpression* a) { return EmitIndexAccessor(a); },
@ -551,7 +551,7 @@ bool BuilderImpl::EmitVariable(const ast::Variable* var) {
}); });
} }
utils::Result<Value> BuilderImpl::EmitBinary(const ast::BinaryExpression* expr) { utils::Result<const Value*> BuilderImpl::EmitBinary(const ast::BinaryExpression* expr) {
auto lhs = EmitExpression(expr->lhs); auto lhs = EmitExpression(expr->lhs);
if (!lhs) { if (!lhs) {
return utils::Failure; return utils::Failure;
@ -623,26 +623,29 @@ utils::Result<Value> BuilderImpl::EmitBinary(const ast::BinaryExpression* expr)
return utils::Failure; return utils::Failure;
} }
auto result = instr.Result(); auto* result = instr.Result();
current_flow_block->instructions.Push(instr); current_flow_block->instructions.Push(instr);
return result; return utils::Result<const Value*>(result);
} }
utils::Result<Value> BuilderImpl::EmitLiteral(const ast::LiteralExpression* lit) { utils::Result<const Value*> BuilderImpl::EmitLiteral(const ast::LiteralExpression* lit) {
return tint::Switch( // return tint::Switch( //
lit, lit,
[&](const ast::BoolLiteralExpression* l) { return utils::Result<Value>{Value(l->value)}; }, [&](const ast::BoolLiteralExpression* l) {
return utils::Result<const Value*>(builder.MkValue(l->value));
},
[&](const ast::FloatLiteralExpression* l) { [&](const ast::FloatLiteralExpression* l) {
if (l->suffix == ast::FloatLiteralExpression::Suffix::kF) { if (l->suffix == ast::FloatLiteralExpression::Suffix::kF) {
return utils::Result<Value>{Value(f32(static_cast<float>(l->value)))}; return utils::Result<const Value*>(
builder.MkValue(f32(static_cast<float>(l->value))));
} }
return utils::Result<Value>{Value(f16(static_cast<float>(l->value)))}; return utils::Result<const Value*>(builder.MkValue(f16(static_cast<float>(l->value))));
}, },
[&](const ast::IntLiteralExpression* l) { [&](const ast::IntLiteralExpression* l) {
if (l->suffix == ast::IntLiteralExpression::Suffix::kI) { if (l->suffix == ast::IntLiteralExpression::Suffix::kI) {
return utils::Result<Value>{Value(i32(l->value))}; return utils::Result<const Value*>(builder.MkValue(i32(l->value)));
} }
return utils::Result<Value>{Value(u32(l->value))}; return utils::Result<const Value*>(builder.MkValue(u32(l->value)));
}, },
[&](Default) { [&](Default) {
diagnostics_.add_warning(tint::diag::System::IR, diagnostics_.add_warning(tint::diag::System::IR,

View File

@ -140,7 +140,7 @@ class BuilderImpl {
/// Emits an expression /// Emits an expression
/// @param expr the expression to emit /// @param expr the expression to emit
/// @returns true if successful, false otherwise /// @returns true if successful, false otherwise
utils::Result<Value> EmitExpression(const ast::Expression* expr); utils::Result<const Value*> EmitExpression(const ast::Expression* expr);
/// Emits a variable /// Emits a variable
/// @param var the variable to emit /// @param var the variable to emit
@ -150,12 +150,12 @@ class BuilderImpl {
/// Emits a binary expression /// Emits a binary expression
/// @param expr the binary expression /// @param expr the binary expression
/// @returns the value storing the result if successful, utils::Failure otherwise /// @returns the value storing the result if successful, utils::Failure otherwise
utils::Result<Value> EmitBinary(const ast::BinaryExpression* expr); utils::Result<const Value*> EmitBinary(const ast::BinaryExpression* expr);
/// Emits a literal expression /// Emits a literal expression
/// @param lit the literal to emit /// @param lit the literal to emit
/// @returns true if successful, false otherwise /// @returns true if successful, false otherwise
utils::Result<Value> EmitLiteral(const ast::LiteralExpression* lit); utils::Result<const Value*> EmitLiteral(const ast::LiteralExpression* lit);
/// Emits a type /// Emits a type
/// @param ty the type to emit /// @param ty the type to emit

View File

@ -101,9 +101,9 @@ TEST_F(IR_BuilderImplTest, IfStatement) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
// Check condition // Check condition
auto instr = flow->condition; auto* instr = flow->condition;
ASSERT_TRUE(instr.IsBool()); ASSERT_TRUE(instr->IsBool());
EXPECT_TRUE(instr.AsBool()); EXPECT_TRUE(instr->AsBool());
} }
TEST_F(IR_BuilderImplTest, IfStatement_TrueReturns) { TEST_F(IR_BuilderImplTest, IfStatement_TrueReturns) {
@ -502,9 +502,9 @@ TEST_F(IR_BuilderImplTest, Loop_WithReturn) {
EXPECT_EQ(loop_flow->merge_target->branch_target, nullptr); EXPECT_EQ(loop_flow->merge_target->branch_target, nullptr);
// Check condition // Check condition
auto instr = if_flow->condition; auto* instr = if_flow->condition;
ASSERT_TRUE(instr.IsBool()); ASSERT_TRUE(instr->IsBool());
EXPECT_TRUE(instr.AsBool()); EXPECT_TRUE(instr->AsBool());
} }
TEST_F(IR_BuilderImplTest, Loop_WithOnlyReturn) { TEST_F(IR_BuilderImplTest, Loop_WithOnlyReturn) {
@ -947,9 +947,9 @@ TEST_F(IR_BuilderImplTest, While) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
// Check condition // Check condition
auto instr = if_flow->condition; auto* instr = if_flow->condition;
ASSERT_TRUE(instr.IsBool()); ASSERT_TRUE(instr->IsBool());
EXPECT_FALSE(instr.AsBool()); EXPECT_FALSE(instr->AsBool());
} }
TEST_F(IR_BuilderImplTest, While_Return) { TEST_F(IR_BuilderImplTest, While_Return) {
@ -1071,9 +1071,9 @@ TEST_F(IR_BuilderImplTest, DISABLED_For) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
// Check condition // Check condition
auto instr = if_flow->condition; auto* instr = if_flow->condition;
ASSERT_TRUE(instr.IsBool()); ASSERT_TRUE(instr->IsBool());
EXPECT_FALSE(instr.AsBool()); EXPECT_FALSE(instr->AsBool());
} }
TEST_F(IR_BuilderImplTest, For_NoInitCondOrContinuing) { TEST_F(IR_BuilderImplTest, For_NoInitCondOrContinuing) {
@ -1171,9 +1171,9 @@ TEST_F(IR_BuilderImplTest, Switch) {
EXPECT_EQ(flow->merge_target->branch_target, func->end_target); EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
// Check condition // Check condition
auto instr = flow->condition; auto* instr = flow->condition;
ASSERT_TRUE(instr.IsI32()); ASSERT_TRUE(instr->IsI32());
EXPECT_EQ(1_i, instr.AsI32()); EXPECT_EQ(1_i, instr->AsI32());
} }
TEST_F(IR_BuilderImplTest, Switch_OnlyDefault) { TEST_F(IR_BuilderImplTest, Switch_OnlyDefault) {
@ -1341,9 +1341,9 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_True) {
auto r = b.EmitLiteral(Expr(true)); auto r = b.EmitLiteral(Expr(true));
ASSERT_TRUE(r); ASSERT_TRUE(r);
auto reg = r.Get(); auto* val = r.Get();
EXPECT_TRUE(reg.IsBool()); EXPECT_TRUE(val->IsBool());
EXPECT_TRUE(reg.AsBool()); EXPECT_TRUE(val->AsBool());
} }
TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_False) { TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_False) {
@ -1351,9 +1351,9 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_False) {
auto r = b.EmitLiteral(Expr(false)); auto r = b.EmitLiteral(Expr(false));
ASSERT_TRUE(r); ASSERT_TRUE(r);
auto reg = r.Get(); auto val = r.Get();
EXPECT_TRUE(reg.IsBool()); EXPECT_TRUE(val->IsBool());
EXPECT_FALSE(reg.AsBool()); EXPECT_FALSE(val->AsBool());
} }
TEST_F(IR_BuilderImplTest, EmitLiteral_F32) { TEST_F(IR_BuilderImplTest, EmitLiteral_F32) {
@ -1361,9 +1361,9 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_F32) {
auto r = b.EmitLiteral(Expr(1.2_f)); auto r = b.EmitLiteral(Expr(1.2_f));
ASSERT_TRUE(r); ASSERT_TRUE(r);
auto reg = r.Get(); auto val = r.Get();
EXPECT_TRUE(reg.IsF32()); EXPECT_TRUE(val->IsF32());
EXPECT_EQ(1.2_f, reg.AsF32()); EXPECT_EQ(1.2_f, val->AsF32());
} }
TEST_F(IR_BuilderImplTest, EmitLiteral_F16) { TEST_F(IR_BuilderImplTest, EmitLiteral_F16) {
@ -1371,9 +1371,9 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_F16) {
auto r = b.EmitLiteral(Expr(1.2_h)); auto r = b.EmitLiteral(Expr(1.2_h));
ASSERT_TRUE(r); ASSERT_TRUE(r);
auto reg = r.Get(); auto val = r.Get();
EXPECT_TRUE(reg.IsF16()); EXPECT_TRUE(val->IsF16());
EXPECT_EQ(1.2_h, reg.AsF16()); EXPECT_EQ(1.2_h, val->AsF16());
} }
TEST_F(IR_BuilderImplTest, EmitLiteral_I32) { TEST_F(IR_BuilderImplTest, EmitLiteral_I32) {
@ -1381,9 +1381,9 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_I32) {
auto r = b.EmitLiteral(Expr(-2_i)); auto r = b.EmitLiteral(Expr(-2_i));
ASSERT_TRUE(r); ASSERT_TRUE(r);
auto reg = r.Get(); auto val = r.Get();
EXPECT_TRUE(reg.IsI32()); EXPECT_TRUE(val->IsI32());
EXPECT_EQ(-2_i, reg.AsI32()); EXPECT_EQ(-2_i, val->AsI32());
} }
TEST_F(IR_BuilderImplTest, EmitLiteral_U32) { TEST_F(IR_BuilderImplTest, EmitLiteral_U32) {
@ -1391,9 +1391,9 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_U32) {
auto r = b.EmitLiteral(Expr(2_u)); auto r = b.EmitLiteral(Expr(2_u));
ASSERT_TRUE(r); ASSERT_TRUE(r);
auto reg = r.Get(); auto val = r.Get();
EXPECT_TRUE(reg.IsU32()); EXPECT_TRUE(val->IsU32());
EXPECT_EQ(2_u, reg.AsU32()); EXPECT_EQ(2_u, val->AsU32());
} }
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Add) { TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Add) {

View File

@ -45,7 +45,7 @@ class If : public Castable<If, FlowNode> {
/// branches into it. (e.g. if both branches `return`) /// branches into it. (e.g. if both branches `return`)
Block* merge_target = nullptr; Block* merge_target = nullptr;
/// Value holding the condition result /// Value holding the condition result
Value condition; const Value* condition = nullptr;
}; };
} // namespace tint::ir } // namespace tint::ir

View File

@ -18,7 +18,7 @@ namespace tint::ir {
Instruction::Instruction() {} Instruction::Instruction() {}
Instruction::Instruction(Kind kind, Value result, Value lhs, Value rhs) Instruction::Instruction(Kind kind, const Value* result, const Value* lhs, const Value* rhs)
: kind_(kind), result_(result), args_({lhs, rhs}) {} : kind_(kind), result_(result), args_({lhs, rhs}) {}
Instruction::Instruction(const Instruction&) = default; Instruction::Instruction(const Instruction&) = default;
@ -32,9 +32,9 @@ Instruction& Instruction::operator=(const Instruction& instr) = default;
Instruction& Instruction::operator=(Instruction&& instr) = default; Instruction& Instruction::operator=(Instruction&& instr) = default;
std::ostream& operator<<(std::ostream& out, const Instruction& instr) { std::ostream& operator<<(std::ostream& out, const Instruction& instr) {
out << instr.Result() << " = "; out << *(instr.Result()) << " = ";
if (instr.HasLHS()) { if (instr.HasLHS()) {
out << instr.LHS(); out << *(instr.LHS());
} }
out << " "; out << " ";
@ -96,7 +96,7 @@ std::ostream& operator<<(std::ostream& out, const Instruction& instr) {
} }
if (instr.HasRHS()) { if (instr.HasRHS()) {
out << " " << instr.RHS(); out << " " << *(instr.RHS());
} }
return out; return out;

View File

@ -58,7 +58,7 @@ class Instruction {
/// @param result the result value /// @param result the result value
/// @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
Instruction(Kind kind, Value result, Value lhs, Value rhs); Instruction(Kind kind, const Value* result, const Value* lhs, const Value* rhs);
/// Copy constructor /// Copy constructor
/// @param instr the instruction to copy from /// @param instr the instruction to copy from
Instruction(const Instruction& instr); Instruction(const Instruction& instr);
@ -81,12 +81,12 @@ class Instruction {
Kind GetKind() const { return kind_; } Kind GetKind() const { return kind_; }
/// @returns the result value for the instruction /// @returns the result value for the instruction
const Value& Result() const { return result_; } const Value* Result() const { return result_; }
/// @returns true if the instruction has a LHS /// @returns true if the instruction has a LHS
bool HasLHS() const { return args_.Length() >= 1; } bool HasLHS() const { return args_.Length() >= 1; }
/// @returns the left-hand-side value for the instruction /// @returns the left-hand-side value for the instruction
const Value& LHS() const { const Value* LHS() const {
TINT_ASSERT(IR, HasLHS()); TINT_ASSERT(IR, HasLHS());
return args_[0]; return args_[0];
} }
@ -94,7 +94,7 @@ class Instruction {
/// @returns true if the instruction has a RHS /// @returns true if the instruction has a RHS
bool HasRHS() const { return args_.Length() >= 2; } bool HasRHS() const { return args_.Length() >= 2; }
/// @returns the right-hand-side value for the instruction /// @returns the right-hand-side value for the instruction
const Value& RHS() const { const Value* RHS() const {
TINT_ASSERT(IR, HasRHS()); TINT_ASSERT(IR, HasRHS());
return args_[1]; return args_[1];
} }
@ -102,8 +102,8 @@ class Instruction {
private: private:
Kind kind_; Kind kind_;
Value result_; const Value* result_;
utils::Vector<Value, 2> args_; utils::Vector<const Value*, 2> args_;
}; };
std::ostream& operator<<(std::ostream& out, const Instruction&); std::ostream& operator<<(std::ostream& out, const Instruction&);

View File

@ -26,22 +26,22 @@ TEST_F(IR_InstructionTest, CreateAnd) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.And(Value(i32(4)), Value(i32(2))); auto instr = b.builder.And(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kAnd); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kAnd);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -52,22 +52,22 @@ TEST_F(IR_InstructionTest, CreateOr) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.Or(Value(i32(4)), Value(i32(2))); auto instr = b.builder.Or(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kOr); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kOr);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -78,22 +78,22 @@ TEST_F(IR_InstructionTest, CreateXor) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.Xor(Value(i32(4)), Value(i32(2))); auto instr = b.builder.Xor(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kXor); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kXor);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -104,22 +104,22 @@ TEST_F(IR_InstructionTest, CreateLogicalAnd) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.LogicalAnd(Value(i32(4)), Value(i32(2))); auto instr = b.builder.LogicalAnd(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLogicalAnd); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLogicalAnd);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -130,22 +130,22 @@ TEST_F(IR_InstructionTest, CreateLogicalOr) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.LogicalOr(Value(i32(4)), Value(i32(2))); auto instr = b.builder.LogicalOr(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLogicalOr); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLogicalOr);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -156,22 +156,22 @@ TEST_F(IR_InstructionTest, CreateEqual) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.Equal(Value(i32(4)), Value(i32(2))); auto instr = b.builder.Equal(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kEqual); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kEqual);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -182,22 +182,22 @@ TEST_F(IR_InstructionTest, CreateNotEqual) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.NotEqual(Value(i32(4)), Value(i32(2))); auto instr = b.builder.NotEqual(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kNotEqual); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kNotEqual);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -208,22 +208,22 @@ TEST_F(IR_InstructionTest, CreateLessThan) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.LessThan(Value(i32(4)), Value(i32(2))); auto instr = b.builder.LessThan(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLessThan); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLessThan);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -234,22 +234,22 @@ TEST_F(IR_InstructionTest, CreateGreaterThan) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.GreaterThan(Value(i32(4)), Value(i32(2))); auto instr = b.builder.GreaterThan(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kGreaterThan); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kGreaterThan);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -260,22 +260,22 @@ TEST_F(IR_InstructionTest, CreateLessThanEqual) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.LessThanEqual(Value(i32(4)), Value(i32(2))); auto instr = b.builder.LessThanEqual(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLessThanEqual); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLessThanEqual);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -286,22 +286,22 @@ TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.GreaterThanEqual(Value(i32(4)), Value(i32(2))); auto instr = b.builder.GreaterThanEqual(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kGreaterThanEqual); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kGreaterThanEqual);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -312,22 +312,22 @@ TEST_F(IR_InstructionTest, CreateShiftLeft) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.ShiftLeft(Value(i32(4)), Value(i32(2))); auto instr = b.builder.ShiftLeft(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kShiftLeft); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kShiftLeft);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -338,22 +338,22 @@ TEST_F(IR_InstructionTest, CreateShiftRight) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.ShiftRight(Value(i32(4)), Value(i32(2))); auto instr = b.builder.ShiftRight(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kShiftRight); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kShiftRight);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -364,22 +364,22 @@ TEST_F(IR_InstructionTest, CreateAdd) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.Add(Value(i32(4)), Value(i32(2))); auto instr = b.builder.Add(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kAdd); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kAdd);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -390,22 +390,22 @@ TEST_F(IR_InstructionTest, CreateSubtract) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.Subtract(Value(i32(4)), Value(i32(2))); auto instr = b.builder.Subtract(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kSubtract); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kSubtract);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -416,22 +416,22 @@ TEST_F(IR_InstructionTest, CreateMultiply) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.Multiply(Value(i32(4)), Value(i32(2))); auto instr = b.builder.Multiply(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kMultiply); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kMultiply);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -442,22 +442,22 @@ TEST_F(IR_InstructionTest, CreateDivide) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.Divide(Value(i32(4)), Value(i32(2))); auto instr = b.builder.Divide(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kDivide); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kDivide);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;
@ -468,22 +468,22 @@ TEST_F(IR_InstructionTest, CreateModulo) {
auto& b = CreateEmptyBuilder(); auto& b = CreateEmptyBuilder();
b.builder.next_value_id = Value::Id(42); b.builder.next_value_id = Value::Id(42);
auto instr = b.builder.Modulo(Value(i32(4)), Value(i32(2))); auto instr = b.builder.Modulo(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
EXPECT_EQ(instr.GetKind(), Instruction::Kind::kModulo); EXPECT_EQ(instr.GetKind(), Instruction::Kind::kModulo);
ASSERT_TRUE(instr.Result().IsTemp()); ASSERT_TRUE(instr.Result()->IsTemp());
EXPECT_EQ(Value::Id(42), instr.Result().AsId()); EXPECT_EQ(Value::Id(42), instr.Result()->AsId());
ASSERT_TRUE(instr.HasLHS()); ASSERT_TRUE(instr.HasLHS());
auto& lhs = instr.LHS(); auto lhs = instr.LHS();
ASSERT_TRUE(lhs.IsI32()); ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs.AsI32()); EXPECT_EQ(i32(4), lhs->AsI32());
ASSERT_TRUE(instr.HasRHS()); ASSERT_TRUE(instr.HasRHS());
auto& rhs = instr.RHS(); auto rhs = instr.RHS();
ASSERT_TRUE(rhs.IsI32()); ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs.AsI32()); EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str; std::stringstream str;
str << instr; str << instr;

View File

@ -18,6 +18,7 @@
#include <string> #include <string>
#include "src/tint/ir/function.h" #include "src/tint/ir/function.h"
#include "src/tint/ir/value.h"
#include "src/tint/utils/block_allocator.h" #include "src/tint/utils/block_allocator.h"
#include "src/tint/utils/result.h" #include "src/tint/utils/result.h"
#include "src/tint/utils/vector.h" #include "src/tint/utils/vector.h"
@ -66,6 +67,8 @@ class Module {
/// The flow node allocator /// The flow node allocator
utils::BlockAllocator<FlowNode> flow_nodes; utils::BlockAllocator<FlowNode> flow_nodes;
/// The value allocator
utils::BlockAllocator<Value> values;
/// List of functions in the program /// List of functions in the program
utils::Vector<Function*, 8> functions; utils::Vector<Function*, 8> functions;

View File

@ -53,7 +53,7 @@ class Switch : public Castable<Switch, FlowNode> {
utils::Vector<Case, 4> cases; utils::Vector<Case, 4> cases;
/// Value holding the condition result /// Value holding the condition result
Value condition; const Value* condition = nullptr;
}; };
} // namespace tint::ir } // namespace tint::ir

View File

@ -16,8 +16,6 @@
namespace tint::ir { namespace tint::ir {
Value::Value() : kind_(Kind::kUninitialized), data_(Id(0)) {}
Value::Value(Id id) : kind_(Kind::kTemp), data_(id) {} Value::Value(Id id) : kind_(Kind::kTemp), data_(id) {}
Value::Value(f32 f) : kind_(Kind::kF32), data_(f) {} Value::Value(f32 f) : kind_(Kind::kF32), data_(f) {}
@ -60,9 +58,6 @@ std::ostream& operator<<(std::ostream& out, const Value& r) {
case Value::Kind::kBool: case Value::Kind::kBool:
out << (r.AsBool() ? "true" : "false"); out << (r.AsBool() ? "true" : "false");
break; break;
case Value::Kind::kUninitialized:
out << "unknown value";
break;
} }
return out; return out;
} }

View File

@ -32,8 +32,6 @@ class Value {
/// The type of the value /// The type of the value
enum class Kind { enum class Kind {
/// A uninitialized value
kUninitialized,
/// A temporary allocated value /// A temporary allocated value
kTemp, kTemp,
/// A f32 value /// A f32 value
@ -48,10 +46,6 @@ class Value {
kBool, kBool,
}; };
/// Constructor
/// Creates a uninitialized value
Value();
/// Constructor /// Constructor
/// @param id the id for the value /// @param id the id for the value
explicit Value(Id id); explicit Value(Id id);

View File

@ -133,16 +133,5 @@ TEST_F(IR_ValueTest, bool) {
EXPECT_TRUE(val.IsBool()); EXPECT_TRUE(val.IsBool());
} }
TEST_F(IR_ValueTest, uninitialized) {
Value val;
EXPECT_FALSE(val.IsF32());
EXPECT_FALSE(val.IsF16());
EXPECT_FALSE(val.IsI32());
EXPECT_FALSE(val.IsU32());
EXPECT_FALSE(val.IsTemp());
EXPECT_FALSE(val.IsBool());
}
} // namespace } // namespace
} // namespace tint::ir } // namespace tint::ir