blob: 57f27731e1c8917e8937e9937902e73ab2277075 [file] [log] [blame]
Sebastian Pop41774802016-07-15 13:45:20 +00001//===- GVNHoist.cpp - Hoist scalar and load expressions -------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This pass hoists expressions from branches to a common dominator. It uses
11// GVN (global value numbering) to discover expressions computing the same
12// values. The primary goal is to reduce the code size, and in some
13// cases reduce critical path (by exposing more ILP).
14// Hoisting may affect the performance in some cases. To mitigate that, hoisting
15// is disabled in the following cases.
16// 1. Scalars across calls.
17// 2. geps when corresponding load/store cannot be hoisted.
18//===----------------------------------------------------------------------===//
19
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/SmallPtrSet.h"
22#include "llvm/ADT/Statistic.h"
23#include "llvm/Analysis/ValueTracking.h"
24#include "llvm/Transforms/Scalar.h"
25#include "llvm/Transforms/Scalar/GVN.h"
26#include "llvm/Transforms/Utils/MemorySSA.h"
27
28using namespace llvm;
29
30#define DEBUG_TYPE "gvn-hoist"
31
32STATISTIC(NumHoisted, "Number of instructions hoisted");
33STATISTIC(NumRemoved, "Number of instructions removed");
34STATISTIC(NumLoadsHoisted, "Number of loads hoisted");
35STATISTIC(NumLoadsRemoved, "Number of loads removed");
36STATISTIC(NumStoresHoisted, "Number of stores hoisted");
37STATISTIC(NumStoresRemoved, "Number of stores removed");
38STATISTIC(NumCallsHoisted, "Number of calls hoisted");
39STATISTIC(NumCallsRemoved, "Number of calls removed");
40
41static cl::opt<int>
42 MaxHoistedThreshold("gvn-max-hoisted", cl::Hidden, cl::init(-1),
43 cl::desc("Max number of instructions to hoist "
44 "(default unlimited = -1)"));
45static cl::opt<int> MaxNumberOfBBSInPath(
46 "gvn-hoist-max-bbs", cl::Hidden, cl::init(4),
47 cl::desc("Max number of basic blocks on the path between "
48 "hoisting locations (default = 4, unlimited = -1)"));
49
Sebastian Pop41774802016-07-15 13:45:20 +000050namespace {
51
52// Provides a sorting function based on the execution order of two instructions.
53struct SortByDFSIn {
54private:
55 DenseMap<const BasicBlock *, unsigned> &DFSNumber;
56
57public:
58 SortByDFSIn(DenseMap<const BasicBlock *, unsigned> &D) : DFSNumber(D) {}
59
60 // Returns true when A executes before B.
61 bool operator()(const Instruction *A, const Instruction *B) const {
62 // FIXME: libc++ has a std::sort() algorithm that will call the compare
63 // function on the same element. Once PR20837 is fixed and some more years
64 // pass by and all the buildbots have moved to a corrected std::sort(),
65 // enable the following assert:
66 //
67 // assert(A != B);
68
69 const BasicBlock *BA = A->getParent();
70 const BasicBlock *BB = B->getParent();
71 unsigned NA = DFSNumber[BA];
72 unsigned NB = DFSNumber[BB];
73 if (NA < NB)
74 return true;
75 if (NA == NB) {
76 // Sort them in the order they occur in the same basic block.
77 BasicBlock::const_iterator AI(A), BI(B);
78 return std::distance(AI, BI) < 0;
79 }
80 return false;
81 }
82};
83
84// A map from a VN (value number) to all the instructions with that VN.
85typedef DenseMap<unsigned, SmallVector<Instruction *, 4>> VNtoInsns;
86
87// Records all scalar instructions candidate for code hoisting.
88class InsnInfo {
89 VNtoInsns VNtoScalars;
90
91public:
92 // Inserts I and its value number in VNtoScalars.
93 void insert(Instruction *I, GVN::ValueTable &VN) {
94 // Scalar instruction.
95 unsigned V = VN.lookupOrAdd(I);
96 VNtoScalars[V].push_back(I);
97 }
98
99 const VNtoInsns &getVNTable() const { return VNtoScalars; }
100};
101
102// Records all load instructions candidate for code hoisting.
103class LoadInfo {
104 VNtoInsns VNtoLoads;
105
106public:
107 // Insert Load and the value number of its memory address in VNtoLoads.
108 void insert(LoadInst *Load, GVN::ValueTable &VN) {
109 if (Load->isSimple()) {
110 unsigned V = VN.lookupOrAdd(Load->getPointerOperand());
111 VNtoLoads[V].push_back(Load);
112 }
113 }
114
115 const VNtoInsns &getVNTable() const { return VNtoLoads; }
116};
117
118// Records all store instructions candidate for code hoisting.
119class StoreInfo {
120 VNtoInsns VNtoStores;
121
122public:
123 // Insert the Store and a hash number of the store address and the stored
124 // value in VNtoStores.
125 void insert(StoreInst *Store, GVN::ValueTable &VN) {
126 if (!Store->isSimple())
127 return;
128 // Hash the store address and the stored value.
129 Value *Ptr = Store->getPointerOperand();
130 Value *Val = Store->getValueOperand();
131 VNtoStores[hash_combine(VN.lookupOrAdd(Ptr), VN.lookupOrAdd(Val))]
132 .push_back(Store);
133 }
134
135 const VNtoInsns &getVNTable() const { return VNtoStores; }
136};
137
138// Records all call instructions candidate for code hoisting.
139class CallInfo {
140 VNtoInsns VNtoCallsScalars;
141 VNtoInsns VNtoCallsLoads;
142 VNtoInsns VNtoCallsStores;
143
144public:
145 // Insert Call and its value numbering in one of the VNtoCalls* containers.
146 void insert(CallInst *Call, GVN::ValueTable &VN) {
147 // A call that doesNotAccessMemory is handled as a Scalar,
148 // onlyReadsMemory will be handled as a Load instruction,
149 // all other calls will be handled as stores.
150 unsigned V = VN.lookupOrAdd(Call);
151
152 if (Call->doesNotAccessMemory())
153 VNtoCallsScalars[V].push_back(Call);
154 else if (Call->onlyReadsMemory())
155 VNtoCallsLoads[V].push_back(Call);
156 else
157 VNtoCallsStores[V].push_back(Call);
158 }
159
160 const VNtoInsns &getScalarVNTable() const { return VNtoCallsScalars; }
161
162 const VNtoInsns &getLoadVNTable() const { return VNtoCallsLoads; }
163
164 const VNtoInsns &getStoreVNTable() const { return VNtoCallsStores; }
165};
166
167typedef DenseMap<const BasicBlock *, bool> BBSideEffectsSet;
168typedef SmallVector<Instruction *, 4> SmallVecInsn;
169typedef SmallVectorImpl<Instruction *> SmallVecImplInsn;
170
171// This pass hoists common computations across branches sharing common
172// dominator. The primary goal is to reduce the code size, and in some
173// cases reduce critical path (by exposing more ILP).
174class GVNHoist {
175public:
176 GVN::ValueTable VN;
177 DominatorTree *DT;
178 AliasAnalysis *AA;
179 MemoryDependenceResults *MD;
180 const bool OptForMinSize;
181 DenseMap<const BasicBlock *, unsigned> DFSNumber;
182 BBSideEffectsSet BBSideEffects;
183 MemorySSA *MSSA;
David Majnemeraa241782016-07-18 00:35:01 +0000184 int HoistedCtr;
185
Sebastian Pop41774802016-07-15 13:45:20 +0000186 enum InsKind { Unknown, Scalar, Load, Store };
187
188 GVNHoist(DominatorTree *Dt, AliasAnalysis *Aa, MemoryDependenceResults *Md,
189 bool OptForMinSize)
David Majnemeraa241782016-07-18 00:35:01 +0000190 : DT(Dt), AA(Aa), MD(Md), OptForMinSize(OptForMinSize), HoistedCtr(0) {}
Sebastian Pop41774802016-07-15 13:45:20 +0000191
192 // Return true when there are exception handling in BB.
193 bool hasEH(const BasicBlock *BB) {
194 auto It = BBSideEffects.find(BB);
195 if (It != BBSideEffects.end())
196 return It->second;
197
198 if (BB->isEHPad() || BB->hasAddressTaken()) {
199 BBSideEffects[BB] = true;
200 return true;
201 }
202
203 if (BB->getTerminator()->mayThrow()) {
204 BBSideEffects[BB] = true;
205 return true;
206 }
207
208 BBSideEffects[BB] = false;
209 return false;
210 }
211
212 // Return true when all paths from A to the end of the function pass through
213 // either B or C.
214 bool hoistingFromAllPaths(const BasicBlock *A, const BasicBlock *B,
215 const BasicBlock *C) {
216 // We fully copy the WL in order to be able to remove items from it.
217 SmallPtrSet<const BasicBlock *, 2> WL;
218 WL.insert(B);
219 WL.insert(C);
220
221 for (auto It = df_begin(A), E = df_end(A); It != E;) {
222 // There exists a path from A to the exit of the function if we are still
223 // iterating in DF traversal and we removed all instructions from the work
224 // list.
225 if (WL.empty())
226 return false;
227
228 const BasicBlock *BB = *It;
229 if (WL.erase(BB)) {
230 // Stop DFS traversal when BB is in the work list.
231 It.skipChildren();
232 continue;
233 }
234
235 // Check for end of function, calls that do not return, etc.
236 if (!isGuaranteedToTransferExecutionToSuccessor(BB->getTerminator()))
237 return false;
238
239 // Increment DFS traversal when not skipping children.
240 ++It;
241 }
242
243 return true;
244 }
245
246 /* Return true when I1 appears before I2 in the instructions of BB. */
247 bool firstInBB(BasicBlock *BB, const Instruction *I1, const Instruction *I2) {
248 for (Instruction &I : *BB) {
249 if (&I == I1)
250 return true;
251 if (&I == I2)
252 return false;
253 }
254
255 llvm_unreachable("I1 and I2 not found in BB");
256 }
257 // Return true when there are users of Def in BB.
258 bool hasMemoryUseOnPath(MemoryAccess *Def, const BasicBlock *BB,
259 const Instruction *OldPt) {
Sebastian Pop41774802016-07-15 13:45:20 +0000260 const BasicBlock *DefBB = Def->getBlock();
261 const BasicBlock *OldBB = OldPt->getParent();
262
David Majnemer4c66a712016-07-18 00:34:58 +0000263 for (User *U : Def->users())
264 if (auto *MU = dyn_cast<MemoryUse>(U)) {
265 BasicBlock *UBB = MU->getBlock();
Sebastian Pop41774802016-07-15 13:45:20 +0000266 // Only analyze uses in BB.
267 if (BB != UBB)
268 continue;
269
270 // A use in the same block as the Def is on the path.
271 if (UBB == DefBB) {
David Majnemer4c66a712016-07-18 00:34:58 +0000272 assert(MSSA->locallyDominates(Def, MU) && "def not dominating use");
Sebastian Pop41774802016-07-15 13:45:20 +0000273 return true;
274 }
275
276 if (UBB != OldBB)
277 return true;
278
279 // It is only harmful to hoist when the use is before OldPt.
David Majnemer4c66a712016-07-18 00:34:58 +0000280 if (firstInBB(UBB, MU->getMemoryInst(), OldPt))
Sebastian Pop41774802016-07-15 13:45:20 +0000281 return true;
282 }
283
284 return false;
285 }
286
287 // Return true when there are exception handling or loads of memory Def
288 // between OldPt and NewPt.
289
290 // Decrement by 1 NBBsOnAllPaths for each block between HoistPt and BB, and
291 // return true when the counter NBBsOnAllPaths reaces 0, except when it is
292 // initialized to -1 which is unlimited.
293 bool hasEHOrLoadsOnPath(const Instruction *NewPt, const Instruction *OldPt,
294 MemoryAccess *Def, int &NBBsOnAllPaths) {
295 const BasicBlock *NewBB = NewPt->getParent();
296 const BasicBlock *OldBB = OldPt->getParent();
297 assert(DT->dominates(NewBB, OldBB) && "invalid path");
298 assert(DT->dominates(Def->getBlock(), NewBB) &&
299 "def does not dominate new hoisting point");
300
301 // Walk all basic blocks reachable in depth-first iteration on the inverse
302 // CFG from OldBB to NewBB. These blocks are all the blocks that may be
303 // executed between the execution of NewBB and OldBB. Hoisting an expression
304 // from OldBB into NewBB has to be safe on all execution paths.
305 for (auto I = idf_begin(OldBB), E = idf_end(OldBB); I != E;) {
306 if (*I == NewBB) {
307 // Stop traversal when reaching HoistPt.
308 I.skipChildren();
309 continue;
310 }
311
312 // Impossible to hoist with exceptions on the path.
313 if (hasEH(*I))
314 return true;
315
316 // Check that we do not move a store past loads.
317 if (hasMemoryUseOnPath(Def, *I, OldPt))
318 return true;
319
320 // Stop walk once the limit is reached.
321 if (NBBsOnAllPaths == 0)
322 return true;
323
324 // -1 is unlimited number of blocks on all paths.
325 if (NBBsOnAllPaths != -1)
326 --NBBsOnAllPaths;
327
328 ++I;
329 }
330
331 return false;
332 }
333
334 // Return true when there are exception handling between HoistPt and BB.
335 // Decrement by 1 NBBsOnAllPaths for each block between HoistPt and BB, and
336 // return true when the counter NBBsOnAllPaths reaches 0, except when it is
337 // initialized to -1 which is unlimited.
338 bool hasEHOnPath(const BasicBlock *HoistPt, const BasicBlock *BB,
339 int &NBBsOnAllPaths) {
340 assert(DT->dominates(HoistPt, BB) && "Invalid path");
341
342 // Walk all basic blocks reachable in depth-first iteration on
343 // the inverse CFG from BBInsn to NewHoistPt. These blocks are all the
344 // blocks that may be executed between the execution of NewHoistPt and
345 // BBInsn. Hoisting an expression from BBInsn into NewHoistPt has to be safe
346 // on all execution paths.
347 for (auto I = idf_begin(BB), E = idf_end(BB); I != E;) {
348 if (*I == HoistPt) {
349 // Stop traversal when reaching NewHoistPt.
350 I.skipChildren();
351 continue;
352 }
353
354 // Impossible to hoist with exceptions on the path.
355 if (hasEH(*I))
356 return true;
357
358 // Stop walk once the limit is reached.
359 if (NBBsOnAllPaths == 0)
360 return true;
361
362 // -1 is unlimited number of blocks on all paths.
363 if (NBBsOnAllPaths != -1)
364 --NBBsOnAllPaths;
365
366 ++I;
367 }
368
369 return false;
370 }
371
372 // Return true when it is safe to hoist a memory load or store U from OldPt
373 // to NewPt.
374 bool safeToHoistLdSt(const Instruction *NewPt, const Instruction *OldPt,
375 MemoryUseOrDef *U, InsKind K, int &NBBsOnAllPaths) {
376
377 // In place hoisting is safe.
378 if (NewPt == OldPt)
379 return true;
380
381 const BasicBlock *NewBB = NewPt->getParent();
382 const BasicBlock *OldBB = OldPt->getParent();
383 const BasicBlock *UBB = U->getBlock();
384
385 // Check for dependences on the Memory SSA.
386 MemoryAccess *D = U->getDefiningAccess();
387 BasicBlock *DBB = D->getBlock();
388 if (DT->properlyDominates(NewBB, DBB))
389 // Cannot move the load or store to NewBB above its definition in DBB.
390 return false;
391
392 if (NewBB == DBB && !MSSA->isLiveOnEntryDef(D))
David Majnemer4c66a712016-07-18 00:34:58 +0000393 if (auto *UD = dyn_cast<MemoryUseOrDef>(D))
Sebastian Pop41774802016-07-15 13:45:20 +0000394 if (firstInBB(DBB, NewPt, UD->getMemoryInst()))
395 // Cannot move the load or store to NewPt above its definition in D.
396 return false;
397
398 // Check for unsafe hoistings due to side effects.
399 if (K == InsKind::Store) {
400 if (hasEHOrLoadsOnPath(NewPt, OldPt, D, NBBsOnAllPaths))
401 return false;
402 } else if (hasEHOnPath(NewBB, OldBB, NBBsOnAllPaths))
403 return false;
404
405 if (UBB == NewBB) {
406 if (DT->properlyDominates(DBB, NewBB))
407 return true;
408 assert(UBB == DBB);
409 assert(MSSA->locallyDominates(D, U));
410 }
411
412 // No side effects: it is safe to hoist.
413 return true;
414 }
415
416 // Return true when it is safe to hoist scalar instructions from BB1 and BB2
417 // to HoistBB.
418 bool safeToHoistScalar(const BasicBlock *HoistBB, const BasicBlock *BB1,
419 const BasicBlock *BB2, int &NBBsOnAllPaths) {
420 // Check that the hoisted expression is needed on all paths. When HoistBB
421 // already contains an instruction to be hoisted, the expression is needed
422 // on all paths. Enable scalar hoisting at -Oz as it is safe to hoist
423 // scalars to a place where they are partially needed.
424 if (!OptForMinSize && BB1 != HoistBB &&
425 !hoistingFromAllPaths(HoistBB, BB1, BB2))
426 return false;
427
428 if (hasEHOnPath(HoistBB, BB1, NBBsOnAllPaths) ||
429 hasEHOnPath(HoistBB, BB2, NBBsOnAllPaths))
430 return false;
431
432 // Safe to hoist scalars from BB1 and BB2 to HoistBB.
433 return true;
434 }
435
436 // Each element of a hoisting list contains the basic block where to hoist and
437 // a list of instructions to be hoisted.
438 typedef std::pair<BasicBlock *, SmallVecInsn> HoistingPointInfo;
439 typedef SmallVector<HoistingPointInfo, 4> HoistingPointList;
440
441 // Partition InstructionsToHoist into a set of candidates which can share a
442 // common hoisting point. The partitions are collected in HPL. IsScalar is
443 // true when the instructions in InstructionsToHoist are scalars. IsLoad is
444 // true when the InstructionsToHoist are loads, false when they are stores.
445 void partitionCandidates(SmallVecImplInsn &InstructionsToHoist,
446 HoistingPointList &HPL, InsKind K) {
447 // No need to sort for two instructions.
448 if (InstructionsToHoist.size() > 2) {
449 SortByDFSIn Pred(DFSNumber);
450 std::sort(InstructionsToHoist.begin(), InstructionsToHoist.end(), Pred);
451 }
452
453 int NBBsOnAllPaths = MaxNumberOfBBSInPath;
454
455 SmallVecImplInsn::iterator II = InstructionsToHoist.begin();
456 SmallVecImplInsn::iterator Start = II;
457 Instruction *HoistPt = *II;
458 BasicBlock *HoistBB = HoistPt->getParent();
459 MemoryUseOrDef *UD;
460 if (K != InsKind::Scalar)
461 UD = cast<MemoryUseOrDef>(MSSA->getMemoryAccess(HoistPt));
462
463 for (++II; II != InstructionsToHoist.end(); ++II) {
464 Instruction *Insn = *II;
465 BasicBlock *BB = Insn->getParent();
466 BasicBlock *NewHoistBB;
467 Instruction *NewHoistPt;
468
469 if (BB == HoistBB) {
470 NewHoistBB = HoistBB;
471 NewHoistPt = firstInBB(BB, Insn, HoistPt) ? Insn : HoistPt;
472 } else {
473 NewHoistBB = DT->findNearestCommonDominator(HoistBB, BB);
474 if (NewHoistBB == BB)
475 NewHoistPt = Insn;
476 else if (NewHoistBB == HoistBB)
477 NewHoistPt = HoistPt;
478 else
479 NewHoistPt = NewHoistBB->getTerminator();
480 }
481
482 if (K == InsKind::Scalar) {
483 if (safeToHoistScalar(NewHoistBB, HoistBB, BB, NBBsOnAllPaths)) {
484 // Extend HoistPt to NewHoistPt.
485 HoistPt = NewHoistPt;
486 HoistBB = NewHoistBB;
487 continue;
488 }
489 } else {
490 // When NewBB already contains an instruction to be hoisted, the
491 // expression is needed on all paths.
492 // Check that the hoisted expression is needed on all paths: it is
493 // unsafe to hoist loads to a place where there may be a path not
494 // loading from the same address: for instance there may be a branch on
495 // which the address of the load may not be initialized.
496 if ((HoistBB == NewHoistBB || BB == NewHoistBB ||
497 hoistingFromAllPaths(NewHoistBB, HoistBB, BB)) &&
498 // Also check that it is safe to move the load or store from HoistPt
499 // to NewHoistPt, and from Insn to NewHoistPt.
500 safeToHoistLdSt(NewHoistPt, HoistPt, UD, K, NBBsOnAllPaths) &&
501 safeToHoistLdSt(NewHoistPt, Insn,
502 cast<MemoryUseOrDef>(MSSA->getMemoryAccess(Insn)),
503 K, NBBsOnAllPaths)) {
504 // Extend HoistPt to NewHoistPt.
505 HoistPt = NewHoistPt;
506 HoistBB = NewHoistBB;
507 continue;
508 }
509 }
510
511 // At this point it is not safe to extend the current hoisting to
512 // NewHoistPt: save the hoisting list so far.
513 if (std::distance(Start, II) > 1)
David Majnemer4c66a712016-07-18 00:34:58 +0000514 HPL.push_back({HoistBB, SmallVecInsn(Start, II)});
Sebastian Pop41774802016-07-15 13:45:20 +0000515
516 // Start over from BB.
517 Start = II;
518 if (K != InsKind::Scalar)
519 UD = cast<MemoryUseOrDef>(MSSA->getMemoryAccess(*Start));
520 HoistPt = Insn;
521 HoistBB = BB;
522 NBBsOnAllPaths = MaxNumberOfBBSInPath;
523 }
524
525 // Save the last partition.
526 if (std::distance(Start, II) > 1)
David Majnemer4c66a712016-07-18 00:34:58 +0000527 HPL.push_back({HoistBB, SmallVecInsn(Start, II)});
Sebastian Pop41774802016-07-15 13:45:20 +0000528 }
529
530 // Initialize HPL from Map.
531 void computeInsertionPoints(const VNtoInsns &Map, HoistingPointList &HPL,
532 InsKind K) {
David Majnemer4c66a712016-07-18 00:34:58 +0000533 for (const auto &Entry : Map) {
Sebastian Pop41774802016-07-15 13:45:20 +0000534 if (MaxHoistedThreshold != -1 && ++HoistedCtr > MaxHoistedThreshold)
535 return;
536
David Majnemer4c66a712016-07-18 00:34:58 +0000537 const SmallVecInsn &V = Entry.second;
Sebastian Pop41774802016-07-15 13:45:20 +0000538 if (V.size() < 2)
539 continue;
540
541 // Compute the insertion point and the list of expressions to be hoisted.
542 SmallVecInsn InstructionsToHoist;
543 for (auto I : V)
544 if (!hasEH(I->getParent()))
545 InstructionsToHoist.push_back(I);
546
David Majnemer4c66a712016-07-18 00:34:58 +0000547 if (!InstructionsToHoist.empty())
Sebastian Pop41774802016-07-15 13:45:20 +0000548 partitionCandidates(InstructionsToHoist, HPL, K);
549 }
550 }
551
552 // Return true when all operands of Instr are available at insertion point
553 // HoistPt. When limiting the number of hoisted expressions, one could hoist
554 // a load without hoisting its access function. So before hoisting any
555 // expression, make sure that all its operands are available at insert point.
556 bool allOperandsAvailable(const Instruction *I,
557 const BasicBlock *HoistPt) const {
David Majnemer4c66a712016-07-18 00:34:58 +0000558 for (const Use &Op : I->operands())
559 if (const auto *Inst = dyn_cast<Instruction>(&Op))
560 if (!DT->dominates(Inst->getParent(), HoistPt))
561 return false;
Sebastian Pop41774802016-07-15 13:45:20 +0000562
563 return true;
564 }
565
566 Instruction *firstOfTwo(Instruction *I, Instruction *J) const {
567 for (Instruction &I1 : *I->getParent())
568 if (&I1 == I || &I1 == J)
569 return &I1;
570 llvm_unreachable("Both I and J must be from same BB");
571 }
572
573 // Replace the use of From with To in Insn.
574 void replaceUseWith(Instruction *Insn, Value *From, Value *To) const {
575 for (Value::use_iterator UI = From->use_begin(), UE = From->use_end();
576 UI != UE;) {
577 Use &U = *UI++;
578 if (U.getUser() == Insn) {
579 U.set(To);
580 return;
581 }
582 }
583 llvm_unreachable("should replace exactly once");
584 }
585
586 bool makeOperandsAvailable(Instruction *Repl, BasicBlock *HoistPt) const {
587 // Check whether the GEP of a ld/st can be synthesized at HoistPt.
588 Instruction *Gep = nullptr;
589 Instruction *Val = nullptr;
David Majnemer4c66a712016-07-18 00:34:58 +0000590 if (auto *Ld = dyn_cast<LoadInst>(Repl))
Sebastian Pop41774802016-07-15 13:45:20 +0000591 Gep = dyn_cast<Instruction>(Ld->getPointerOperand());
David Majnemer4c66a712016-07-18 00:34:58 +0000592 if (auto *St = dyn_cast<StoreInst>(Repl)) {
Sebastian Pop41774802016-07-15 13:45:20 +0000593 Gep = dyn_cast<Instruction>(St->getPointerOperand());
594 Val = dyn_cast<Instruction>(St->getValueOperand());
595 }
596
597 if (!Gep || !isa<GetElementPtrInst>(Gep))
598 return false;
599
600 // Check whether we can compute the Gep at HoistPt.
601 if (!allOperandsAvailable(Gep, HoistPt))
602 return false;
603
604 // Also check that the stored value is available.
605 if (Val && !allOperandsAvailable(Val, HoistPt))
606 return false;
607
608 // Copy the gep before moving the ld/st.
609 Instruction *ClonedGep = Gep->clone();
610 ClonedGep->insertBefore(HoistPt->getTerminator());
611 replaceUseWith(Repl, Gep, ClonedGep);
612
613 // Also copy Val.
614 if (Val) {
615 Instruction *ClonedVal = Val->clone();
616 ClonedVal->insertBefore(HoistPt->getTerminator());
617 replaceUseWith(Repl, Val, ClonedVal);
618 }
619
620 return true;
621 }
622
623 std::pair<unsigned, unsigned> hoist(HoistingPointList &HPL) {
624 unsigned NI = 0, NL = 0, NS = 0, NC = 0, NR = 0;
625 for (const HoistingPointInfo &HP : HPL) {
626 // Find out whether we already have one of the instructions in HoistPt,
627 // in which case we do not have to move it.
628 BasicBlock *HoistPt = HP.first;
629 const SmallVecInsn &InstructionsToHoist = HP.second;
630 Instruction *Repl = nullptr;
631 for (Instruction *I : InstructionsToHoist)
632 if (I->getParent() == HoistPt) {
633 // If there are two instructions in HoistPt to be hoisted in place:
634 // update Repl to be the first one, such that we can rename the uses
635 // of the second based on the first.
636 Repl = !Repl ? I : firstOfTwo(Repl, I);
637 }
638
639 if (Repl) {
640 // Repl is already in HoistPt: it remains in place.
641 assert(allOperandsAvailable(Repl, HoistPt) &&
642 "instruction depends on operands that are not available");
643 } else {
644 // When we do not find Repl in HoistPt, select the first in the list
645 // and move it to HoistPt.
646 Repl = InstructionsToHoist.front();
647
648 // We can move Repl in HoistPt only when all operands are available.
649 // The order in which hoistings are done may influence the availability
650 // of operands.
651 if (!allOperandsAvailable(Repl, HoistPt) &&
652 !makeOperandsAvailable(Repl, HoistPt))
653 continue;
654 Repl->moveBefore(HoistPt->getTerminator());
655 }
656
657 if (isa<LoadInst>(Repl))
658 ++NL;
659 else if (isa<StoreInst>(Repl))
660 ++NS;
661 else if (isa<CallInst>(Repl))
662 ++NC;
663 else // Scalar
664 ++NI;
665
666 // Remove and rename all other instructions.
667 for (Instruction *I : InstructionsToHoist)
668 if (I != Repl) {
669 ++NR;
670 if (isa<LoadInst>(Repl))
671 ++NumLoadsRemoved;
672 else if (isa<StoreInst>(Repl))
673 ++NumStoresRemoved;
674 else if (isa<CallInst>(Repl))
675 ++NumCallsRemoved;
676 I->replaceAllUsesWith(Repl);
677 I->eraseFromParent();
678 }
679 }
680
681 NumHoisted += NL + NS + NC + NI;
682 NumRemoved += NR;
683 NumLoadsHoisted += NL;
684 NumStoresHoisted += NS;
685 NumCallsHoisted += NC;
686 return {NI, NL + NC + NS};
687 }
688
689 // Hoist all expressions. Returns Number of scalars hoisted
690 // and number of non-scalars hoisted.
691 std::pair<unsigned, unsigned> hoistExpressions(Function &F) {
692 InsnInfo II;
693 LoadInfo LI;
694 StoreInfo SI;
695 CallInfo CI;
696 for (BasicBlock *BB : depth_first(&F.getEntryBlock())) {
697 for (Instruction &I1 : *BB) {
David Majnemer4c66a712016-07-18 00:34:58 +0000698 if (auto *Load = dyn_cast<LoadInst>(&I1))
Sebastian Pop41774802016-07-15 13:45:20 +0000699 LI.insert(Load, VN);
David Majnemer4c66a712016-07-18 00:34:58 +0000700 else if (auto *Store = dyn_cast<StoreInst>(&I1))
Sebastian Pop41774802016-07-15 13:45:20 +0000701 SI.insert(Store, VN);
David Majnemer4c66a712016-07-18 00:34:58 +0000702 else if (auto *Call = dyn_cast<CallInst>(&I1)) {
703 if (auto *Intr = dyn_cast<IntrinsicInst>(Call)) {
Sebastian Pop41774802016-07-15 13:45:20 +0000704 if (isa<DbgInfoIntrinsic>(Intr) ||
705 Intr->getIntrinsicID() == Intrinsic::assume)
706 continue;
707 }
708 if (Call->mayHaveSideEffects()) {
709 if (!OptForMinSize)
710 break;
711 // We may continue hoisting across calls which write to memory.
712 if (Call->mayThrow())
713 break;
714 }
715 CI.insert(Call, VN);
716 } else if (OptForMinSize || !isa<GetElementPtrInst>(&I1))
717 // Do not hoist scalars past calls that may write to memory because
718 // that could result in spills later. geps are handled separately.
719 // TODO: We can relax this for targets like AArch64 as they have more
720 // registers than X86.
721 II.insert(&I1, VN);
722 }
723 }
724
725 HoistingPointList HPL;
726 computeInsertionPoints(II.getVNTable(), HPL, InsKind::Scalar);
727 computeInsertionPoints(LI.getVNTable(), HPL, InsKind::Load);
728 computeInsertionPoints(SI.getVNTable(), HPL, InsKind::Store);
729 computeInsertionPoints(CI.getScalarVNTable(), HPL, InsKind::Scalar);
730 computeInsertionPoints(CI.getLoadVNTable(), HPL, InsKind::Load);
731 computeInsertionPoints(CI.getStoreVNTable(), HPL, InsKind::Store);
732 return hoist(HPL);
733 }
734
735 bool run(Function &F) {
736 VN.setDomTree(DT);
737 VN.setAliasAnalysis(AA);
738 VN.setMemDep(MD);
739 bool Res = false;
740
741 unsigned I = 0;
742 for (const BasicBlock *BB : depth_first(&F.getEntryBlock()))
David Majnemer4c66a712016-07-18 00:34:58 +0000743 DFSNumber.insert({BB, ++I});
Sebastian Pop41774802016-07-15 13:45:20 +0000744
745 // FIXME: use lazy evaluation of VN to avoid the fix-point computation.
746 while (1) {
747 // FIXME: only compute MemorySSA once. We need to update the analysis in
748 // the same time as transforming the code.
749 MemorySSA M(F, AA, DT);
750 MSSA = &M;
751
752 auto HoistStat = hoistExpressions(F);
753 if (HoistStat.first + HoistStat.second == 0) {
754 return Res;
755 }
756 if (HoistStat.second > 0) {
757 // To address a limitation of the current GVN, we need to rerun the
758 // hoisting after we hoisted loads in order to be able to hoist all
759 // scalars dependent on the hoisted loads. Same for stores.
760 VN.clear();
761 }
762 Res = true;
763 }
764
765 return Res;
766 }
767};
768
769class GVNHoistLegacyPass : public FunctionPass {
770public:
771 static char ID;
772
773 GVNHoistLegacyPass() : FunctionPass(ID) {
774 initializeGVNHoistLegacyPassPass(*PassRegistry::getPassRegistry());
775 }
776
777 bool runOnFunction(Function &F) override {
778 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
779 auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
780 auto &MD = getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
781
782 GVNHoist G(&DT, &AA, &MD, F.optForMinSize());
783 return G.run(F);
784 }
785
786 void getAnalysisUsage(AnalysisUsage &AU) const override {
787 AU.addRequired<DominatorTreeWrapperPass>();
788 AU.addRequired<AAResultsWrapperPass>();
789 AU.addRequired<MemoryDependenceWrapperPass>();
790 AU.addPreserved<DominatorTreeWrapperPass>();
791 }
792};
793} // namespace
794
795PreservedAnalyses GVNHoistPass::run(Function &F,
796 AnalysisManager<Function> &AM) {
797 DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F);
798 AliasAnalysis &AA = AM.getResult<AAManager>(F);
799 MemoryDependenceResults &MD = AM.getResult<MemoryDependenceAnalysis>(F);
800
801 GVNHoist G(&DT, &AA, &MD, F.optForMinSize());
802 if (!G.run(F))
803 return PreservedAnalyses::all();
804
805 PreservedAnalyses PA;
806 PA.preserve<DominatorTreeAnalysis>();
807 return PA;
808}
809
810char GVNHoistLegacyPass::ID = 0;
811INITIALIZE_PASS_BEGIN(GVNHoistLegacyPass, "gvn-hoist",
812 "Early GVN Hoisting of Expressions", false, false)
813INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
814INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
815INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
816INITIALIZE_PASS_END(GVNHoistLegacyPass, "gvn-hoist",
817 "Early GVN Hoisting of Expressions", false, false)
818
819FunctionPass *llvm::createGVNHoistPass() { return new GVNHoistLegacyPass(); }