Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use hints when generating fresh labels in IRBuilder #7086

Merged
merged 5 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/passes/Outlining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,14 @@ struct Outlining : public Pass {
// Position the outlined functions first in the functions vector to make
// the outlining lit tests far more readable.
moveOutlinedFunctions(module, substrings.size());

// Because we visit control flow in stringified order rather than normal
// postorder, IRBuilder is not able to properly track branches, so it may
// not have finalized blocks with the correct types. ReFinalize now to fix
// any issues.
PassRunner runner(getPassRunner());
runner.add(std::make_unique<ReFinalize>());
runner.run();
}

Name addOutlinedFunction(Module* module,
Expand Down
7 changes: 5 additions & 2 deletions src/wasm-ir-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,16 +507,19 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
// its stack.
std::unordered_map<Name, std::vector<Index>> labelDepths;

Name makeFresh(Name label) {
Name makeFresh(Name label, Index hint = 0) {
return Names::getValidName(
label,
[&](Name candidate) {
return labelDepths.insert({candidate, {}}).second;
},
0,
hint,
"");
}

Index blockHint = 0;
Index labelHint = 0;

void pushScope(ScopeCtx scope) {
if (auto label = scope.getOriginalLabel()) {
// Assign a fresh label to the scope, if necessary.
Expand Down
18 changes: 12 additions & 6 deletions src/wasm/wasm-ir-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,12 @@ Result<> IRBuilder::visitEnd() {
block->type = blockType;
return block;
}
return builder.makeBlock(label, {curr}, blockType);
auto* block = builder.makeBlock();
block->name = label;
block->list.push_back(curr);
block->finalize(blockType,
scope.labelUsed ? Block::HasBreak : Block::NoBreak);
return block;
};

if (auto* func = scope.getFunction()) {
Expand All @@ -982,12 +987,13 @@ Result<> IRBuilder::visitEnd() {
EHUtils::handleBlockNestedPops(func, wasm);
}
this->func = nullptr;
blockHint = 0;
labelHint = 0;
} else if (auto* block = scope.getBlock()) {
assert(*expr == block);
block->name = scope.label;
// TODO: Track branches so we can know whether this block is a target and
// finalize more efficiently.
block->finalize(block->type);
block->finalize(block->type,
scope.labelUsed ? Block::HasBreak : Block::NoBreak);
push(block);
} else if (auto* loop = scope.getLoop()) {
loop->body = *expr;
Expand Down Expand Up @@ -1069,9 +1075,9 @@ Result<Name> IRBuilder::getLabelName(Index label, bool forDelegate) {
if (!scopeLabel) {
// The scope does not already have a name, so we need to create one.
if ((*scope)->getBlock()) {
scopeLabel = makeFresh("block");
scopeLabel = makeFresh("block", blockHint++);
} else {
scopeLabel = makeFresh("label");
scopeLabel = makeFresh("label", labelHint++);
}
}
if (!forDelegate) {
Expand Down
38 changes: 19 additions & 19 deletions test/lit/basic/reference-types.wast
Original file line number Diff line number Diff line change
Expand Up @@ -361,88 +361,88 @@
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block0 (result eqref)
;; CHECK-TEXT-NEXT: (br_if $block0
;; CHECK-TEXT-NEXT: (global.get $global_eqref)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block1 (result eqref)
;; CHECK-TEXT-NEXT: (br_if $block1
;; CHECK-TEXT-NEXT: (ref.null none)
;; CHECK-TEXT-NEXT: (global.get $global_eqref)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block2 (result funcref)
;; CHECK-TEXT-NEXT: (block $block2 (result eqref)
;; CHECK-TEXT-NEXT: (br_if $block2
;; CHECK-TEXT-NEXT: (local.get $local_funcref)
;; CHECK-TEXT-NEXT: (ref.null none)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block3 (result funcref)
;; CHECK-TEXT-NEXT: (br_if $block3
;; CHECK-TEXT-NEXT: (global.get $global_funcref)
;; CHECK-TEXT-NEXT: (local.get $local_funcref)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block4 (result funcref)
;; CHECK-TEXT-NEXT: (br_if $block4
;; CHECK-TEXT-NEXT: (ref.null nofunc)
;; CHECK-TEXT-NEXT: (global.get $global_funcref)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block5 (result funcref)
;; CHECK-TEXT-NEXT: (br_if $block5
;; CHECK-TEXT-NEXT: (ref.func $foo)
;; CHECK-TEXT-NEXT: (ref.null nofunc)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block6 (result anyref)
;; CHECK-TEXT-NEXT: (block $block6 (result funcref)
;; CHECK-TEXT-NEXT: (br_if $block6
;; CHECK-TEXT-NEXT: (local.get $local_anyref)
;; CHECK-TEXT-NEXT: (ref.func $foo)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block7 (result anyref)
;; CHECK-TEXT-NEXT: (br_if $block7
;; CHECK-TEXT-NEXT: (global.get $global_anyref)
;; CHECK-TEXT-NEXT: (local.get $local_anyref)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block8 (result anyref)
;; CHECK-TEXT-NEXT: (br_if $block8
;; CHECK-TEXT-NEXT: (ref.null none)
;; CHECK-TEXT-NEXT: (global.get $global_anyref)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block9 (result anyref)
;; CHECK-TEXT-NEXT: (br_if $block9
;; CHECK-TEXT-NEXT: (local.get $local_eqref)
;; CHECK-TEXT-NEXT: (ref.null none)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block10 (result anyref)
;; CHECK-TEXT-NEXT: (br_if $block10
;; CHECK-TEXT-NEXT: (local.get $local_eqref)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: (drop
;; CHECK-TEXT-NEXT: (block $block11 (result anyref)
;; CHECK-TEXT-NEXT: (br_if $block11
;; CHECK-TEXT-NEXT: (ref.null none)
;; CHECK-TEXT-NEXT: (i32.const 1)
;; CHECK-TEXT-NEXT: )
Expand Down
4 changes: 2 additions & 2 deletions test/lit/passes/outlining.wast
Original file line number Diff line number Diff line change
Expand Up @@ -675,8 +675,8 @@
;; CHECK: (func $a (type $1) (param $0 i32) (result i32)
;; CHECK-NEXT: (call $outline$)
;; CHECK-NEXT: (block $block
;; CHECK-NEXT: (block $block0
;; CHECK-NEXT: (br_table $block $block0
;; CHECK-NEXT: (block $block1
;; CHECK-NEXT: (br_table $block $block1
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (return
Expand Down
18 changes: 9 additions & 9 deletions test/lit/wat-kitchen-sink.wast
Original file line number Diff line number Diff line change
Expand Up @@ -2570,14 +2570,14 @@
)

;; CHECK: (func $label-index (type $0)
;; CHECK-NEXT: (block $block1
;; CHECK-NEXT: (block $block2
;; CHECK-NEXT: (block $block
;; CHECK-NEXT: (block $block0
;; CHECK-NEXT: (block $block1
;; CHECK-NEXT: (block $l
;; CHECK-NEXT: (br $block)
;; CHECK-NEXT: (br $block0)
;; CHECK-NEXT: (br $l)
;; CHECK-NEXT: (br $block1)
;; CHECK-NEXT: (br $l)
;; CHECK-NEXT: (br $block2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
Expand Down Expand Up @@ -2844,9 +2844,9 @@
;; CHECK: (func $br-table-index (type $0)
;; CHECK-NEXT: (block $block
;; CHECK-NEXT: (block $l
;; CHECK-NEXT: (block $block1
;; CHECK-NEXT: (block $block0
;; CHECK-NEXT: (br_table $block $l $block0 $block1
;; CHECK-NEXT: (block $block2
;; CHECK-NEXT: (block $block1
;; CHECK-NEXT: (br_table $block $l $block1 $block2
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
Expand Down Expand Up @@ -4821,9 +4821,9 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block $block (result (ref $to-f32-cont))
;; CHECK-NEXT: (tuple.drop 3
;; CHECK-NEXT: (block $block0 (type $34) (result i32 i64 (ref null $simple-cont))
;; CHECK-NEXT: (block $block1 (type $34) (result i32 i64 (ref null $simple-cont))
;; CHECK-NEXT: (local.set $f
;; CHECK-NEXT: (resume $simple-cont (on $empty $block) (on $tag-pair-to-pair $block0)
;; CHECK-NEXT: (resume $simple-cont (on $empty $block) (on $tag-pair-to-pair $block1)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i64.const 1)
;; CHECK-NEXT: (local.get $ct)
Expand Down
Loading
Loading