@@ -85,68 +85,29 @@ static void getNumGEPIndexUses(const Value *V, unsigned &NumGEPIdxUses) {
8585 getNumGEPIndexUses (SExtI, NumGEPIdxUses);
8686 else if (const auto *ZExtI = dyn_cast<ZExtInst>(U))
8787 getNumGEPIndexUses (ZExtI, NumGEPIdxUses);
88- else if (const auto *TruncI = dyn_cast<TruncInst>(U))
89- getNumGEPIndexUses (TruncI, NumGEPIdxUses); // XXX Effective?
9088 else if (isa<GetElementPtrInst>(U))
9189 NumGEPIdxUses++;
9290 }
9391}
9492
95- // Only one load? one store?
96- // Only constants?
93+ // Return true if Arg is used in a Load; Add/Sub; Store sequence.
9794static bool looksLikeIVUpdate (const Function *F, const Value *Arg) {
98- assert (Arg->getType ()->isPointerTy () && " Expecting alloca (ptr)." );
99- // Load *Arg -> Add/Sub Constant -> Store *Arg
100- unsigned IVUpdates = 0 ;
101- unsigned NumLoads = 0 ;
102- unsigned NumStores = 0 ;
103- unsigned NumCalls = 0 ;
104- unsigned NumOthers = 0 ;
105- for (const User *U : Arg->users ()) {
106- if (const auto *LI = dyn_cast<LoadInst>(U)) {
107- if (!LI->getType ()->isIntegerTy ()) {
108- NumOthers++;
109- continue ;
110- }
111- NumLoads++;
112- for (const User *U2 : LI->users ()) {
113- const Instruction *LdUser = cast<Instruction>(U2);
114- if ((LdUser->getOpcode () == Instruction::Add) // &&
115- // (isa<Constant>(LdUser->getOperand(0)) ||
116- // isa<Constant>(LdUser->getOperand(1))))
117- ||
118- (LdUser->getOpcode () == Instruction::Sub) // &&
119- // isa<Constant>(LdUser->getOperand(1)))
120- ) {
121- for (const User *U3 : LdUser->users ())
122- if (const auto *SI = dyn_cast<StoreInst>(U3))
123- if (SI->getPointerOperand () == Arg)
124- IVUpdates++;
95+ assert (Arg->getType ()->isPointerTy () && " Expecting ptr arg." );
96+ for (const User *ArgU : Arg->users ())
97+ if (const auto *LoadI = dyn_cast<LoadInst>(ArgU))
98+ if (LoadI->getType ()->isIntegerTy ())
99+ for (const User *LdU : LoadI->users ()) {
100+ const Instruction *AddSubI = cast<Instruction>(LdU);
101+ if (AddSubI->getOpcode () == Instruction::Add ||
102+ AddSubI->getOpcode () == Instruction::Sub)
103+ for (const User *ASU : AddSubI->users ())
104+ if (const auto *StoreI = dyn_cast<StoreInst>(ASU))
105+ if (StoreI->getPointerOperand () == Arg)
106+ return true ;
125107 }
126- }
127- }
128- else if (isa<StoreInst>(U))
129- NumStores++;
130- else if (isa<CallBase>(U))
131- NumCalls++;
132- else
133- NumOthers++;
134- }
135- dbgs () << " IVUpdates: " << IVUpdates
136- << " NumLoads: " << NumLoads
137- << " NumStores: " << NumStores
138- << " NumCalls: " << NumCalls
139- << " NumOthers: " << NumOthers;
140-
141- return IVUpdates > 0 ; // && NumStores == IVUpdates;
108+ return false ;
142109}
143110
144- #include " llvm/IR/Dominators.h"
145- #include " llvm/Analysis/LoopInfo.h"
146- static cl::opt<bool > ONLYINLOOPS (" onlyinloops" , cl::init(false ));
147- static cl::opt<unsigned > NUMGEPIDX (" numgepidx" , cl::init(0 ));
148- static cl::opt<bool > ONLYIVUPDATES (" onlyivupdates" , cl::init(true ));
149-
150111unsigned SystemZTTIImpl::adjustInliningThreshold (const CallBase *CB) const {
151112 unsigned Bonus = 0 ;
152113 const Function *Caller = CB->getParent ()->getParent ();
@@ -155,46 +116,6 @@ unsigned SystemZTTIImpl::adjustInliningThreshold(const CallBase *CB) const {
155116 return 0 ;
156117 const Module *M = Caller->getParent ();
157118
158- // if (strcmp(Caller->getName().data(), "_Z6searchP7state_tiiiii") == 0 &&
159- // strcmp(Callee->getName().data(), "_ZL15remove_one_fastPiS_S_i") == 0) {
160- // if (!ONLYINLOOPS)
161- // return 1000;
162- // else {
163- // DominatorTree DT(*(const_cast<Function *>(Caller)));
164- // LoopInfo LI(DT);
165- // const BasicBlock *CallBB = CB->getParent();
166- // if (LI.getLoopFor(CallBB) != nullptr)
167- // return 1000;
168- // }
169- // }
170-
171- // Give bonus for an integer alloca which is used as a GEP index in
172- // caller....XXX
173- for (unsigned OpIdx = 0 ; OpIdx != Callee->arg_size (); ++OpIdx) {
174- Value *CallerArg = CB->getArgOperand (OpIdx);
175- Argument *CalleeArg = Callee->getArg (OpIdx);
176- if (const AllocaInst *AI = dyn_cast<AllocaInst>(CallerArg))
177- if (AI->getAllocatedType ()->isIntegerTy () && !AI->isArrayAllocation ()) {
178- unsigned NumGEPIdxUses = 0 ;
179- getNumGEPIndexUses (CallerArg, NumGEPIdxUses);
180- dbgs () << " ALLOCA-ARG: "
181- << Caller->getName ().data () << " / "
182- << Callee->getName ().data () << " : "
183- << *AI->getAllocatedType ()
184- << " NumGEPIdxUses: " << NumGEPIdxUses
185- << " IV: " ;
186- bool IsIVUpdate = looksLikeIVUpdate (Callee, CalleeArg);
187- DominatorTree DT (*(const_cast <Function *>(Caller)));
188- LoopInfo LI (DT);
189- bool InLoop = (LI.getLoopFor (CB->getParent ()) != nullptr );
190- dbgs () << " InLoop: " << InLoop << " \n " ;
191- if ((NumGEPIdxUses > NUMGEPIDX) &&
192- (IsIVUpdate || !ONLYIVUPDATES) &&
193- (InLoop || !ONLYINLOOPS))
194- return 1000 ;
195- }
196- }
197-
198119 // Increase the threshold if an incoming argument is used only as a memcpy
199120 // source.
200121 for (const Argument &Arg : Callee->args ()) {
@@ -244,6 +165,22 @@ unsigned SystemZTTIImpl::adjustInliningThreshold(const CallBase *CB) const {
244165 Bonus += NumStores * 50 ;
245166 Bonus = std::min (Bonus, unsigned (1000 ));
246167
168+ // Give bonus for an integer alloca which is used as a GEP index in caller
169+ // and is updated like an IV in memory in callee. This will help LSR.
170+ for (unsigned OpIdx = 0 ; OpIdx != Callee->arg_size (); ++OpIdx) {
171+ Value *CallerArg = CB->getArgOperand (OpIdx);
172+ Argument *CalleeArg = Callee->getArg (OpIdx);
173+ if (const AllocaInst *AI = dyn_cast<AllocaInst>(CallerArg))
174+ if (AI->getAllocatedType ()->isIntegerTy () && !AI->isArrayAllocation ()) {
175+ unsigned NumGEPIdxUses = 0 ;
176+ getNumGEPIndexUses (AI, NumGEPIdxUses);
177+ if (NumGEPIdxUses && looksLikeIVUpdate (Callee, CalleeArg)) {
178+ Bonus = 1000 ;
179+ break ;
180+ }
181+ }
182+ }
183+
247184 LLVM_DEBUG (if (Bonus)
248185 dbgs () << " ++ SZTTI Adding inlining bonus: " << Bonus << " \n " ;);
249186 return Bonus;
0 commit comments