forked from OSchip/llvm-project
[InstCombine][NFC] Refactor llvm.stackrestore handling
Hoist the instruction classification logic outside the loop in preparation for reuse in a future commit. Signed-off-by: Itay Bookstein <itay.bookstein@nextsilicon.com> Reviewed By: lebedev.ri Differential Revision: https://reviews.llvm.org/D113464
This commit is contained in:
parent
82ce912743
commit
fe7491d32f
|
@ -1776,6 +1776,32 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Intrinsic::stackrestore: {
|
case Intrinsic::stackrestore: {
|
||||||
|
enum class ClassifyResult {
|
||||||
|
None,
|
||||||
|
Alloca,
|
||||||
|
StackRestore,
|
||||||
|
CallWithSideEffects,
|
||||||
|
};
|
||||||
|
auto Classify = [](const Instruction *I) {
|
||||||
|
if (isa<AllocaInst>(I))
|
||||||
|
return ClassifyResult::Alloca;
|
||||||
|
|
||||||
|
if (auto *CI = dyn_cast<CallInst>(I)) {
|
||||||
|
if (auto *II = dyn_cast<IntrinsicInst>(CI)) {
|
||||||
|
if (II->getIntrinsicID() == Intrinsic::stackrestore)
|
||||||
|
return ClassifyResult::StackRestore;
|
||||||
|
|
||||||
|
if (II->mayHaveSideEffects())
|
||||||
|
return ClassifyResult::CallWithSideEffects;
|
||||||
|
} else {
|
||||||
|
// Consider all non-intrinsic calls to be side effects
|
||||||
|
return ClassifyResult::CallWithSideEffects;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ClassifyResult::None;
|
||||||
|
};
|
||||||
|
|
||||||
// If the save is right next to the restore, remove the restore. This can
|
// If the save is right next to the restore, remove the restore. This can
|
||||||
// happen when variable allocas are DCE'd.
|
// happen when variable allocas are DCE'd.
|
||||||
if (IntrinsicInst *SS = dyn_cast<IntrinsicInst>(II->getArgOperand(0))) {
|
if (IntrinsicInst *SS = dyn_cast<IntrinsicInst>(II->getArgOperand(0))) {
|
||||||
|
@ -1793,29 +1819,25 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
|
||||||
Instruction *TI = II->getParent()->getTerminator();
|
Instruction *TI = II->getParent()->getTerminator();
|
||||||
bool CannotRemove = false;
|
bool CannotRemove = false;
|
||||||
for (++BI; &*BI != TI; ++BI) {
|
for (++BI; &*BI != TI; ++BI) {
|
||||||
if (isa<AllocaInst>(BI)) {
|
switch (Classify(&*BI)) {
|
||||||
|
case ClassifyResult::None:
|
||||||
|
// So far so good, look at next instructions.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ClassifyResult::StackRestore:
|
||||||
|
// If there is a stackrestore below this one, remove this one.
|
||||||
|
return eraseInstFromFunction(CI);
|
||||||
|
|
||||||
|
case ClassifyResult::Alloca:
|
||||||
|
case ClassifyResult::CallWithSideEffects:
|
||||||
|
// If we found an alloca, a non-intrinsic call, or an intrinsic call
|
||||||
|
// with side effects (such as llvm.stacksave and llvm.read_register),
|
||||||
|
// we can't remove the stack restore.
|
||||||
CannotRemove = true;
|
CannotRemove = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (CallInst *BCI = dyn_cast<CallInst>(BI)) {
|
if (CannotRemove)
|
||||||
if (auto *II2 = dyn_cast<IntrinsicInst>(BCI)) {
|
break;
|
||||||
// If there is a stackrestore below this one, remove this one.
|
|
||||||
if (II2->getIntrinsicID() == Intrinsic::stackrestore)
|
|
||||||
return eraseInstFromFunction(CI);
|
|
||||||
|
|
||||||
// Bail if we cross over an intrinsic with side effects, such as
|
|
||||||
// llvm.stacksave, or llvm.read_register.
|
|
||||||
if (II2->mayHaveSideEffects()) {
|
|
||||||
CannotRemove = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If we found a non-intrinsic call, we can't remove the stack
|
|
||||||
// restore.
|
|
||||||
CannotRemove = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the stack restore is in a return, resume, or unwind block and if there
|
// If the stack restore is in a return, resume, or unwind block and if there
|
||||||
|
|
Loading…
Reference in New Issue