Repository navigation
Conversation
Checking for constant call arguments before calling canConstantFoldCallTo reduces opt's user instruction count by about 0.15% on a call-heavy InstCombine microbenchmark, with no change in output. tryConstantFoldCall asked canConstantFoldCallTo whether the callee is foldable before checking whether all arguments are constant. The former queries call-site and callee attributes (nobuiltin, strictfp) and may consult TargetLibraryInfo, while the latter is a cheap scan that fails for most calls. Swap the order so the common case exits early. LLM-aided
|
@llvm/pr-subscribers-llvm-analysis Author: Reid Kleckner (rnk) Changes
It turns out that querying attributes and TLI is more expensive than scanning for Constant arguments, so do that first. This patch swaps the order so the common case exits early. Compile-time tracker: https://llvm-compile-time-tracker.com/compare.php?from=6e58f6f5536016c55365ac55be11e6ac783d64cf&to=ebc6a8a748f0d3338efc8c2633f057418ebca43a&stat=instructions:u This is worth ~0.15% on my workload, but only ~0.04% on the CTT Clang build. Again, I think this might show that my workload is intrinsic-call heavy, but I haven't confirmed that yet. LLM-aided Full diff: https://github.com/llvm/llvm-project/pull/240676.diff 1 Files Affected:
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index c85cfac11110c..cfadaa15cb80b 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -7751,9 +7751,11 @@ static Value *simplifyIntrinsic(CallBase *Call, ArrayRef<Value *> Args,
static Value *tryConstantFoldCall(CallBase *Call, ArrayRef<Value *> Args,
const SimplifyQuery &Q) {
auto *F = Call->getCalledFunction();
- if (!F || !canConstantFoldCallTo(Call, F, Q.TLI))
+ if (!F)
return nullptr;
+ // Check for constant arguments before querying canConstantFoldCallTo.
+ // Checking arguments is cheaper than TLI classification and attribute checks.
SmallVector<Constant *, 4> ConstantArgs;
ConstantArgs.reserve(Args.size());
for (Value *Arg : Args) {
@@ -7766,6 +7768,10 @@ static Value *tryConstantFoldCall(CallBase *Call, ArrayRef<Value *> Args,
ConstantArgs.push_back(C);
}
+ // Check if this is a known library function that we know how to fold.
+ if (!canConstantFoldCallTo(Call, F, Q.TLI))
+ return nullptr;
+
return ConstantFoldCall(Call, F, ConstantArgs, Q.TLI);
}
|
|
Thanks! |
|
Hm, still getting these errors: Should I revisit that workflow PR I sent a while back? |
|
Merged main to re-run premerge checks and auto-merging, we'll see if it fixes itself |
|
nikic
left a comment
There was a problem hiding this comment.
Generally looks fine, but you might want to try reordering checks inside canCosntantFoldCallTo instead?
I'm thinking check the intrinsic case first (as it doesn't need any other the other checks). Then check TLI, which is cached. And then check the attributes.
I looked, and Also, I misspoke, it turns out the workload I was profiling did not have many intrinsic calls, it had many standard direct call sites to opaque functions. I think the original source for this workload is calling shader-library supplied runtime libraries, but as far as LLVM is concerned, they are standard functions. |
tryConstantFoldCallruns two checks before continuing to fold:canConstantFoldCallTo, which checks if the call is marked nobuiltin and that it is a known library call (cached)It turns out that querying attributes and TLI is more expensive than scanning for Constant arguments, so do that first. This patch swaps the order so the common case exits early.
Compile-time tracker: https://llvm-compile-time-tracker.com/compare.php?from=6e58f6f5536016c55365ac55be11e6ac783d64cf&to=ebc6a8a748f0d3338efc8c2633f057418ebca43a&stat=instructions:u
This is worth ~0.15% on my workload, but only ~0.04% on the CTT Clang build. Again, I think this might show that my workload is intrinsic-call heavy, but I haven't confirmed that yet.
LLM-aided