forked from OSchip/llvm-project
[InstCombine] Extend stacksave/restore elimination
Previously, InstCombine detected a pair of llvm.stacksave/stackrestore instructions that are adjacent modulo debug instructions in order to eliminate the llvm.stackrestore. This precludes situations where intervening instructions (e.g. loads) preclude the llvm.stacksave and llvm.stackrestore from becoming adjacent. This commit extends the logic and allows for eliminating the llvm.stackrestore when the range of instructions between them does not include any alloca or side-effect causing instructions. Signed-off-by: Itay Bookstein <itay.bookstein@nextsilicon.com> Reviewed By: lebedev.ri Differential Revision: https://reviews.llvm.org/D113105
This commit is contained in:
parent
fe7491d32f
commit
f9059efa0d
|
@ -1802,14 +1802,40 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
|
|||
return ClassifyResult::None;
|
||||
};
|
||||
|
||||
// If the save is right next to the restore, remove the restore. This can
|
||||
// happen when variable allocas are DCE'd.
|
||||
// If the stacksave and the stackrestore are in the same BB, and there is
|
||||
// no intervening call, alloca, or stackrestore of a different stacksave,
|
||||
// remove the restore. This can happen when variable allocas are DCE'd.
|
||||
if (IntrinsicInst *SS = dyn_cast<IntrinsicInst>(II->getArgOperand(0))) {
|
||||
if (SS->getIntrinsicID() == Intrinsic::stacksave) {
|
||||
// Skip over debug info.
|
||||
if (SS->getNextNonDebugInstruction() == II) {
|
||||
return eraseInstFromFunction(CI);
|
||||
if (SS->getIntrinsicID() == Intrinsic::stacksave &&
|
||||
SS->getParent() == II->getParent()) {
|
||||
BasicBlock::iterator BI(SS);
|
||||
bool CannotRemove = false;
|
||||
for (++BI; &*BI != II; ++BI) {
|
||||
switch (Classify(&*BI)) {
|
||||
case ClassifyResult::None:
|
||||
// So far so good, look at next instructions.
|
||||
break;
|
||||
|
||||
case ClassifyResult::StackRestore:
|
||||
// If we found an intervening stackrestore for a different
|
||||
// stacksave, we can't remove the stackrestore. Otherwise, continue.
|
||||
if (cast<IntrinsicInst>(*BI).getArgOperand(0) != SS)
|
||||
CannotRemove = true;
|
||||
break;
|
||||
|
||||
case ClassifyResult::Alloca:
|
||||
case ClassifyResult::CallWithSideEffects:
|
||||
// If we found an alloca, a non-intrinsic call, or an intrinsic
|
||||
// call with side effects, we can't remove the stackrestore.
|
||||
CannotRemove = true;
|
||||
break;
|
||||
}
|
||||
if (CannotRemove)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CannotRemove)
|
||||
return eraseInstFromFunction(CI);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -110,3 +110,31 @@ return:
|
|||
; CHECK: call void @llvm.stackrestore(i8* %save1)
|
||||
; CHECK: br i1 %done, label %loop, label %return
|
||||
; CHECK: ret void
|
||||
|
||||
define i32 @test4(i32 %m, i32* %a, i32* %b) {
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
for.body:
|
||||
%x.012 = phi i32 [ 0, %entry ], [ %add2, %for.body ]
|
||||
%i.011 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
|
||||
%0 = call i8* @llvm.stacksave()
|
||||
%load1 = load i32, i32* %a, align 4
|
||||
%mul1 = mul nsw i32 %load1, %m
|
||||
%add1 = add nsw i32 %mul1, %x.012
|
||||
call void @llvm.stackrestore(i8* %0)
|
||||
%load2 = load i32, i32* %b, align 4
|
||||
%mul2 = mul nsw i32 %load2, %m
|
||||
%add2 = add nsw i32 %mul2, %add1
|
||||
call void @llvm.stackrestore(i8* %0)
|
||||
%inc = add nuw nsw i32 %i.011, 1
|
||||
%exitcond.not = icmp eq i32 %inc, 100
|
||||
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
|
||||
|
||||
for.cond.cleanup:
|
||||
ret i32 %add2
|
||||
}
|
||||
|
||||
; CHECK-LABEL: define i32 @test4(
|
||||
; CHECK-NOT: call void @llvm.stackrestore
|
||||
; CHECK: ret i32 %add2
|
||||
|
|
Loading…
Reference in New Issue