Skip to content

[TempRValueOpt] Fold added destroy_addrs into loads/copy_addrs. #65052

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

Merged
merged 4 commits into from
Apr 12, 2023

Conversation

nate-chandler
Copy link
Contributor

To avoid introducing new copies--which is illegal for move-only values-- don't rewrite load [take]s and copy_addr [take]s as load [copy]s and copy_addrs respectively and introduce new destroy_addrs after them. Instead, get the effect of folding such a newly created destroy_addr into the preceding rewritten load [copy] or copy_addr. Get that effect by neither modifying the copy_addr [take] or load [take] nor adding a subsequent destroy_addr.

An example for each kind (load [take] and copy_addr [take]):

// Input 1 (`load [take]`)
  copy_addr [take] %src to [init] %tmp
  %val = load [take] %src
// Old Output 1
  %val = load [copy] %src
  destroy_addr %src
// New Output 2
  %val = load [take] %src
// Input 2 (`copy_addr [take]`)
  copy_addr [take] %src to [init] %tmp
  copy_addr [take] %src to [init] %dst
// Old Output 2
  copy_addr %src to [init] %dst
  destroy_addr %src
// New Output 2
  copy_addr [take] %src to [init] %dst

rdar://107839979

@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler
Copy link
Contributor Author

@swift-ci please benchmark

@nate-chandler
Copy link
Contributor Author

@swift-ci please test source compatibility

@nate-chandler
Copy link
Contributor Author

Source compat failures match baseline.

Copy link
Contributor

@eeckstein eeckstein left a comment

Choose a reason for hiding this comment

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

lgtm

li->getOwnershipQualifier() != LoadOwnershipQualifier::Take;
}
return true;
}();
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe you can add an assert here to check if it's a move only type then needToInsertDestroy must be false

Copy link
Contributor Author

@nate-chandler nate-chandler Apr 11, 2023

Choose a reason for hiding this comment

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

Added asserts along those lines in 1021519 . (Along with a test illustrating why needToInsertDestroy might be true even when the type is move-only--if lastLoadInst is an apply.)

In preparation for "folding" an "inserted destroy" into a load [copy] or
copy_addr, rename the variable that indicates whether the copyInst's
source must be deinitialized after its last "load".
As a separate commit to make the behavior change more obvious.
To avoid introducing new copies--which is illegal for move-only values--
don't rewrite `load [take]`s and `copy_addr [take]`s as `load [copy]`s
and `copy_addr`s respectively and introduce new `destroy_addr`s after
them.  Instead, get the effect of folding such a newly created
`destroy_addr` into the preceding rewritten `load [copy]` or
`copy_addr`.  Get that effect by neither modifying the `copy_addr [take]`
or `load [take]` nor adding a subsequent `destroy_addr`.

An example for each kind (`load [take]` and `copy_addr [take]`):

```
// Input 1 (`load [take]`)
  copy_addr [take] %src to [init] %tmp
  %val = load [take] %src
// Old Output 1
  %val = load [copy] %src
  destroy_addr %src
// New Output 2
  %val = load [take] %src
```

```
// Input 2 (`copy_addr [take]`)
  copy_addr [take] %src to [init] %tmp
  copy_addr [take] %src to [init] %dst
// Old Output 2
  copy_addr %src to [init] %dst
  destroy_addr %src
// New Output 2
  copy_addr [take] %src to [init] %dst
```

rdar://107839979
@nate-chandler
Copy link
Contributor Author

@swift-ci please test and merge

@nate-chandler
Copy link
Contributor Author

@swift-ci please test linux platform

@nate-chandler
Copy link
Contributor Author

@swift-ci please test macOS platform

@nate-chandler
Copy link
Contributor Author

@swift-ci please test linux platform

if (lastLoadInst == copyInst)
return true;
if (auto *cai = dyn_cast<CopyAddrInst>(lastLoadInst)) {
auto retval = cai->getSrc() != tempObj || !cai->isTakeOfSrc();
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: all these conditions are getting hard to understand. IMO, for clarity it's better to write

  if (cai->getSrc() == tempObj && cai->isTakeOfSrc()) {
    // Can reuse the last copy_addr as deinitialization.
    return false;
  } else {
    assert(!tempObj->getType().isMoveOnly() && "introducing copy of move-only value!?");
    return true;
  }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@nate-chandler nate-chandler merged commit 2a3e7ba into swiftlang:main Apr 12, 2023
@nate-chandler nate-chandler deleted the rdar104729396 branch April 12, 2023 14:03
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.

2 participants