[llvm] [Analysis]: Allow inlining recursive call IF recursion depth is 1. (PR #119677)
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 23 15:06:41 PST 2025
================
@@ -1666,6 +1668,71 @@ bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &I) {
return isGEPFree(I);
}
+/// Simplify \p Cmp if RHS is const and we can ValueTrack LHS,
+// This handles the case when the Cmp instruction is guarded a recursive call
+// that will cause the Cmp to fail/succeed for the next iteration.
+bool CallAnalyzer::simplifyCmpInst(Function *F, CmpInst &Cmp) {
+ // Bail out if the RHS is NOT const:
+ if (!isa<Constant>(Cmp.getOperand(1)))
+ return false;
+ auto *CmpOp = Cmp.getOperand(0);
+ // Iterate over the users of the function to check if it's a recursive
+ // function:
+ for (auto *U : F->users()) {
+ CallInst *Call = dyn_cast<CallInst>(U);
+ if (!Call || Call->getFunction() != F)
+ continue;
+ auto *CallBB = Call->getParent();
+ auto *Predecessor = CallBB->getSinglePredecessor();
+ // Only handle the case when the callsite has a single predecessor:
+ if (!Predecessor)
+ continue;
+
+ auto *Br = dyn_cast<BranchInst>(Predecessor->getTerminator());
+ if (!Br || Br->isUnconditional())
+ continue;
+ // Check if the Br condition is the same Cmp instr we are investigating:
+ auto *CmpInstr = dyn_cast<CmpInst>(Br->getCondition());
+ if (!CmpInstr || CmpInstr != &Cmp)
+ continue;
+ // Check if there are any arg of the recursive callsite is affecting the cmp
+ // instr:
+ bool ArgFound = false;
+ Value *FuncArg = nullptr, *CallArg = nullptr;
+ for (unsigned ArgNum = 0;
+ ArgNum < F->arg_size() && ArgNum < Call->arg_size(); ArgNum++) {
+ FuncArg = F->getArg(ArgNum);
+ CallArg = Call->getArgOperand(ArgNum);
+ if ((FuncArg == CmpOp) && (CallArg != CmpOp)) {
+ ArgFound = true;
+ break;
+ }
+ }
+ if (!ArgFound)
+ continue;
+ // Now we have a recursive call that is guarded by a cmp instruction.
+ // Check if this cmp can be simplified:
+ SimplifyQuery SQ(DL, dyn_cast<Instruction>(CallArg));
+ DomConditionCache DC;
+ DC.registerBranch(Br);
+ SQ.DC = &DC;
+ DominatorTree DT(*F);
----------------
aeubanks wrote:
creating a domtree for potentially every cmp inst is not going to work compile time wise, we need some way of reusing a domtree for an entire inline cost invocation
https://github.com/llvm/llvm-project/pull/119677
More information about the llvm-commits
mailing list