Skip to content

Commit

Permalink
Update the computation of the control flow graph
Browse files Browse the repository at this point in the history
  • Loading branch information
vouillon committed Feb 7, 2025
1 parent 4de3787 commit 50d6418
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 59 deletions.
27 changes: 27 additions & 0 deletions src/cfg/cfg-traversal.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,19 @@ struct CFGWalker : public PostWalker<SubType, VisitorType> {
self->tryStack.pop_back();
}

static void doEndResume(SubType* self, Expression** currp) {
auto* module = self->getModule();
if (!module || module->features.hasExceptionHandling()) {
// This resume might throw, so run the code to handle that.
doEndThrowingInst(self, currp);
}
auto handlerBlocks = BranchUtils::getUniqueTargets(*currp);
// Add branches to the targets.
for (auto target : handlerBlocks) {
self->branches[target].push_back(self->currBasicBlock);
}
}

static bool isReturnCall(Expression* curr) {
switch (curr->_id) {
case Expression::Id::CallId:
Expand Down Expand Up @@ -521,6 +534,20 @@ struct CFGWalker : public PostWalker<SubType, VisitorType> {
self->pushTask(SubType::doEndThrow, currp);
break;
}
case Expression::Id::ResumeId:
case Expression::Id::ResumeThrowId: {
self->pushTask(SubType::doEndResume, currp);
break;
}
case Expression::Id::SuspendId:
case Expression::Id::StackSwitchId: {
auto* module = self->getModule();
if (!module || module->features.hasExceptionHandling()) {
// This might throw, so run the code to handle that.
self->pushTask(SubType::doEndCall, currp);
}
break;
}
default: {
if (Properties::isBranch(curr)) {
self->pushTask(SubType::doEndBranch, currp);
Expand Down
91 changes: 48 additions & 43 deletions test/lit/passes/O3_stack-switching.wast
Original file line number Diff line number Diff line change
Expand Up @@ -25,64 +25,69 @@
(tag $effect (param (ref eq)) (result (ref eq) (ref eq)))

;; CHECK: (func $resume (type $10) (param $0 (ref $fiber)) (param $1 (ref $closure)) (param $2 (ref eq)) (result (ref eq))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local $3 (tuple (ref eq) (ref $cont)))
;; CHECK-NEXT: (local $4 (ref $handlers))
;; CHECK-NEXT: (local $5 (ref $closure_2))
;; CHECK-NEXT: (return_call_ref $function_1
;; CHECK-NEXT: (block $handle_exception (result (ref eq))
;; CHECK-NEXT: (tuple.drop 2
;; CHECK-NEXT: (block $handle_effect (type $3) (result (ref eq) (ref $cont))
;; CHECK-NEXT: (return_call_ref $function_1
;; CHECK-NEXT: (try_table (result (ref eq)) (catch $exception $handle_exception)
;; CHECK-NEXT: (resume $cont (on $effect $handle_effect)
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: (struct.get $fiber $cont
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: (return_call_ref $function_2
;; CHECK-NEXT: (tuple.extract 2 0
;; CHECK-NEXT: (local.tee $3
;; CHECK-NEXT: (block $handle_effect (type $7) (result (ref eq) (ref $cont))
;; CHECK-NEXT: (return_call_ref $function_1
;; CHECK-NEXT: (try_table (result (ref eq)) (catch $exception $handle_exception)
;; CHECK-NEXT: (resume $cont (on $effect $handle_effect)
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: (struct.get $fiber $cont
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.tee $1
;; CHECK-NEXT: (struct.get $handlers $value
;; CHECK-NEXT: (struct.get $fiber $handlers
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: (local.tee $1
;; CHECK-NEXT: (struct.get $handlers $value
;; CHECK-NEXT: (struct.get $fiber $handlers
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.get $closure 0
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.get $closure 0
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block ;; (replaces unreachable CallRef we can't emit)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block ;; (replaces unreachable StructGet we can't emit)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block ;; (replaces unreachable StructGet we can't emit)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: (struct.new $fiber
;; CHECK-NEXT: (local.tee $4
;; CHECK-NEXT: (struct.get $fiber $handlers
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: (tuple.extract 2 1
;; CHECK-NEXT: (local.get $3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: (local.tee $5
;; CHECK-NEXT: (struct.get $handlers $effect
;; CHECK-NEXT: (local.get $4)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.get $closure_2 0
;; CHECK-NEXT: (local.get $5)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block ;; (replaces unreachable StructGet we can't emit)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: (local.tee $1
;; CHECK-NEXT: (struct.get $handlers $exn
;; CHECK-NEXT: (struct.get $fiber $handlers
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: (struct.get $closure 0
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $resume (export "resume") (param $fiber (ref $fiber)) (param $f (ref $closure)) (param $v (ref eq)) (result (ref eq))
Expand Down
28 changes: 12 additions & 16 deletions test/lit/passes/coalesce-locals-stack-switching.wast
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@

;; CHECK: (func $resume (type $2) (param $0 (ref $cont)) (result i32)
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (block $handle_exn (result i32)
;; CHECK-NEXT: (try_table (catch $exn $handle_exn)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (block $handle_effect (result (ref $cont))
;; CHECK-NEXT: (resume $cont (on $tag $handle_effect)
;; CHECK-NEXT: (local.get $0)
Expand All @@ -32,17 +32,15 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (return_call $resume
;; CHECK-NEXT: (block (result (ref $cont))
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (return
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
(func $resume (param $c (ref $cont)) (result i32)
(local $x i32)
Expand Down Expand Up @@ -77,10 +75,10 @@

;; CHECK: (func $resume_throw (type $2) (param $0 (ref $cont)) (result i32)
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (block $handle_exn (result i32)
;; CHECK-NEXT: (try_table (catch $exn $handle_exn)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (block $handle_effect (result (ref $cont))
;; CHECK-NEXT: (resume_throw $cont $tag (on $tag $handle_effect)
;; CHECK-NEXT: (local.get $0)
Expand All @@ -91,17 +89,15 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (return_call $resume
;; CHECK-NEXT: (block (result (ref $cont))
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (return
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
(func $resume_throw (param $c (ref $cont)) (result i32)
(local $x i32)
Expand Down Expand Up @@ -136,7 +132,7 @@

;; CHECK: (func $suspend (type $6) (result i32)
;; CHECK-NEXT: (local $0 i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (block $handle_exn (result i32)
;; CHECK-NEXT: (try_table (catch $exn $handle_exn)
;; CHECK-NEXT: (suspend $tag)
Expand All @@ -146,7 +142,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
(func $suspend (result i32)
(local $x i32)
Expand All @@ -167,7 +163,7 @@

;; CHECK: (func $switch (type $7) (param $0 (ref $cont_2)) (result i32)
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (block $handle_exn (result i32)
;; CHECK-NEXT: (try_table (catch $exn $handle_exn)
;; CHECK-NEXT: (switch $cont_2 $tag
Expand All @@ -179,7 +175,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
(func $switch (param $c (ref $cont_2)) (result i32)
(local $x i32)
Expand Down

0 comments on commit 50d6418

Please sign in to comment.