-
Notifications
You must be signed in to change notification settings - Fork 10.5k
TempRValueOptPass: accept try_apply as user of the temporary object #27721
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1645,7 +1645,8 @@ bool TempRValueOptPass::collectLoads( | |
<< *user); | ||
return false; | ||
|
||
case SILInstructionKind::ApplyInst: { | ||
case SILInstructionKind::ApplyInst: | ||
case SILInstructionKind::TryApplyInst: { | ||
ApplySite apply(user); | ||
|
||
// Check if the function can just read from userOp. | ||
|
@@ -1714,12 +1715,10 @@ bool TempRValueOptPass::collectLoads( | |
|
||
case SILInstructionKind::LoadInst: | ||
case SILInstructionKind::LoadBorrowInst: | ||
case SILInstructionKind::WitnessMethodInst: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did you remove the rest of this stuff from this PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added more detailed comment in the commit message (I should have copied that to the PR description):
I hope that answers your question There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is the wrong approach. It will make it so that we by mistake handle things that we may not intend to. That is a large problem with this pass. Thought: why not instead make it so that the default in asserts builds asserts, but in non-asserts builds has the other behavior? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't agree. We want to handle a few instructions in a special way, all other instructions the same. So IMO, using "default" is the right choice here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The statement "we want to handle a few instruction in a special way, all other instructions the same" is incorrect. When this pass was written we were pattern matching a specific semantic codegen pattern, so the code was written this way by @atrick to make sure that we /only/ pattern matched that pattern and if we hit a pattern by mistake that was not anticipated, we got a nice error from the compiler so we knew to update this code. With this change, we will not get that error and instead will start silently accepting such new code patterns, allowing for the introduction of bugs and a reduction in the quality and correctness of the compiler. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really care about this particular case--it seems fairly hard to break. But Michael is right that the original intention was for the optimization to be self-checking. When correctness is at stake, it's generally important to list both the specially handled instructions and the "known-safe" instructions. There are so many variations of SIL operations, and we're continually adding more, so new instructions might come along that need special handling. (The previous bug was that an instruction was specially handled, but handled incorrectly). Listing known-safe cases also communicates to future maintainers which cases were deliberately handled vs. which cases were forgotten. It helps me when reading the code to know what all the expected cases are without taking time to step through the code. There is always the tradeoff between aggressively asserting in optimization passes vs. falling back to something that is probably safe. The LLVM/Swift approach has generally been to aggressively assert. It means many more bug reports early on but fewer hard-to-reproduce bugs later in the produce lifecycle. |
||
// Loads are the end of the data flow chain. The users of the load can't | ||
// access the temporary storage. | ||
loadInsts.insert(user); | ||
return true; | ||
} | ||
|
||
case SILInstructionKind::CopyAddrInst: { | ||
// copy_addr which read from the temporary are like loads. | ||
|
@@ -1834,17 +1833,9 @@ bool TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) { | |
use->set(copyInst->getSrc()); | ||
break; | ||
} | ||
case SILInstructionKind::StructElementAddrInst: | ||
case SILInstructionKind::TupleElementAddrInst: | ||
case SILInstructionKind::LoadInst: | ||
case SILInstructionKind::LoadBorrowInst: | ||
case SILInstructionKind::ApplyInst: | ||
case SILInstructionKind::OpenExistentialAddrInst: | ||
default: | ||
use->set(copyInst->getSrc()); | ||
break; | ||
|
||
default: | ||
llvm_unreachable("unhandled instruction"); | ||
} | ||
} | ||
tempObj->eraseFromParent(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this ever work if something isn't a full apply site? If not, can you make this a full apply site?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that would probably be more descriptive. But using an ApplySite does not hurt here, because the switch case already selects only full apply sites: ApplyInst and TryApplyInst.