[llvm] [Coroutines] Drop dead instructions more aggressively in addMustTailToCoroResumes() (PR #85271)
Chuanqi Xu via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 18 06:18:53 PDT 2024
================
@@ -1246,54 +1231,48 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) {
BasicBlock *Succ = BR->getSuccessor(SuccIndex);
scanPHIsAndUpdateValueMap(I, Succ, ResolvedValues);
- I = GetFirstValidInstruction(Succ->getFirstNonPHIOrDbgOrLifetime());
-
+ I = Succ->getFirstNonPHIOrDbgOrLifetime();
continue;
}
- if (auto *CondCmp = dyn_cast<CmpInst>(I)) {
+ if (auto *Cmp = dyn_cast<CmpInst>(I)) {
// If the case number of suspended switch instruction is reduced to
// 1, then it is simplified to CmpInst in llvm::ConstantFoldTerminator.
- auto *BR = dyn_cast<BranchInst>(
- GetFirstValidInstruction(CondCmp->getNextNode()));
- if (!BR || !BR->isConditional() || CondCmp != BR->getCondition())
- return false;
-
- // And the comparsion looks like : %cond = icmp eq i8 %V, constant.
- // So we try to resolve constant for the first operand only since the
- // second operand should be literal constant by design.
- ConstantInt *Cond0 = TryResolveConstant(CondCmp->getOperand(0));
- auto *Cond1 = dyn_cast<ConstantInt>(CondCmp->getOperand(1));
- if (!Cond0 || !Cond1)
- return false;
-
- // Both operands of the CmpInst are Constant. So that we could evaluate
- // it immediately to get the destination.
- auto *ConstResult =
- dyn_cast_or_null<ConstantInt>(ConstantFoldCompareInstOperands(
- CondCmp->getPredicate(), Cond0, Cond1, DL));
- if (!ConstResult)
- return false;
-
- ResolvedValues[BR->getCondition()] = ConstResult;
-
- // Handle this branch in next iteration.
- I = BR;
- continue;
+ // Try to constant fold it.
+ ConstantInt *Cond0 = TryResolveConstant(Cmp->getOperand(0));
+ ConstantInt *Cond1 = TryResolveConstant(Cmp->getOperand(1));
+ if (Cond0 && Cond1) {
+ ConstantInt *Result =
+ dyn_cast_or_null<ConstantInt>(ConstantFoldCompareInstOperands(
+ Cmp->getPredicate(), Cond0, Cond1, DL));
+ if (Result) {
+ ResolvedValues[Cmp] = Result;
+ I = I->getNextNode();
+ continue;
+ }
+ }
}
if (auto *SI = dyn_cast<SwitchInst>(I)) {
ConstantInt *Cond = TryResolveConstant(SI->getCondition());
if (!Cond)
return false;
- BasicBlock *BB = SI->findCaseValue(Cond)->getCaseSuccessor();
- scanPHIsAndUpdateValueMap(I, BB, ResolvedValues);
- I = GetFirstValidInstruction(BB->getFirstNonPHIOrDbgOrLifetime());
+ BasicBlock *Succ = SI->findCaseValue(Cond)->getCaseSuccessor();
+ scanPHIsAndUpdateValueMap(I, Succ, ResolvedValues);
+ I = Succ->getFirstNonPHIOrDbgOrLifetime();
+ continue;
+ }
+
+ if (I->isDebugOrPseudoInst() || I->isLifetimeStartOrEnd() ||
+ !I->mayHaveSideEffects()) {
+ // We can skip instructions without side effects. If their values are
+ // needed, we'll notice later, e.g. when hitting a conditional branch.
+ I = I->getNextNode();
continue;
}
- return false;
+ break;
----------------
ChuanqiXu9 wrote:
IIUC, we shouldn't do this. This is the pattern we generally do for optimizations. But here, it is not an pure optimizations. We are implementing a C++ semantics. (See my above comments for some backgrounds.) So it is better to break early if we have something we are not able to handle.
https://github.com/llvm/llvm-project/pull/85271
More information about the llvm-commits
mailing list