[PATCH] An Assumption-Tracking Pass
Philip Reames
listmail at philipreames.com
Fri Aug 1 15:46:03 PDT 2014
Er, it looks like this patch is missing some of the changes? I don't see AT being piped through all the passes you're trying to use it in?
Overall approach seems reasonable.
================
Comment at: include/llvm/Analysis/AssumptionTracker.h:11
@@ +10,3 @@
+// This file contains a pass that keeps track of @llvm.assume intrinsics in
+// the functions of a module.
+//
----------------
Comment could be improved. Specifically, why are they tracked? What is the actually mapping?
Suggestions: pass that keeps track of @llvm.assume intrinsics found in each function of the module. As a result, scanning for assumes is quite cheap and can be used freely by the optimizers.
================
Comment at: include/llvm/Analysis/AssumptionTracker.h:30
@@ +29,3 @@
+class AssumptionTracker : public ImmutablePass {
+ /// A callback value handle applied to function objects, which we use to
+ /// delete our cache of intrinsics for a function when it is deleted.
----------------
Order wise, I'd reverse this. Interface at the top, details at the bottom. What are most users going to want to find?
================
Comment at: include/llvm/Analysis/AssumptionTracker.h:90
@@ +89,3 @@
+ /// Remove the cache of @llvm.assume intrinsics for the given function.
+ void clearAssumptions(Function *F);
+
----------------
Naming wise, this is used to force a recalculation, not to remove intrinsics. Maybe a name like "forgetCachedAssumptions" might make that clearer?
================
Comment at: include/llvm/Analysis/AssumptionTracker.h:101
@@ +100,3 @@
+
+ inline assumption_range assumptions(Function *F) {
+ FunctionCallsMap::iterator I = CachedAssumeCalls.find(F);
----------------
Might be worth adding a couple of filter ranges here. e.g. dominating_assumptions(F, I), or entry_assumptions(F).
Putting them here would simplify implementation changes later if we wanted to tune for these.
================
Comment at: lib/Analysis/AssumptionTracker.cpp:56
@@ +55,3 @@
+ // to our cache.
+ for (BasicBlock &B : *F)
+ for (Instruction &II : B)
----------------
I might use a inst_iterator here. Also, I'm not a huge fan of the match notation for such trivial matches, but that's purely stylistic.
================
Comment at: lib/Analysis/AssumptionTracker.cpp:70
@@ +69,3 @@
+ Function *F = CI->getParent()->getParent();
+ assert(F && "Cannot register @llvm.assume call not in a function");
+
----------------
Adding a check that instruction belongs to a BB might be useful.
================
Comment at: lib/Analysis/AssumptionTracker.cpp:74
@@ +73,3 @@
+ if (I == CachedAssumeCalls.end()) {
+ I = scanFunction(F);
+ assert(I->second.count(CI) && "Function scan did not find the call");
----------------
The choice to scan here is non-obvious. Doing so avoids a rescan latter, but is that valuable?
================
Comment at: lib/Transforms/InstCombine/InstCombineCalls.cpp:1003
@@ -1001,3 +1002,3 @@
if (match(IIOperand, m_And(m_Value(A), m_Value(B)))) {
- Builder->CreateCall(AssumeIntrinsic, A, II->getName());
- Builder->CreateCall(AssumeIntrinsic, B, II->getName());
+ AT->registerAssumption(
+ Builder->CreateCall(AssumeIntrinsic, A, II->getName()));
----------------
This part seems bug prone. Don't we already have hook into the builder which catches all adds to the worklist? What about using that mechanism to do assumption recognition?
================
Comment at: lib/Transforms/Scalar/LoopUnswitch.cpp:828
@@ +827,3 @@
+ // whole function's cache.
+ AT->clearAssumptions(F);
+
----------------
I may be missing the obvious here, but where did this AT come from? I don't see it being piped through the class.
http://reviews.llvm.org/D4689
More information about the llvm-commits
mailing list