mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-03 03:35:59 +00:00
[ir] Update disassembly output.
This CL switches the disassembler back to being recursive and fixes up the indenting of blocks to better highlight if branches and switch cases. Bug: tint:1718 Change-Id: I14e8d7c68a083bf3afd9ff7241d49b2aa76be4ba Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/134300 Commit-Queue: Dan Sinclair <dsinclair@chromium.org> Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
b3e680bb88
commit
a518707db4
@ -89,111 +89,106 @@ std::string_view Disassembler::IdOf(const Value* value) {
|
|||||||
|
|
||||||
std::string Disassembler::Disassemble() {
|
std::string Disassembler::Disassemble() {
|
||||||
if (mod_.root_block) {
|
if (mod_.root_block) {
|
||||||
walk_list_.push_back(mod_.root_block);
|
Indent() << "# Root block" << std::endl;
|
||||||
Walk();
|
Walk(mod_.root_block);
|
||||||
TINT_ASSERT(IR, walk_list_.empty());
|
Walk(mod_.root_block->Branch()->To());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto* func : mod_.functions) {
|
for (auto* func : mod_.functions) {
|
||||||
walk_list_.push_back(func);
|
EmitFunction(func);
|
||||||
Walk();
|
|
||||||
TINT_ASSERT(IR, walk_list_.empty());
|
|
||||||
}
|
}
|
||||||
return out_.str();
|
return out_.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Disassembler::Walk() {
|
void Disassembler::Walk(const Block* blk) {
|
||||||
utils::Hashset<const FlowNode*, 32> visited_;
|
if (visited_.Contains(blk)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
visited_.Add(blk);
|
||||||
|
|
||||||
while (!walk_list_.empty()) {
|
tint::Switch(
|
||||||
const FlowNode* node = walk_list_.front();
|
blk,
|
||||||
walk_list_.pop_front();
|
[&](const ir::FunctionTerminator* t) {
|
||||||
|
TINT_ASSERT(IR, in_function_);
|
||||||
|
Indent() << "%fn" << IdOf(t) << " = func_terminator" << std::endl;
|
||||||
|
in_function_ = false;
|
||||||
|
},
|
||||||
|
[&](const ir::RootTerminator* t) {
|
||||||
|
TINT_ASSERT(IR, !in_function_);
|
||||||
|
Indent() << "%fn" << IdOf(t) << " = root_terminator" << std::endl << std::endl;
|
||||||
|
},
|
||||||
|
[&](const ir::Block* b) {
|
||||||
|
// If this block is dead, nothing to do
|
||||||
|
if (!b->HasBranchTarget()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (visited_.Contains(node)) {
|
Indent() << "%fn" << IdOf(b) << " = block";
|
||||||
continue;
|
if (!b->Params().IsEmpty()) {
|
||||||
}
|
out_ << " (";
|
||||||
visited_.Add(node);
|
for (auto* p : b->Params()) {
|
||||||
|
if (p != b->Params().Front()) {
|
||||||
tint::Switch(
|
|
||||||
node,
|
|
||||||
[&](const ir::Function* f) {
|
|
||||||
in_function_ = true;
|
|
||||||
|
|
||||||
Indent() << "%fn" << IdOf(f) << " = func " << f->Name().Name() << "(";
|
|
||||||
for (auto* p : f->Params()) {
|
|
||||||
if (p != f->Params().Front()) {
|
|
||||||
out_ << ", ";
|
out_ << ", ";
|
||||||
}
|
}
|
||||||
out_ << "%" << IdOf(p) << ":" << p->Type()->FriendlyName();
|
EmitValue(p);
|
||||||
}
|
}
|
||||||
out_ << "):" << f->ReturnType()->FriendlyName();
|
out_ << ")";
|
||||||
|
}
|
||||||
|
|
||||||
if (f->Stage() != Function::PipelineStage::kUndefined) {
|
out_ << " {" << std::endl;
|
||||||
out_ << " [@" << f->Stage();
|
{
|
||||||
|
ScopedIndent si(indent_size_);
|
||||||
|
EmitBlockInstructions(b);
|
||||||
|
}
|
||||||
|
Indent() << "}" << std::endl;
|
||||||
|
|
||||||
if (f->WorkgroupSize()) {
|
if (!b->Branch()->To()->Is<FunctionTerminator>()) {
|
||||||
auto arr = f->WorkgroupSize().value();
|
out_ << std::endl;
|
||||||
out_ << " @workgroup_size(" << arr[0] << ", " << arr[1] << ", " << arr[2]
|
}
|
||||||
<< ")";
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!f->ReturnAttributes().IsEmpty()) {
|
void Disassembler::EmitFunction(const Function* func) {
|
||||||
out_ << " ra:";
|
in_function_ = true;
|
||||||
|
|
||||||
for (auto attr : f->ReturnAttributes()) {
|
Indent() << "%fn" << IdOf(func) << " = func " << func->Name().Name() << "(";
|
||||||
out_ << " @" << attr;
|
for (auto* p : func->Params()) {
|
||||||
if (attr == Function::ReturnAttribute::kLocation) {
|
if (p != func->Params().Front()) {
|
||||||
out_ << "(" << f->ReturnLocation().value() << ")";
|
out_ << ", ";
|
||||||
}
|
}
|
||||||
}
|
out_ << "%" << IdOf(p) << ":" << p->Type()->FriendlyName();
|
||||||
}
|
|
||||||
|
|
||||||
out_ << "]";
|
|
||||||
}
|
|
||||||
out_ << " -> %fn" << IdOf(f->StartTarget()) << std::endl;
|
|
||||||
walk_list_.push_back(f->StartTarget());
|
|
||||||
},
|
|
||||||
[&](const ir::FunctionTerminator* t) {
|
|
||||||
TINT_ASSERT(IR, in_function_);
|
|
||||||
Indent() << "%fn" << IdOf(t) << " = func_terminator" << std::endl << std::endl;
|
|
||||||
in_function_ = false;
|
|
||||||
},
|
|
||||||
[&](const ir::RootTerminator* t) {
|
|
||||||
TINT_ASSERT(IR, !in_function_);
|
|
||||||
Indent() << "%fn" << IdOf(t) << " = root_terminator" << std::endl << std::endl;
|
|
||||||
},
|
|
||||||
[&](const ir::Block* b) {
|
|
||||||
// If this block is dead, nothing to do
|
|
||||||
if (!b->HasBranchTarget()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Indent() << "%fn" << IdOf(b) << " = block";
|
|
||||||
if (!b->Params().IsEmpty()) {
|
|
||||||
out_ << " (";
|
|
||||||
for (auto* p : b->Params()) {
|
|
||||||
if (p != b->Params().Front()) {
|
|
||||||
out_ << ", ";
|
|
||||||
}
|
|
||||||
EmitValue(p);
|
|
||||||
}
|
|
||||||
out_ << ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
out_ << " {" << std::endl;
|
|
||||||
{
|
|
||||||
ScopedIndent si(indent_size_);
|
|
||||||
EmitBlockInstructions(b);
|
|
||||||
}
|
|
||||||
Indent() << "}" << std::endl;
|
|
||||||
|
|
||||||
if (!b->Branch()->To()->Is<FunctionTerminator>()) {
|
|
||||||
out_ << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
walk_list_.push_back(b->Branch()->To());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
out_ << "):" << func->ReturnType()->FriendlyName();
|
||||||
|
|
||||||
|
if (func->Stage() != Function::PipelineStage::kUndefined) {
|
||||||
|
out_ << " [@" << func->Stage();
|
||||||
|
|
||||||
|
if (func->WorkgroupSize()) {
|
||||||
|
auto arr = func->WorkgroupSize().value();
|
||||||
|
out_ << " @workgroup_size(" << arr[0] << ", " << arr[1] << ", " << arr[2] << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!func->ReturnAttributes().IsEmpty()) {
|
||||||
|
out_ << " ra:";
|
||||||
|
|
||||||
|
for (auto attr : func->ReturnAttributes()) {
|
||||||
|
out_ << " @" << attr;
|
||||||
|
if (attr == Function::ReturnAttribute::kLocation) {
|
||||||
|
out_ << "(" << func->ReturnLocation().value() << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out_ << "]";
|
||||||
|
}
|
||||||
|
out_ << " -> %fn" << IdOf(func->StartTarget()) << " {" << std::endl;
|
||||||
|
|
||||||
|
{
|
||||||
|
ScopedIndent si(indent_size_);
|
||||||
|
Walk(func->StartTarget());
|
||||||
|
Walk(func->EndTarget());
|
||||||
|
}
|
||||||
|
Indent() << "}" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Disassembler::EmitValueWithType(const Value* val) {
|
void Disassembler::EmitValueWithType(const Value* val) {
|
||||||
@ -335,16 +330,21 @@ void Disassembler::EmitIf(const If* i) {
|
|||||||
if (i->Merge()->IsConnected()) {
|
if (i->Merge()->IsConnected()) {
|
||||||
out_ << ", m: %fn" << IdOf(i->Merge());
|
out_ << ", m: %fn" << IdOf(i->Merge());
|
||||||
}
|
}
|
||||||
out_ << "]";
|
out_ << "]" << std::endl;
|
||||||
|
|
||||||
if (has_true) {
|
if (has_true) {
|
||||||
walk_list_.push_back(i->True());
|
ScopedIndent si(indent_size_);
|
||||||
|
Indent() << "# True block" << std::endl;
|
||||||
|
Walk(i->True());
|
||||||
}
|
}
|
||||||
if (has_false) {
|
if (has_false) {
|
||||||
walk_list_.push_back(i->False());
|
ScopedIndent si(indent_size_);
|
||||||
|
Indent() << "# False block" << std::endl;
|
||||||
|
Walk(i->False());
|
||||||
}
|
}
|
||||||
if (i->Merge()->IsConnected()) {
|
if (i->Merge()->IsConnected()) {
|
||||||
walk_list_.push_back(i->Merge());
|
Indent() << "# Merge block" << std::endl;
|
||||||
|
Walk(i->Merge());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,15 +357,21 @@ void Disassembler::EmitLoop(const Loop* l) {
|
|||||||
if (l->Merge()->IsConnected()) {
|
if (l->Merge()->IsConnected()) {
|
||||||
out_ << ", m: %fn" << IdOf(l->Merge());
|
out_ << ", m: %fn" << IdOf(l->Merge());
|
||||||
}
|
}
|
||||||
out_ << "]";
|
out_ << "]" << std::endl;
|
||||||
|
|
||||||
{ walk_list_.push_back(l->Start()); }
|
{
|
||||||
|
ScopedIndent si(indent_size_);
|
||||||
|
Walk(l->Start());
|
||||||
|
}
|
||||||
|
|
||||||
if (l->Continuing()->IsConnected()) {
|
if (l->Continuing()->IsConnected()) {
|
||||||
walk_list_.push_back(l->Continuing());
|
ScopedIndent si(indent_size_);
|
||||||
|
Indent() << "# Continuing block" << std::endl;
|
||||||
|
Walk(l->Continuing());
|
||||||
}
|
}
|
||||||
if (l->Merge()->IsConnected()) {
|
if (l->Merge()->IsConnected()) {
|
||||||
walk_list_.push_back(l->Merge());
|
Indent() << "# Merge block" << std::endl;
|
||||||
|
Walk(l->Merge());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,13 +400,16 @@ void Disassembler::EmitSwitch(const Switch* s) {
|
|||||||
if (s->Merge()->IsConnected()) {
|
if (s->Merge()->IsConnected()) {
|
||||||
out_ << ", m: %fn" << IdOf(s->Merge());
|
out_ << ", m: %fn" << IdOf(s->Merge());
|
||||||
}
|
}
|
||||||
out_ << "]";
|
out_ << "]" << std::endl;
|
||||||
|
|
||||||
for (auto& c : s->Cases()) {
|
for (auto& c : s->Cases()) {
|
||||||
walk_list_.push_back(c.Start());
|
ScopedIndent si(indent_size_);
|
||||||
|
Indent() << "# Case block" << std::endl;
|
||||||
|
Walk(c.Start());
|
||||||
}
|
}
|
||||||
if (s->Merge()->IsConnected()) {
|
if (s->Merge()->IsConnected()) {
|
||||||
walk_list_.push_back(s->Merge());
|
Indent() << "# Merge block" << std::endl;
|
||||||
|
Walk(s->Merge());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#ifndef SRC_TINT_IR_DISASSEMBLER_H_
|
#ifndef SRC_TINT_IR_DISASSEMBLER_H_
|
||||||
#define SRC_TINT_IR_DISASSEMBLER_H_
|
#define SRC_TINT_IR_DISASSEMBLER_H_
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/ir/binary.h"
|
#include "src/tint/ir/binary.h"
|
||||||
@ -27,6 +26,7 @@
|
|||||||
#include "src/tint/ir/switch.h"
|
#include "src/tint/ir/switch.h"
|
||||||
#include "src/tint/ir/unary.h"
|
#include "src/tint/ir/unary.h"
|
||||||
#include "src/tint/utils/hashmap.h"
|
#include "src/tint/utils/hashmap.h"
|
||||||
|
#include "src/tint/utils/hashset.h"
|
||||||
#include "src/tint/utils/string_stream.h"
|
#include "src/tint/utils/string_stream.h"
|
||||||
|
|
||||||
namespace tint::ir {
|
namespace tint::ir {
|
||||||
@ -56,7 +56,8 @@ class Disassembler {
|
|||||||
size_t IdOf(const FlowNode* node);
|
size_t IdOf(const FlowNode* node);
|
||||||
std::string_view IdOf(const Value* node);
|
std::string_view IdOf(const Value* node);
|
||||||
|
|
||||||
void Walk();
|
void Walk(const Block* blk);
|
||||||
|
void EmitFunction(const Function* func);
|
||||||
void EmitInstruction(const Instruction* inst);
|
void EmitInstruction(const Instruction* inst);
|
||||||
void EmitValueWithType(const Value* val);
|
void EmitValueWithType(const Value* val);
|
||||||
void EmitValue(const Value* val);
|
void EmitValue(const Value* val);
|
||||||
@ -70,7 +71,7 @@ class Disassembler {
|
|||||||
|
|
||||||
const Module& mod_;
|
const Module& mod_;
|
||||||
utils::StringStream out_;
|
utils::StringStream out_;
|
||||||
std::deque<const FlowNode*> walk_list_;
|
utils::Hashset<const Block*, 32> visited_;
|
||||||
utils::Hashmap<const FlowNode*, size_t, 32> flow_node_ids_;
|
utils::Hashmap<const FlowNode*, size_t, 32> flow_node_ids_;
|
||||||
utils::Hashmap<const Value*, std::string, 32> value_ids_;
|
utils::Hashmap<const Value*, std::string, 32> value_ids_;
|
||||||
uint32_t indent_size_ = 0;
|
uint32_t indent_size_ = 0;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -35,20 +35,20 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Bitcast) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func my_func():f32 -> %fn2
|
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func my_func():f32 -> %fn2 {
|
||||||
%fn2 = block {
|
%fn2 = block {
|
||||||
br %fn3 0.0f # return
|
br %fn3 0.0f # return
|
||||||
|
}
|
||||||
|
%fn3 = func_terminator
|
||||||
}
|
}
|
||||||
%fn3 = func_terminator
|
%fn4 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn5 {
|
||||||
|
%fn5 = block {
|
||||||
%fn4 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn5
|
%1:f32 = call my_func
|
||||||
%fn5 = block {
|
%tint_symbol:f32 = bitcast %1
|
||||||
%1:f32 = call my_func
|
br %fn6 # return
|
||||||
%tint_symbol:f32 = bitcast %1
|
}
|
||||||
br %fn6 # return
|
%fn6 = func_terminator
|
||||||
}
|
}
|
||||||
%fn6 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,13 +62,13 @@ TEST_F(IR_BuilderImplTest, EmitStatement_Discard) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func test_function():void [@fragment] -> %fn2
|
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func test_function():void [@fragment] -> %fn2 {
|
||||||
%fn2 = block {
|
%fn2 = block {
|
||||||
discard
|
discard
|
||||||
br %fn3 # return
|
br %fn3 # return
|
||||||
|
}
|
||||||
|
%fn3 = func_terminator
|
||||||
}
|
}
|
||||||
%fn3 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,19 +80,19 @@ TEST_F(IR_BuilderImplTest, EmitStatement_UserFunction) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func my_func(%p:f32):void -> %fn2
|
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func my_func(%p:f32):void -> %fn2 {
|
||||||
%fn2 = block {
|
%fn2 = block {
|
||||||
br %fn3 # return
|
br %fn3 # return
|
||||||
|
}
|
||||||
|
%fn3 = func_terminator
|
||||||
}
|
}
|
||||||
%fn3 = func_terminator
|
%fn4 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn5 {
|
||||||
|
%fn5 = block {
|
||||||
%fn4 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn5
|
%2:void = call my_func, 6.0f
|
||||||
%fn5 = block {
|
br %fn6 # return
|
||||||
%2:void = call my_func, 6.0f
|
}
|
||||||
br %fn6 # return
|
%fn6 = func_terminator
|
||||||
}
|
}
|
||||||
%fn6 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,21 +104,22 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Convert) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = block {
|
EXPECT_EQ(Disassemble(m.Get()), R"(# Root block
|
||||||
|
%fn1 = block {
|
||||||
%i:ptr<private, i32, read_write> = var, 1i
|
%i:ptr<private, i32, read_write> = var, 1i
|
||||||
br %fn2 # root_end
|
br %fn2 # root_end
|
||||||
}
|
}
|
||||||
|
|
||||||
%fn2 = root_terminator
|
%fn2 = root_terminator
|
||||||
|
|
||||||
%fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn4
|
%fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn4 {
|
||||||
%fn4 = block {
|
%fn4 = block {
|
||||||
%2:i32 = load %i
|
%2:i32 = load %i
|
||||||
%tint_symbol:f32 = convert i32, %2
|
%tint_symbol:f32 = convert i32, %2
|
||||||
br %fn5 # return
|
br %fn5 # return
|
||||||
|
}
|
||||||
|
%fn5 = func_terminator
|
||||||
}
|
}
|
||||||
%fn5 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +130,8 @@ TEST_F(IR_BuilderImplTest, EmitExpression_ConstructEmpty) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = block {
|
EXPECT_EQ(Disassemble(m.Get()), R"(# Root block
|
||||||
|
%fn1 = block {
|
||||||
%i:ptr<private, vec3<f32>, read_write> = var, vec3<f32> 0.0f
|
%i:ptr<private, vec3<f32>, read_write> = var, vec3<f32> 0.0f
|
||||||
br %fn2 # root_end
|
br %fn2 # root_end
|
||||||
}
|
}
|
||||||
@ -147,21 +149,22 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Construct) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = block {
|
EXPECT_EQ(Disassemble(m.Get()), R"(# Root block
|
||||||
|
%fn1 = block {
|
||||||
%i:ptr<private, f32, read_write> = var, 1.0f
|
%i:ptr<private, f32, read_write> = var, 1.0f
|
||||||
br %fn2 # root_end
|
br %fn2 # root_end
|
||||||
}
|
}
|
||||||
|
|
||||||
%fn2 = root_terminator
|
%fn2 = root_terminator
|
||||||
|
|
||||||
%fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn4
|
%fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn4 {
|
||||||
%fn4 = block {
|
%fn4 = block {
|
||||||
%2:f32 = load %i
|
%2:f32 = load %i
|
||||||
%tint_symbol:vec3<f32> = construct 2.0f, 3.0f, %2
|
%tint_symbol:vec3<f32> = construct 2.0f, 3.0f, %2
|
||||||
br %fn5 # return
|
br %fn5 # return
|
||||||
|
}
|
||||||
|
%fn5 = func_terminator
|
||||||
}
|
}
|
||||||
%fn5 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,12 +34,12 @@ TEST_F(IR_BuilderImplTest, EmitExpression_MaterializedCall) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func test_function():f32 -> %fn2
|
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func test_function():f32 -> %fn2 {
|
||||||
%fn2 = block {
|
%fn2 = block {
|
||||||
br %fn3 2.0f # return
|
br %fn3 2.0f # return
|
||||||
|
}
|
||||||
|
%fn3 = func_terminator
|
||||||
}
|
}
|
||||||
%fn3 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,20 +35,21 @@ TEST_F(IR_BuilderImplTest, EmitStatement_Assign) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = block {
|
EXPECT_EQ(Disassemble(m.Get()), R"(# Root block
|
||||||
|
%fn1 = block {
|
||||||
%a:ptr<private, u32, read_write> = var
|
%a:ptr<private, u32, read_write> = var
|
||||||
br %fn2 # root_end
|
br %fn2 # root_end
|
||||||
}
|
}
|
||||||
|
|
||||||
%fn2 = root_terminator
|
%fn2 = root_terminator
|
||||||
|
|
||||||
%fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn4
|
%fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn4 {
|
||||||
%fn4 = block {
|
%fn4 = block {
|
||||||
store %a, 4u
|
store %a, 4u
|
||||||
br %fn5 # return
|
br %fn5 # return
|
||||||
|
}
|
||||||
|
%fn5 = func_terminator
|
||||||
}
|
}
|
||||||
%fn5 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -34,20 +34,20 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Unary_Not) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func my_func():bool -> %fn2
|
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func my_func():bool -> %fn2 {
|
||||||
%fn2 = block {
|
%fn2 = block {
|
||||||
br %fn3 false # return
|
br %fn3 false # return
|
||||||
|
}
|
||||||
|
%fn3 = func_terminator
|
||||||
}
|
}
|
||||||
%fn3 = func_terminator
|
%fn4 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn5 {
|
||||||
|
%fn5 = block {
|
||||||
%fn4 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn5
|
%1:bool = call my_func
|
||||||
%fn5 = block {
|
%tint_symbol:bool = eq %1, false
|
||||||
%1:bool = call my_func
|
br %fn6 # return
|
||||||
%tint_symbol:bool = eq %1, false
|
}
|
||||||
br %fn6 # return
|
%fn6 = func_terminator
|
||||||
}
|
}
|
||||||
%fn6 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,20 +59,20 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Unary_Complement) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func my_func():u32 -> %fn2
|
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func my_func():u32 -> %fn2 {
|
||||||
%fn2 = block {
|
%fn2 = block {
|
||||||
br %fn3 1u # return
|
br %fn3 1u # return
|
||||||
|
}
|
||||||
|
%fn3 = func_terminator
|
||||||
}
|
}
|
||||||
%fn3 = func_terminator
|
%fn4 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn5 {
|
||||||
|
%fn5 = block {
|
||||||
%fn4 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn5
|
%1:u32 = call my_func
|
||||||
%fn5 = block {
|
%tint_symbol:u32 = complement %1
|
||||||
%1:u32 = call my_func
|
br %fn6 # return
|
||||||
%tint_symbol:u32 = complement %1
|
}
|
||||||
br %fn6 # return
|
%fn6 = func_terminator
|
||||||
}
|
}
|
||||||
%fn6 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,20 +84,20 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Unary_Negation) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func my_func():i32 -> %fn2
|
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = func my_func():i32 -> %fn2 {
|
||||||
%fn2 = block {
|
%fn2 = block {
|
||||||
br %fn3 1i # return
|
br %fn3 1i # return
|
||||||
|
}
|
||||||
|
%fn3 = func_terminator
|
||||||
}
|
}
|
||||||
%fn3 = func_terminator
|
%fn4 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn5 {
|
||||||
|
%fn5 = block {
|
||||||
%fn4 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn5
|
%1:i32 = call my_func
|
||||||
%fn5 = block {
|
%tint_symbol:i32 = negation %1
|
||||||
%1:i32 = call my_func
|
br %fn6 # return
|
||||||
%tint_symbol:i32 = negation %1
|
}
|
||||||
br %fn6 # return
|
%fn6 = func_terminator
|
||||||
}
|
}
|
||||||
%fn6 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,19 +110,20 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Unary_AddressOf) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = block {
|
EXPECT_EQ(Disassemble(m.Get()), R"(# Root block
|
||||||
|
%fn1 = block {
|
||||||
%v2:ptr<private, i32, read_write> = var
|
%v2:ptr<private, i32, read_write> = var
|
||||||
br %fn2 # root_end
|
br %fn2 # root_end
|
||||||
}
|
}
|
||||||
|
|
||||||
%fn2 = root_terminator
|
%fn2 = root_terminator
|
||||||
|
|
||||||
%fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn4
|
%fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn4 {
|
||||||
%fn4 = block {
|
%fn4 = block {
|
||||||
br %fn5 # return
|
br %fn5 # return
|
||||||
|
}
|
||||||
|
%fn5 = func_terminator
|
||||||
}
|
}
|
||||||
%fn5 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,20 +138,21 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Unary_Indirection) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = block {
|
EXPECT_EQ(Disassemble(m.Get()), R"(# Root block
|
||||||
|
%fn1 = block {
|
||||||
%v3:ptr<private, i32, read_write> = var
|
%v3:ptr<private, i32, read_write> = var
|
||||||
br %fn2 # root_end
|
br %fn2 # root_end
|
||||||
}
|
}
|
||||||
|
|
||||||
%fn2 = root_terminator
|
%fn2 = root_terminator
|
||||||
|
|
||||||
%fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn4
|
%fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn4 {
|
||||||
%fn4 = block {
|
%fn4 = block {
|
||||||
store %v3, 42i
|
store %v3, 42i
|
||||||
br %fn5 # return
|
br %fn5 # return
|
||||||
|
}
|
||||||
|
%fn5 = func_terminator
|
||||||
}
|
}
|
||||||
%fn5 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,8 @@ TEST_F(IR_BuilderImplTest, Emit_GlobalVar_NoInit) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = block {
|
EXPECT_EQ(Disassemble(m.Get()), R"(# Root block
|
||||||
|
%fn1 = block {
|
||||||
%a:ptr<private, u32, read_write> = var
|
%a:ptr<private, u32, read_write> = var
|
||||||
br %fn2 # root_end
|
br %fn2 # root_end
|
||||||
}
|
}
|
||||||
@ -49,7 +50,8 @@ TEST_F(IR_BuilderImplTest, Emit_GlobalVar_Init) {
|
|||||||
auto m = Build();
|
auto m = Build();
|
||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = block {
|
EXPECT_EQ(Disassemble(m.Get()), R"(# Root block
|
||||||
|
%fn1 = block {
|
||||||
%a:ptr<private, u32, read_write> = var, 2u
|
%a:ptr<private, u32, read_write> = var, 2u
|
||||||
br %fn2 # root_end
|
br %fn2 # root_end
|
||||||
}
|
}
|
||||||
@ -67,13 +69,13 @@ TEST_F(IR_BuilderImplTest, Emit_Var_NoInit) {
|
|||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()),
|
EXPECT_EQ(Disassemble(m.Get()),
|
||||||
R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn2
|
R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn2 {
|
||||||
%fn2 = block {
|
%fn2 = block {
|
||||||
%a:ptr<function, u32, read_write> = var
|
%a:ptr<function, u32, read_write> = var
|
||||||
br %fn3 # return
|
br %fn3 # return
|
||||||
|
}
|
||||||
|
%fn3 = func_terminator
|
||||||
}
|
}
|
||||||
%fn3 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,13 +88,13 @@ TEST_F(IR_BuilderImplTest, Emit_Var_Init) {
|
|||||||
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
|
||||||
|
|
||||||
EXPECT_EQ(Disassemble(m.Get()),
|
EXPECT_EQ(Disassemble(m.Get()),
|
||||||
R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn2
|
R"(%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)] -> %fn2 {
|
||||||
%fn2 = block {
|
%fn2 = block {
|
||||||
%a:ptr<function, u32, read_write> = var, 2u
|
%a:ptr<function, u32, read_write> = var, 2u
|
||||||
br %fn3 # return
|
br %fn3 # return
|
||||||
|
}
|
||||||
|
%fn3 = func_terminator
|
||||||
}
|
}
|
||||||
%fn3 = func_terminator
|
|
||||||
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -25,12 +25,12 @@ using IR_AddEmptyEntryPointTest = TransformTest;
|
|||||||
|
|
||||||
TEST_F(IR_AddEmptyEntryPointTest, EmptyModule) {
|
TEST_F(IR_AddEmptyEntryPointTest, EmptyModule) {
|
||||||
auto* expect = R"(
|
auto* expect = R"(
|
||||||
%fn1 = func unused_entry_point():void [@compute @workgroup_size(1, 1, 1)] -> %fn2
|
%fn1 = func unused_entry_point():void [@compute @workgroup_size(1, 1, 1)] -> %fn2 {
|
||||||
%fn2 = block {
|
%fn2 = block {
|
||||||
br %fn3 # return
|
br %fn3 # return
|
||||||
|
}
|
||||||
|
%fn3 = func_terminator
|
||||||
}
|
}
|
||||||
%fn3 = func_terminator
|
|
||||||
|
|
||||||
)";
|
)";
|
||||||
|
|
||||||
Run<AddEmptyEntryPoint>();
|
Run<AddEmptyEntryPoint>();
|
||||||
@ -44,12 +44,12 @@ TEST_F(IR_AddEmptyEntryPointTest, ExistingEntryPoint) {
|
|||||||
mod.functions.Push(ep);
|
mod.functions.Push(ep);
|
||||||
|
|
||||||
auto* expect = R"(
|
auto* expect = R"(
|
||||||
%fn1 = func main():void [@fragment] -> %fn2
|
%fn1 = func main():void [@fragment] -> %fn2 {
|
||||||
%fn2 = block {
|
%fn2 = block {
|
||||||
br %fn3 # return
|
br %fn3 # return
|
||||||
|
}
|
||||||
|
%fn3 = func_terminator
|
||||||
}
|
}
|
||||||
%fn3 = func_terminator
|
|
||||||
|
|
||||||
)";
|
)";
|
||||||
|
|
||||||
Run<AddEmptyEntryPoint>();
|
Run<AddEmptyEntryPoint>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user