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

[Outlining] Fixes break reconstruction #6352

Merged
merged 7 commits into from
Feb 28, 2024
Merged

[Outlining] Fixes break reconstruction #6352

merged 7 commits into from
Feb 28, 2024

Conversation

ashleynh
Copy link
Collaborator

Adds new visitBreakWithType and visitSwitchWithType functions to the IRBuilder API. These functions work around an assumption in IRBuilder that the module is being traversed in the fully nested format, i.e., that the destination scope of a break or switch has been visited before visiting the break or switch. Instead, the type of the destination scope is passed to IRBuilder.

Type type = expr->value ? expr->value->type : Type::none;
ASSERT_OK(builder->visitSwitchWithType(expr, type));
} else {
ASSERT_OK(builder->visit(curr));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to add an assertion somewhere to future-proof ourselves against the possibility that a new kind of Expression starts to need a visit*WithType variant. This could either be an assert(!Properties::isBranch(curr)) here guarding the default builder->visit(curr) case, or it could be an assertion that curr is a Break or Switch inside IRBuilder::getBranchValue.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 225 to 226
// with a corresponding push onto the scope stack. As a result, an exception
// will occur if a corresponding scope is not found for the break.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not an exception, right? Will we return an error in this case?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, not an exception. Updated!

[[nodiscard]] Result<> visitBreak(Break*,
std::optional<Index> label = std::nullopt);
// Used to visit break nodes when traversing the module in the stacky format.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be more precise.

Suggested change
// Used to visit break nodes when traversing the module in the stacky format.
// Used to visit break nodes when traversing a single block without its context.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 230 to 231
// The type indicates how many values need to be popped from the stack and
// consumed by the break.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's important that the condition (if any), which is also popped from the stack, is not included in this.

Suggested change
// The type indicates how many values need to be popped from the stack and
// consumed by the break.
// The type indicates how many values the break carries to its destination.

Similar comments apply to visitSwitchWithType below.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

CHECK_ERR(cond);
curr->condition = *cond;
}
if (!curr->value) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type should be the only source of truth here.

Suggested change
if (!curr->value) {
if (type == Type::None) {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 447 to 449
// TODO: Call more efficient versions of finalize() that take the known type
// for other kinds of nodes as well, as done above.
ReFinalizeNode{}.visit(curr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we know what kind of expression this is, we can just call finalize directly. There's also no more efficient variant for Break.

Suggested change
// TODO: Call more efficient versions of finalize() that take the known type
// for other kinds of nodes as well, as done above.
ReFinalizeNode{}.visit(curr);
curr->finalize();

Same for Switch below.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

;; CHECK-NEXT: (call $outline$)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to add a test for the br_table case as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to add comments on the assertions explaining how they are there to prevent potential future problems, but other than that, LGTM!

@ashleynh ashleynh merged commit 1ef95ae into main Feb 28, 2024
14 checks passed
@ashleynh ashleynh deleted the label_fix_pr branch February 28, 2024 01:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants