Skip to content

Commit 2c6d5af

Browse files
committed
Copy propagation redesign
This rewrites functionality that was mostly disabled but is now ready to be enabled. Allow lifetime canonicalization of owned values and function arguments as a simple stand-alone utility. This is now being called from within SILCombine, so we should only do the kind of canonicalization that makes sense in that context. Canonicalizing other borrow scopes should *not* be invoked as a single-value cleanup because it affects other lifetimes outside the borrow scope boundary. It is a somewhat complicated process that hoists and sinks forwarding instructions and can generate surrounding compensation code. The copy propagation pass knows how to post-process the related lifetimes in just the right order. So borrow scope rewriting should only be done in the copy propagation pass. Similarly, only do simple canonicalization of owned values and function arguments at -Onone. The feature to canoncalize borrow scopes is now ready to be enabled (-canonical-ossa-rewrite-borrows), but flipping the switch should be a separate commit. So most of the functionality that was affected is not exposed by this PR. Changes: Split canonicalization of owned lifetimes vs. borrowed lifetimes into separate utilities. The owned lifetime utility is now back to being the simple utility that I originally envisioned. So not much happened to it other than removing complexity. We now have a separate entry point for finding the starting point for rewriting borrow scopes: CanonicalizeBorrowScope::getCanonicalBorrowedDef. We now have a utility that defines forwarding instructions that we can treat consistently as part of a guaranteed lifetime, CanonicalizeBorrowScope::isRewritableOSSAForward. We now have a utility that defines the uses of a borrowed value that are considered part of its lifetime, CanonicalizeBorrowScope::visitBorrowScopeUses. This single utility is used to implement three different parts of the alogrithm: 1. Find any uses of the borrowed value that need to be propagated outside the borrow scope 2. RewriteInnerBorrowUses for SILFunction arguments and borrow scopes with no outer uses. 3. RewriteOuterBorrowUses for borrow scopes with outer uses. Handling these involves creating new copies outside the borrow scope and hoisting forwarding instructions. The end result is that a lot of borrow scopes can be eliminated and owned values can be forwarded to destructures, reducing copies and destroys. If we stop generating borrow scopes for all interior pointers, then we'll need to design a comparable optimization that works on "implicit" borrow scopes: %ownedDef = ... %element struct_extract %ownedDef %copy = copy_value %element apply(@guaranteed %element) apply(@owned %copy) destroy %ownedDef Should be: %ownedDef = ... %borrowedElement = destructure_struct @guaranteed %ownedDef apply(@guaranteed %borrowedElement) %ownedElement = destructure_struct %ownedDef apply(@owned %copy)
1 parent 3050542 commit 2c6d5af

File tree

6 files changed

+1561
-851
lines changed

6 files changed

+1561
-851
lines changed

0 commit comments

Comments
 (0)