Skip to content

Disable TempRValueOpt when there are users of the temp object preceding the copy #66328

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 1 commit into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lib/SILOptimizer/Transforms/TempRValueElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,9 +547,13 @@ void TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
// only users that modify memory are the copy_addr [initialization] and
// destroy_addr.
InstructionSetWithSize loadInsts(getFunction());
// Set of tempObj users
InstructionSet userSet(getFunction());
for (auto *useOper : tempObj->getUses()) {
SILInstruction *user = useOper->getUser();

userSet.insert(user);

if (user == copyInst)
continue;

Expand All @@ -576,6 +580,20 @@ void TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
return;
}

// Check and return without optimization if we have any users of tempObj that
// precede the copyInst.
// This can happen with projections.
// TODO: We can enable this case if we clone the projections at "load" uses

// All instructions in userSet are in the same block as copyInst. collectLoads
// ensures of this.
for (SILInstruction &inst : llvm::make_range(copyInst->getParent()->begin(),
copyInst->getIterator())) {
if (userSet.contains(&inst)) {
return;
}
}

AliasAnalysis *aa = getPassManager()->getAnalysis<AliasAnalysis>(getFunction());

// Check if the source is modified within the lifetime of the temporary.
Expand Down
18 changes: 18 additions & 0 deletions test/SILOptimizer/temp_rvalue_opt_ossa.sil
Original file line number Diff line number Diff line change
Expand Up @@ -1847,3 +1847,21 @@ bb0:
dealloc_stack %src : $*MOS
return %instance_3 : $MOS
}

// CHECK-LABEL: sil [ossa] @dont_optimize_use_before_copy :
// CHECK: copy_addr
// CHECK-LABEL: } // end sil function 'dont_optimize_use_before_copy'
sil [ossa] @dont_optimize_use_before_copy : $@convention(thin) <B> (@in_guaranteed GS<B>, @inout GS<B>) -> () {
bb0(%0 : $*GS<B>, %1 : $*GS<B>):
%2 = alloc_stack $GS<B>
%3 = struct_element_addr %2 : $*GS<B>, #GS._value
copy_addr %1 to [init] %2 : $*GS<B>
%5 = load [trivial] %3 : $*Builtin.Int64
%6 = builtin "cmp_slt_Int64"(%5 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int1
copy_addr %2 to %1 : $*GS<B>
destroy_addr %2 : $*GS<B>
dealloc_stack %2 : $*GS<B>
%10 = tuple ()
return %10 : $()
}