[ir] Make dump output more consistent.
This Cl updates the dump output for the IR to be a bit more consistent. Brackets are removed, named calls are used in place of symbols. Trailing commas cleaned up. Values have their type appended to make it clearer what they are when a literal is emitted. Bug: tint:1718 Change-Id: Ie202d4a4f8267d00b9af4864063b7133f4c7f324 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/130000 Kokoro: Kokoro <noreply+kokoro@google.com> Auto-Submit: Dan Sinclair <dsinclair@chromium.org> Reviewed-by: Ben Clayton <bclayton@google.com> Reviewed-by: James Price <jrprice@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
255a116ea1
commit
642a4f1d8c
|
@ -31,67 +31,66 @@ Binary::~Binary() = default;
|
||||||
|
|
||||||
utils::StringStream& Binary::ToInstruction(utils::StringStream& out) const {
|
utils::StringStream& Binary::ToInstruction(utils::StringStream& out) const {
|
||||||
ToValue(out) << " = ";
|
ToValue(out) << " = ";
|
||||||
lhs_->ToValue(out) << " ";
|
|
||||||
|
|
||||||
switch (GetKind()) {
|
switch (GetKind()) {
|
||||||
case Binary::Kind::kAdd:
|
case Binary::Kind::kAdd:
|
||||||
out << "+";
|
out << "add";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kSubtract:
|
case Binary::Kind::kSubtract:
|
||||||
out << "-";
|
out << "sub";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kMultiply:
|
case Binary::Kind::kMultiply:
|
||||||
out << "*";
|
out << "mul";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kDivide:
|
case Binary::Kind::kDivide:
|
||||||
out << "/";
|
out << "div";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kModulo:
|
case Binary::Kind::kModulo:
|
||||||
out << "%";
|
out << "mod";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kAnd:
|
case Binary::Kind::kAnd:
|
||||||
out << "&";
|
out << "bit_and";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kOr:
|
case Binary::Kind::kOr:
|
||||||
out << "|";
|
out << "bit_or";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kXor:
|
case Binary::Kind::kXor:
|
||||||
out << "^";
|
out << "bit_xor";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kLogicalAnd:
|
case Binary::Kind::kLogicalAnd:
|
||||||
out << "&&";
|
out << "log_and";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kLogicalOr:
|
case Binary::Kind::kLogicalOr:
|
||||||
out << "||";
|
out << "log_or";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kEqual:
|
case Binary::Kind::kEqual:
|
||||||
out << "==";
|
out << "eq";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kNotEqual:
|
case Binary::Kind::kNotEqual:
|
||||||
out << "!=";
|
out << "neq";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kLessThan:
|
case Binary::Kind::kLessThan:
|
||||||
out << "<";
|
out << "lt";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kGreaterThan:
|
case Binary::Kind::kGreaterThan:
|
||||||
out << ">";
|
out << "gt";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kLessThanEqual:
|
case Binary::Kind::kLessThanEqual:
|
||||||
out << "<=";
|
out << "lte";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kGreaterThanEqual:
|
case Binary::Kind::kGreaterThanEqual:
|
||||||
out << ">=";
|
out << "gte";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kShiftLeft:
|
case Binary::Kind::kShiftLeft:
|
||||||
out << "<<";
|
out << "shiftl";
|
||||||
break;
|
break;
|
||||||
case Binary::Kind::kShiftRight:
|
case Binary::Kind::kShiftRight:
|
||||||
out << ">>";
|
out << "shiftr";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
out << " ";
|
out << " ";
|
||||||
|
lhs_->ToValue(out) << ", ";
|
||||||
rhs_->ToValue(out);
|
rhs_->ToValue(out);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ TEST_F(IR_InstructionTest, CreateAnd) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = 4 & 2");
|
EXPECT_EQ(str.str(), "%1(i32) = bit_and 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateOr) {
|
TEST_F(IR_InstructionTest, CreateOr) {
|
||||||
|
@ -69,7 +69,7 @@ TEST_F(IR_InstructionTest, CreateOr) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = 4 | 2");
|
EXPECT_EQ(str.str(), "%1(i32) = bit_or 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateXor) {
|
TEST_F(IR_InstructionTest, CreateXor) {
|
||||||
|
@ -93,7 +93,7 @@ TEST_F(IR_InstructionTest, CreateXor) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = 4 ^ 2");
|
EXPECT_EQ(str.str(), "%1(i32) = bit_xor 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
||||||
|
@ -117,7 +117,7 @@ TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(bool) = 4 && 2");
|
EXPECT_EQ(str.str(), "%1(bool) = log_and 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
||||||
|
@ -141,7 +141,7 @@ TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(bool) = 4 || 2");
|
EXPECT_EQ(str.str(), "%1(bool) = log_or 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateEqual) {
|
TEST_F(IR_InstructionTest, CreateEqual) {
|
||||||
|
@ -165,7 +165,7 @@ TEST_F(IR_InstructionTest, CreateEqual) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(bool) = 4 == 2");
|
EXPECT_EQ(str.str(), "%1(bool) = eq 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateNotEqual) {
|
TEST_F(IR_InstructionTest, CreateNotEqual) {
|
||||||
|
@ -189,7 +189,7 @@ TEST_F(IR_InstructionTest, CreateNotEqual) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(bool) = 4 != 2");
|
EXPECT_EQ(str.str(), "%1(bool) = neq 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateLessThan) {
|
TEST_F(IR_InstructionTest, CreateLessThan) {
|
||||||
|
@ -213,7 +213,7 @@ TEST_F(IR_InstructionTest, CreateLessThan) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(bool) = 4 < 2");
|
EXPECT_EQ(str.str(), "%1(bool) = lt 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
||||||
|
@ -237,7 +237,7 @@ TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(bool) = 4 > 2");
|
EXPECT_EQ(str.str(), "%1(bool) = gt 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
||||||
|
@ -261,7 +261,7 @@ TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(bool) = 4 <= 2");
|
EXPECT_EQ(str.str(), "%1(bool) = lte 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
||||||
|
@ -285,7 +285,7 @@ TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(bool) = 4 >= 2");
|
EXPECT_EQ(str.str(), "%1(bool) = gte 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
||||||
|
@ -309,7 +309,7 @@ TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = 4 << 2");
|
EXPECT_EQ(str.str(), "%1(i32) = shiftl 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateShiftRight) {
|
TEST_F(IR_InstructionTest, CreateShiftRight) {
|
||||||
|
@ -333,7 +333,7 @@ TEST_F(IR_InstructionTest, CreateShiftRight) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = 4 >> 2");
|
EXPECT_EQ(str.str(), "%1(i32) = shiftr 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateAdd) {
|
TEST_F(IR_InstructionTest, CreateAdd) {
|
||||||
|
@ -357,7 +357,7 @@ TEST_F(IR_InstructionTest, CreateAdd) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = 4 + 2");
|
EXPECT_EQ(str.str(), "%1(i32) = add 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateSubtract) {
|
TEST_F(IR_InstructionTest, CreateSubtract) {
|
||||||
|
@ -381,7 +381,7 @@ TEST_F(IR_InstructionTest, CreateSubtract) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = 4 - 2");
|
EXPECT_EQ(str.str(), "%1(i32) = sub 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateMultiply) {
|
TEST_F(IR_InstructionTest, CreateMultiply) {
|
||||||
|
@ -405,7 +405,7 @@ TEST_F(IR_InstructionTest, CreateMultiply) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = 4 * 2");
|
EXPECT_EQ(str.str(), "%1(i32) = mul 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateDivide) {
|
TEST_F(IR_InstructionTest, CreateDivide) {
|
||||||
|
@ -429,7 +429,7 @@ TEST_F(IR_InstructionTest, CreateDivide) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = 4 / 2");
|
EXPECT_EQ(str.str(), "%1(i32) = div 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateModulo) {
|
TEST_F(IR_InstructionTest, CreateModulo) {
|
||||||
|
@ -453,7 +453,7 @@ TEST_F(IR_InstructionTest, CreateModulo) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = 4 % 2");
|
EXPECT_EQ(str.str(), "%1(i32) = mod 4i, 2i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, Binary_Usage) {
|
TEST_F(IR_InstructionTest, Binary_Usage) {
|
||||||
|
|
|
@ -25,9 +25,8 @@ Bitcast::Bitcast(uint32_t id, const type::Type* type, Value* val)
|
||||||
Bitcast::~Bitcast() = default;
|
Bitcast::~Bitcast() = default;
|
||||||
|
|
||||||
utils::StringStream& Bitcast::ToInstruction(utils::StringStream& out) const {
|
utils::StringStream& Bitcast::ToInstruction(utils::StringStream& out) const {
|
||||||
ToValue(out) << " = bitcast(";
|
ToValue(out) << " = bitcast ";
|
||||||
EmitArgs(out);
|
EmitArgs(out);
|
||||||
out << ")";
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ TEST_F(IR_InstructionTest, Bitcast) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = bitcast(4)");
|
EXPECT_EQ(str.str(), "%1(i32) = bitcast 4i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, Bitcast_Usage) {
|
TEST_F(IR_InstructionTest, Bitcast_Usage) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ class Block : public utils::Castable<Block, FlowNode> {
|
||||||
|
|
||||||
/// @returns true if this is a dead block. This can happen in the case like a loop merge block
|
/// @returns true if this is a dead block. This can happen in the case like a loop merge block
|
||||||
/// which is never reached.
|
/// which is never reached.
|
||||||
bool IsDead() const { return branch.target == nullptr; }
|
bool IsDead() const override { return branch.target == nullptr; }
|
||||||
|
|
||||||
/// The node this block branches too.
|
/// The node this block branches too.
|
||||||
Branch branch = {};
|
Branch branch = {};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,9 +29,8 @@ Builtin::Builtin(uint32_t id,
|
||||||
Builtin::~Builtin() = default;
|
Builtin::~Builtin() = default;
|
||||||
|
|
||||||
utils::StringStream& Builtin::ToInstruction(utils::StringStream& out) const {
|
utils::StringStream& Builtin::ToInstruction(utils::StringStream& out) const {
|
||||||
ToValue(out) << " = " << builtin::str(func_) << "(";
|
ToValue(out) << " = " << builtin::str(func_) << " ";
|
||||||
EmitArgs(out);
|
EmitArgs(out);
|
||||||
out << ")";
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,27 +35,33 @@ utils::StringStream& Constant::ToValue(utils::StringStream& out) const {
|
||||||
c,
|
c,
|
||||||
[&](const constant::Scalar<AFloat>* scalar) { out << scalar->ValueAs<AFloat>().value; },
|
[&](const constant::Scalar<AFloat>* scalar) { out << scalar->ValueAs<AFloat>().value; },
|
||||||
[&](const constant::Scalar<AInt>* scalar) { out << scalar->ValueAs<AInt>().value; },
|
[&](const constant::Scalar<AInt>* scalar) { out << scalar->ValueAs<AInt>().value; },
|
||||||
[&](const constant::Scalar<i32>* scalar) { out << scalar->ValueAs<i32>().value; },
|
[&](const constant::Scalar<i32>* scalar) {
|
||||||
[&](const constant::Scalar<u32>* scalar) { out << scalar->ValueAs<u32>().value; },
|
out << scalar->ValueAs<i32>().value << "i";
|
||||||
[&](const constant::Scalar<f32>* scalar) { out << scalar->ValueAs<f32>().value; },
|
},
|
||||||
[&](const constant::Scalar<f16>* scalar) { out << scalar->ValueAs<f16>().value; },
|
[&](const constant::Scalar<u32>* scalar) {
|
||||||
|
out << scalar->ValueAs<u32>().value << "u";
|
||||||
|
},
|
||||||
|
[&](const constant::Scalar<f32>* scalar) {
|
||||||
|
out << scalar->ValueAs<f32>().value << "f";
|
||||||
|
},
|
||||||
|
[&](const constant::Scalar<f16>* scalar) {
|
||||||
|
out << scalar->ValueAs<f16>().value << "h";
|
||||||
|
},
|
||||||
[&](const constant::Scalar<bool>* scalar) {
|
[&](const constant::Scalar<bool>* scalar) {
|
||||||
out << (scalar->ValueAs<bool>() ? "true" : "false");
|
out << (scalar->ValueAs<bool>() ? "true" : "false");
|
||||||
},
|
},
|
||||||
[&](const constant::Splat* splat) {
|
[&](const constant::Splat* splat) {
|
||||||
out << splat->Type()->FriendlyName() << "(";
|
out << splat->Type()->FriendlyName() << " ";
|
||||||
emit(splat->Index(0));
|
emit(splat->Index(0));
|
||||||
out << ")";
|
|
||||||
},
|
},
|
||||||
[&](const constant::Composite* composite) {
|
[&](const constant::Composite* composite) {
|
||||||
out << composite->Type()->FriendlyName() << "(";
|
out << composite->Type()->FriendlyName() << " ";
|
||||||
for (const auto* elem : composite->elements) {
|
for (const auto* elem : composite->elements) {
|
||||||
if (elem != composite->elements[0]) {
|
if (elem != composite->elements[0]) {
|
||||||
out << ", ";
|
out << ", ";
|
||||||
}
|
}
|
||||||
emit(elem);
|
emit(elem);
|
||||||
}
|
}
|
||||||
out << ")";
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
emit(value);
|
emit(value);
|
||||||
|
|
|
@ -32,7 +32,7 @@ TEST_F(IR_ConstantTest, f32) {
|
||||||
EXPECT_EQ(1.2_f, c->value->As<constant::Scalar<f32>>()->ValueAs<f32>());
|
EXPECT_EQ(1.2_f, c->value->As<constant::Scalar<f32>>()->ValueAs<f32>());
|
||||||
|
|
||||||
c->ToValue(str);
|
c->ToValue(str);
|
||||||
EXPECT_EQ("1.20000004768371582031", str.str());
|
EXPECT_EQ("1.20000004768371582031f", str.str());
|
||||||
|
|
||||||
EXPECT_TRUE(c->value->Is<constant::Scalar<f32>>());
|
EXPECT_TRUE(c->value->Is<constant::Scalar<f32>>());
|
||||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
|
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
|
||||||
|
@ -50,7 +50,7 @@ TEST_F(IR_ConstantTest, f16) {
|
||||||
EXPECT_EQ(1.1_h, c->value->As<constant::Scalar<f16>>()->ValueAs<f16>());
|
EXPECT_EQ(1.1_h, c->value->As<constant::Scalar<f16>>()->ValueAs<f16>());
|
||||||
|
|
||||||
c->ToValue(str);
|
c->ToValue(str);
|
||||||
EXPECT_EQ("1.099609375", str.str());
|
EXPECT_EQ("1.099609375h", str.str());
|
||||||
|
|
||||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
||||||
EXPECT_TRUE(c->value->Is<constant::Scalar<f16>>());
|
EXPECT_TRUE(c->value->Is<constant::Scalar<f16>>());
|
||||||
|
@ -68,7 +68,7 @@ TEST_F(IR_ConstantTest, i32) {
|
||||||
EXPECT_EQ(1_i, c->value->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
EXPECT_EQ(1_i, c->value->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||||
|
|
||||||
c->ToValue(str);
|
c->ToValue(str);
|
||||||
EXPECT_EQ("1", str.str());
|
EXPECT_EQ("1i", str.str());
|
||||||
|
|
||||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
||||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
|
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
|
||||||
|
@ -86,7 +86,7 @@ TEST_F(IR_ConstantTest, u32) {
|
||||||
EXPECT_EQ(2_u, c->value->As<constant::Scalar<u32>>()->ValueAs<u32>());
|
EXPECT_EQ(2_u, c->value->As<constant::Scalar<u32>>()->ValueAs<u32>());
|
||||||
|
|
||||||
c->ToValue(str);
|
c->ToValue(str);
|
||||||
EXPECT_EQ("2", str.str());
|
EXPECT_EQ("2u", str.str());
|
||||||
|
|
||||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
|
||||||
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
|
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
|
||||||
|
|
|
@ -25,12 +25,8 @@ Construct::Construct(uint32_t id, const type::Type* type, utils::VectorRef<Value
|
||||||
Construct::~Construct() = default;
|
Construct::~Construct() = default;
|
||||||
|
|
||||||
utils::StringStream& Construct::ToInstruction(utils::StringStream& out) const {
|
utils::StringStream& Construct::ToInstruction(utils::StringStream& out) const {
|
||||||
ToValue(out) << " = construct(";
|
ToValue(out) << " = construct ";
|
||||||
if (!Args().IsEmpty()) {
|
|
||||||
out << ", ";
|
|
||||||
EmitArgs(out);
|
EmitArgs(out);
|
||||||
}
|
|
||||||
out << ")";
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,8 @@ Convert::Convert(uint32_t id,
|
||||||
Convert::~Convert() = default;
|
Convert::~Convert() = default;
|
||||||
|
|
||||||
utils::StringStream& Convert::ToInstruction(utils::StringStream& out) const {
|
utils::StringStream& Convert::ToInstruction(utils::StringStream& out) const {
|
||||||
ToValue(out) << " = convert(" << from_type_->FriendlyName() << ", ";
|
ToValue(out) << " = convert " << from_type_->FriendlyName() << ", ";
|
||||||
EmitArgs(out);
|
EmitArgs(out);
|
||||||
out << ")";
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ void Disassembler::Walk(const FlowNode* node) {
|
||||||
tint::Switch(
|
tint::Switch(
|
||||||
node,
|
node,
|
||||||
[&](const ir::Function* f) {
|
[&](const ir::Function* f) {
|
||||||
Indent() << "%bb" << GetIdForNode(f) << " = Function " << f->name.Name() << std::endl;
|
Indent() << "%fn" << GetIdForNode(f) << " = func " << f->name.Name() << std::endl;
|
||||||
|
|
||||||
{
|
{
|
||||||
ScopedIndent func_indent(&indent_size_);
|
ScopedIndent func_indent(&indent_size_);
|
||||||
|
@ -101,27 +101,28 @@ void Disassembler::Walk(const FlowNode* node) {
|
||||||
[&](const ir::Block* b) {
|
[&](const ir::Block* b) {
|
||||||
// If this block is dead, nothing to do
|
// If this block is dead, nothing to do
|
||||||
if (b->IsDead()) {
|
if (b->IsDead()) {
|
||||||
Indent() << "# Dead" << std::endl;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Indent() << "%bb" << GetIdForNode(b) << " = Block" << std::endl;
|
Indent() << "%fn" << GetIdForNode(b) << " = block" << std::endl;
|
||||||
EmitBlockInstructions(b);
|
EmitBlockInstructions(b);
|
||||||
|
|
||||||
if (b->branch.target->Is<Terminator>()) {
|
if (b->branch.target->Is<Terminator>()) {
|
||||||
Indent() << "Return";
|
Indent() << "ret";
|
||||||
} else {
|
} else {
|
||||||
Indent() << "BranchTo "
|
Indent() << "branch "
|
||||||
<< "%bb" << GetIdForNode(b->branch.target);
|
<< "%fn" << GetIdForNode(b->branch.target);
|
||||||
}
|
}
|
||||||
out_ << " (";
|
if (!b->branch.args.IsEmpty()) {
|
||||||
|
out_ << " ";
|
||||||
for (const auto* v : b->branch.args) {
|
for (const auto* v : b->branch.args) {
|
||||||
if (v != b->branch.args.Front()) {
|
if (v != b->branch.args.Front()) {
|
||||||
out_ << ", ";
|
out_ << ", ";
|
||||||
}
|
}
|
||||||
v->ToValue(out_);
|
v->ToValue(out_);
|
||||||
}
|
}
|
||||||
out_ << ")" << std::endl;
|
}
|
||||||
|
out_ << std::endl;
|
||||||
|
|
||||||
if (!b->branch.target->Is<Terminator>()) {
|
if (!b->branch.target->Is<Terminator>()) {
|
||||||
out_ << std::endl;
|
out_ << std::endl;
|
||||||
|
@ -130,15 +131,37 @@ void Disassembler::Walk(const FlowNode* node) {
|
||||||
Walk(b->branch.target);
|
Walk(b->branch.target);
|
||||||
},
|
},
|
||||||
[&](const ir::Switch* s) {
|
[&](const ir::Switch* s) {
|
||||||
Indent() << "%bb" << GetIdForNode(s) << " = Switch (";
|
Indent() << "%fn" << GetIdForNode(s) << " = switch ";
|
||||||
s->condition->ToValue(out_);
|
s->condition->ToValue(out_);
|
||||||
out_ << ")" << std::endl;
|
out_ << " [";
|
||||||
|
for (const auto& c : s->cases) {
|
||||||
|
if (&c != &s->cases.Front()) {
|
||||||
|
out_ << ", ";
|
||||||
|
}
|
||||||
|
out_ << "c: (";
|
||||||
|
for (const auto& selector : c.selectors) {
|
||||||
|
if (&selector != &c.selectors.Front()) {
|
||||||
|
out_ << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selector.IsDefault()) {
|
||||||
|
out_ << "default";
|
||||||
|
} else {
|
||||||
|
selector.val->ToValue(out_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out_ << ", %fn" << GetIdForNode(c.start.target) << ")";
|
||||||
|
}
|
||||||
|
if (s->merge.target->IsConnected()) {
|
||||||
|
out_ << ", m: %fn" << GetIdForNode(s->merge.target);
|
||||||
|
}
|
||||||
|
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) {
|
||||||
if (&selector != &c.selectors.Front()) {
|
if (&selector != &c.selectors.Front()) {
|
||||||
out_ << " ";
|
out_ << " ";
|
||||||
|
@ -155,13 +178,20 @@ void Disassembler::Walk(const FlowNode* node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Indent() << "# Switch Merge" << std::endl;
|
if (s->merge.target->IsConnected()) {
|
||||||
|
Indent() << "# switch merge" << std::endl;
|
||||||
Walk(s->merge.target);
|
Walk(s->merge.target);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[&](const ir::If* i) {
|
[&](const ir::If* i) {
|
||||||
Indent() << "%bb" << GetIdForNode(i) << " = if (";
|
Indent() << "%fn" << GetIdForNode(i) << " = if ";
|
||||||
i->condition->ToValue(out_);
|
i->condition->ToValue(out_);
|
||||||
out_ << ")" << std::endl;
|
out_ << " [t: %fn" << GetIdForNode(i->true_.target) << ", f: %fn"
|
||||||
|
<< GetIdForNode(i->false_.target);
|
||||||
|
if (i->merge.target->IsConnected()) {
|
||||||
|
out_ << ", m: %fn" << GetIdForNode(i->merge.target);
|
||||||
|
}
|
||||||
|
out_ << "]" << std::endl;
|
||||||
|
|
||||||
{
|
{
|
||||||
ScopedIndent if_indent(&indent_size_);
|
ScopedIndent if_indent(&indent_size_);
|
||||||
|
@ -174,13 +204,23 @@ void Disassembler::Walk(const FlowNode* node) {
|
||||||
Walk(i->false_.target);
|
Walk(i->false_.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i->merge.target->IsDisconnected()) {
|
if (i->merge.target->IsConnected()) {
|
||||||
Indent() << "# if merge" << std::endl;
|
Indent() << "# if merge" << std::endl;
|
||||||
Walk(i->merge.target);
|
Walk(i->merge.target);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&](const ir::Loop* l) {
|
[&](const ir::Loop* l) {
|
||||||
Indent() << "%bb" << GetIdForNode(l) << " = loop" << std::endl;
|
Indent() << "%fn" << GetIdForNode(l) << " = loop [s: %fn"
|
||||||
|
<< GetIdForNode(l->start.target);
|
||||||
|
|
||||||
|
if (l->continuing.target->IsConnected()) {
|
||||||
|
out_ << ", c: %fn" << GetIdForNode(l->continuing.target);
|
||||||
|
}
|
||||||
|
if (l->merge.target->IsConnected()) {
|
||||||
|
out_ << ", m: %fn" << GetIdForNode(l->merge.target);
|
||||||
|
}
|
||||||
|
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_);
|
||||||
|
@ -190,14 +230,18 @@ void Disassembler::Walk(const FlowNode* node) {
|
||||||
Walk(l->start.target);
|
Walk(l->start.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (l->continuing.target->IsConnected()) {
|
||||||
Indent() << "# loop continuing" << std::endl;
|
Indent() << "# loop continuing" << std::endl;
|
||||||
Walk(l->continuing.target);
|
Walk(l->continuing.target);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l->merge.target->IsConnected()) {
|
||||||
Indent() << "# loop merge" << std::endl;
|
Indent() << "# loop merge" << std::endl;
|
||||||
Walk(l->merge.target);
|
Walk(l->merge.target);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[&](const ir::Terminator*) { Indent() << "FunctionEnd" << std::endl
|
[&](const ir::Terminator*) { Indent() << "func_end" << std::endl
|
||||||
<< std::endl; });
|
<< std::endl; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,11 @@ class FlowNode : public utils::Castable<FlowNode> {
|
||||||
/// - Node is a continue target outside control flow (loop that returns)
|
/// - Node is a continue target outside control flow (loop that returns)
|
||||||
utils::Vector<FlowNode*, 2> inbound_branches;
|
utils::Vector<FlowNode*, 2> inbound_branches;
|
||||||
|
|
||||||
/// @returns true if this node has no inbound branches
|
/// @returns true if this node has inbound branches and branches out
|
||||||
bool IsDisconnected() const { return inbound_branches.IsEmpty(); }
|
bool IsConnected() const { return !IsDead() && !inbound_branches.IsEmpty(); }
|
||||||
|
|
||||||
|
/// @returns true if the node does not branch out
|
||||||
|
virtual bool IsDead() const { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
|
|
|
@ -29,9 +29,9 @@ Store::Store(Value* to, Value* from) : Base(), to_(to), from_(from) {
|
||||||
Store::~Store() = default;
|
Store::~Store() = default;
|
||||||
|
|
||||||
utils::StringStream& Store::ToInstruction(utils::StringStream& out) const {
|
utils::StringStream& Store::ToInstruction(utils::StringStream& out) const {
|
||||||
out << "store(";
|
out << "store ";
|
||||||
to_->ToValue(out) << ", ";
|
to_->ToValue(out) << ", ";
|
||||||
from_->ToValue(out) << ")";
|
from_->ToValue(out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ TEST_F(IR_InstructionTest, CreateStore) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "store(%0, 4)");
|
EXPECT_EQ(str.str(), "store %0, 4i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, Store_Usage) {
|
TEST_F(IR_InstructionTest, Store_Usage) {
|
||||||
|
|
|
@ -31,21 +31,22 @@ utils::StringStream& Unary::ToInstruction(utils::StringStream& out) const {
|
||||||
ToValue(out) << " = ";
|
ToValue(out) << " = ";
|
||||||
switch (GetKind()) {
|
switch (GetKind()) {
|
||||||
case Unary::Kind::kAddressOf:
|
case Unary::Kind::kAddressOf:
|
||||||
out << "&";
|
out << "addr_of";
|
||||||
break;
|
break;
|
||||||
case Unary::Kind::kComplement:
|
case Unary::Kind::kComplement:
|
||||||
out << "~";
|
out << "bit_complement";
|
||||||
break;
|
break;
|
||||||
case Unary::Kind::kIndirection:
|
case Unary::Kind::kIndirection:
|
||||||
out << "*";
|
out << "indirection";
|
||||||
break;
|
break;
|
||||||
case Unary::Kind::kNegation:
|
case Unary::Kind::kNegation:
|
||||||
out << "-";
|
out << "negation";
|
||||||
break;
|
break;
|
||||||
case Unary::Kind::kNot:
|
case Unary::Kind::kNot:
|
||||||
out << "!";
|
out << "log_not";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
out << " ";
|
||||||
val_->ToValue(out);
|
val_->ToValue(out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ TEST_F(IR_InstructionTest, CreateAddressOf) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(ptr<private, i32, read_write>) = &4");
|
EXPECT_EQ(str.str(), "%1(ptr<private, i32, read_write>) = addr_of 4i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateComplement) {
|
TEST_F(IR_InstructionTest, CreateComplement) {
|
||||||
|
@ -63,7 +63,7 @@ TEST_F(IR_InstructionTest, CreateComplement) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = ~4");
|
EXPECT_EQ(str.str(), "%1(i32) = bit_complement 4i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateIndirection) {
|
TEST_F(IR_InstructionTest, CreateIndirection) {
|
||||||
|
@ -83,7 +83,7 @@ TEST_F(IR_InstructionTest, CreateIndirection) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = *4");
|
EXPECT_EQ(str.str(), "%1(i32) = indirection 4i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateNegation) {
|
TEST_F(IR_InstructionTest, CreateNegation) {
|
||||||
|
@ -101,7 +101,7 @@ TEST_F(IR_InstructionTest, CreateNegation) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(i32) = -4");
|
EXPECT_EQ(str.str(), "%1(i32) = negation 4i");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateNot) {
|
TEST_F(IR_InstructionTest, CreateNot) {
|
||||||
|
@ -119,7 +119,7 @@ TEST_F(IR_InstructionTest, CreateNot) {
|
||||||
|
|
||||||
utils::StringStream str;
|
utils::StringStream str;
|
||||||
inst->ToInstruction(str);
|
inst->ToInstruction(str);
|
||||||
EXPECT_EQ(str.str(), "%1(bool) = !true");
|
EXPECT_EQ(str.str(), "%1(bool) = log_not true");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, Unary_Usage) {
|
TEST_F(IR_InstructionTest, Unary_Usage) {
|
||||||
|
|
|
@ -25,9 +25,11 @@ UserCall::UserCall(uint32_t id, const type::Type* type, Symbol name, utils::Vect
|
||||||
UserCall::~UserCall() = default;
|
UserCall::~UserCall() = default;
|
||||||
|
|
||||||
utils::StringStream& UserCall::ToInstruction(utils::StringStream& out) const {
|
utils::StringStream& UserCall::ToInstruction(utils::StringStream& out) const {
|
||||||
ToValue(out) << " = call(" << name_.Name() << ", ";
|
ToValue(out) << " = call " << name_.Name();
|
||||||
|
if (Args().Length() > 0) {
|
||||||
|
out << ", ";
|
||||||
|
}
|
||||||
EmitArgs(out);
|
EmitArgs(out);
|
||||||
out << ")";
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue