LLVM 24.0.0git
GVNHoist.cpp
Go to the documentation of this file.
1//===- GVNHoist.cpp - Hoist scalar and load expressions -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass hoists expressions from branches to a common dominator. It uses
10// GVN (global value numbering) to discover expressions computing the same
11// values. The primary goals of code-hoisting are:
12// 1. To reduce the code size.
13// 2. In some cases reduce critical path (by exposing more ILP).
14//
15// The algorithm factors out the reachability of values such that multiple
16// queries to find reachability of values are fast. This is based on finding the
17// ANTIC points in the CFG which do not change during hoisting. The ANTIC points
18// are basically the dominance-frontiers in the inverse graph. So we introduce a
19// data structure (CHI nodes) to keep track of values flowing out of a basic
20// block. We only do this for values with multiple occurrences in the function
21// as they are the potential hoistable candidates. This approach allows us to
22// hoist instructions to a basic block with more than two successors, as well as
23// deal with infinite loops in a trivial way.
24//
25// Limitations: This pass does not hoist fully redundant expressions because
26// they are already handled by GVN-PRE. It is advisable to run gvn-hoist before
27// and after gvn-pre because gvn-pre creates opportunities for more instructions
28// to be hoisted.
29//
30// Hoisting may affect the performance in some cases. To mitigate that, hoisting
31// is disabled in the following cases.
32// 1. Scalars across calls.
33// 2. geps when corresponding load/store cannot be hoisted.
34//===----------------------------------------------------------------------===//
35
37#include "ScalarOptions.h"
38#include "llvm/ADT/DenseMap.h"
39#include "llvm/ADT/DenseSet.h"
40#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/Statistic.h"
52#include "llvm/IR/Argument.h"
53#include "llvm/IR/BasicBlock.h"
54#include "llvm/IR/CFG.h"
55#include "llvm/IR/Constants.h"
56#include "llvm/IR/Dominators.h"
57#include "llvm/IR/Function.h"
58#include "llvm/IR/Instruction.h"
61#include "llvm/IR/LLVMContext.h"
62#include "llvm/IR/PassManager.h"
63#include "llvm/IR/Use.h"
64#include "llvm/IR/User.h"
65#include "llvm/IR/Value.h"
67#include "llvm/Support/Debug.h"
71#include <algorithm>
72#include <cassert>
73#include <memory>
74#include <utility>
75#include <vector>
76
77using namespace llvm;
78
79#define DEBUG_TYPE "gvn-hoist"
80
81STATISTIC(NumHoisted, "Number of instructions hoisted");
82STATISTIC(NumRemoved, "Number of instructions removed");
83STATISTIC(NumLoadsHoisted, "Number of loads hoisted");
84STATISTIC(NumLoadsRemoved, "Number of loads removed");
85STATISTIC(NumStoresHoisted, "Number of stores hoisted");
86STATISTIC(NumStoresRemoved, "Number of stores removed");
87STATISTIC(NumCallsHoisted, "Number of calls hoisted");
88STATISTIC(NumCallsRemoved, "Number of calls removed");
89
90namespace llvm {
91
94
95// Each element of a hoisting list contains the basic block where to hoist and
96// a list of instructions to be hoisted.
97using HoistingPointInfo = std::pair<BasicBlock *, SmallVecInsn>;
98
100
101// A map from a pair of VNs to all the instructions with those VNs.
102using VNType = std::pair<unsigned, uintptr_t>;
103
105
106// CHI keeps information about values flowing out of a basic block. It is
107// similar to PHI but in the inverse graph, and used for outgoing values on each
108// edge. For conciseness, it is computed only for instructions with multiple
109// occurrences in the CFG because they are the only hoistable candidates.
110// A (CHI[{V, B, I1}, {V, C, I2}]
111// / \
112// / \
113// B(I1) C (I2)
114// The Value number for both I1 and I2 is V, the CHI node will save the
115// instruction as well as the edge where the value is flowing to.
116struct CHIArg {
118
119 // Edge destination (shows the direction of flow), may not be where the I is.
121
122 // The instruction (VN) which uses the values flowing out of CHI.
124
125 bool operator==(const CHIArg &A) const { return VN == A.VN; }
126 bool operator!=(const CHIArg &A) const { return !(*this == A); }
127};
128
134
135// An invalid value number Used when inserting a single value number into
136// VNtoInsns.
138
139// Records all scalar instructions candidate for code hoisting.
140class InsnInfo {
141 VNtoInsns VNtoScalars;
142
143public:
144 // Inserts I and its value number in VNtoScalars.
146 // Scalar instruction.
147 unsigned V = VN.lookupOrAdd(I);
148 VNtoScalars[{V, InvalidVN}].push_back(I);
149 }
150
151 const VNtoInsns &getVNTable() const { return VNtoScalars; }
152};
153
154// Records all load instructions candidate for code hoisting.
155class LoadInfo {
156 VNtoInsns VNtoLoads;
157
158public:
159 // Insert Load and the value number of its memory address in VNtoLoads.
161 if (Load->isSimple()) {
162 unsigned V = VN.lookupOrAdd(Load->getPointerOperand());
163 // With opaque pointers we may have loads from the same pointer with
164 // different result types, which should be disambiguated.
165 VNtoLoads[{V, (uintptr_t)Load->getType()}].push_back(Load);
166 }
167 }
168
169 const VNtoInsns &getVNTable() const { return VNtoLoads; }
170};
171
172// Records all store instructions candidate for code hoisting.
174 VNtoInsns VNtoStores;
175
176public:
177 // Insert the Store and a hash number of the store address and the stored
178 // value in VNtoStores.
180 if (!Store->isSimple())
181 return;
182 // Hash the store address and the stored value.
183 Value *Ptr = Store->getPointerOperand();
184 Value *Val = Store->getValueOperand();
185 VNtoStores[{VN.lookupOrAdd(Ptr), VN.lookupOrAdd(Val)}].push_back(Store);
186 }
187
188 const VNtoInsns &getVNTable() const { return VNtoStores; }
189};
190
191// Records all call instructions candidate for code hoisting.
192class CallInfo {
193 VNtoInsns VNtoCallsScalars;
194 VNtoInsns VNtoCallsLoads;
195 VNtoInsns VNtoCallsStores;
196
197public:
198 // Insert Call and its value numbering in one of the VNtoCalls* containers.
200 // A call that doesNotAccessMemory is handled as a Scalar,
201 // onlyReadsMemory will be handled as a Load instruction,
202 // all other calls will be handled as stores.
203 unsigned V = VN.lookupOrAdd(Call);
204 auto Entry = std::make_pair(V, InvalidVN);
205
206 if (Call->doesNotAccessMemory())
207 VNtoCallsScalars[Entry].push_back(Call);
208 else if (Call->onlyReadsMemory())
209 VNtoCallsLoads[Entry].push_back(Call);
210 else
211 VNtoCallsStores[Entry].push_back(Call);
212 }
213
214 const VNtoInsns &getScalarVNTable() const { return VNtoCallsScalars; }
215 const VNtoInsns &getLoadVNTable() const { return VNtoCallsLoads; }
216 const VNtoInsns &getStoreVNTable() const { return VNtoCallsStores; }
217};
218
219// This pass hoists common computations across branches sharing common
220// dominator. The primary goal is to reduce the code size, and in some
221// cases reduce critical path (by exposing more ILP).
222class GVNHoist {
223public:
224 GVNHoist(const ScalarOptions &Opts, DominatorTree *DT, PostDominatorTree *PDT,
225 AliasAnalysis *AA, MemorySSA *MSSA)
226 : Opts(Opts), DT(DT), PDT(PDT), AA(AA), MSSA(MSSA),
227 MSSAUpdater(std::make_unique<MemorySSAUpdater>(MSSA)) {
228 MSSA->ensureOptimizedUses();
229 }
230
231 bool run(Function &F);
232
233 // Copied from NewGVN.cpp
234 // This function provides global ranking of operations so that we can place
235 // them in a canonical order. Note that rank alone is not necessarily enough
236 // for a complete ordering, as constants all have the same rank. However,
237 // generally, we will simplify an operation with all constants so that it
238 // doesn't matter what order they appear in.
239 unsigned int rank(const Value *V) const;
240
241private:
242 const ScalarOptions &Opts;
243 GVNValueTable VN;
244 DominatorTree *DT;
247 MemorySSA *MSSA;
248 std::unique_ptr<MemorySSAUpdater> MSSAUpdater;
250 BBSideEffectsSet BBSideEffects;
251 DenseSet<const BasicBlock *> HoistBarrier;
253 unsigned NumFuncArgs;
254 const bool HoistingGeps = false;
255
256 enum InsKind { Unknown, Scalar, Load, Store };
257
258 // Return true when there are exception handling in BB.
259 bool hasEH(const BasicBlock *BB);
260
261 // Return true when I1 appears before I2 in the instructions of BB.
262 bool firstInBB(const Instruction *I1, const Instruction *I2) {
263 assert(I1->getParent() == I2->getParent());
264 unsigned I1DFS = DFSNumber.lookup(I1);
265 unsigned I2DFS = DFSNumber.lookup(I2);
266 assert(I1DFS && I2DFS);
267 return I1DFS < I2DFS;
268 }
269
270 // Return true when there are memory uses of Def in BB.
271 bool hasMemoryUse(const Instruction *NewPt, MemoryDef *Def,
272 const BasicBlock *BB);
273
274 bool hasEHhelper(const BasicBlock *BB, const BasicBlock *SrcBB,
275 int &NBBsOnAllPaths);
276
277 // Return true when there are exception handling or loads of memory Def
278 // between Def and NewPt. This function is only called for stores: Def is
279 // the MemoryDef of the store to be hoisted.
280
281 // Decrement by 1 NBBsOnAllPaths for each block between HoistPt and BB, and
282 // return true when the counter NBBsOnAllPaths reaces 0, except when it is
283 // initialized to -1 which is unlimited.
284 bool hasEHOrLoadsOnPath(const Instruction *NewPt, MemoryDef *Def,
285 int &NBBsOnAllPaths);
286
287 // Return true when there are exception handling between HoistPt and BB.
288 // Decrement by 1 NBBsOnAllPaths for each block between HoistPt and BB, and
289 // return true when the counter NBBsOnAllPaths reaches 0, except when it is
290 // initialized to -1 which is unlimited.
291 bool hasEHOnPath(const BasicBlock *HoistPt, const BasicBlock *SrcBB,
292 int &NBBsOnAllPaths);
293
294 // Return true when it is safe to hoist a memory load or store U from OldPt
295 // to NewPt.
296 bool safeToHoistLdSt(const Instruction *NewPt, const Instruction *OldPt,
297 MemoryUseOrDef *U, InsKind K, int &NBBsOnAllPaths);
298
299 // Return true when it is safe to hoist scalar instructions from all blocks in
300 // WL to HoistBB.
301 bool safeToHoistScalar(const BasicBlock *HoistBB, const BasicBlock *BB,
302 int &NBBsOnAllPaths) {
303 return !hasEHOnPath(HoistBB, BB, NBBsOnAllPaths);
304 }
305
306 // In the inverse CFG, the dominance frontier of basic block (BB) is the
307 // point where ANTIC needs to be computed for instructions which are going
308 // to be hoisted. Since this point does not change during gvn-hoist,
309 // we compute it only once (on demand).
310 // The ides is inspired from:
311 // "Partial Redundancy Elimination in SSA Form"
312 // ROBERT KENNEDY, SUN CHAN, SHIN-MING LIU, RAYMOND LO, PENG TU and FRED CHOW
313 // They use similar idea in the forward graph to find fully redundant and
314 // partially redundant expressions, here it is used in the inverse graph to
315 // find fully anticipable instructions at merge point (post-dominator in
316 // the inverse CFG).
317 // Returns the edge via which an instruction in BB will get the values from.
318
319 // Returns true when the values are flowing out to each edge.
320 bool valueAnticipable(CHIArgs C, Instruction *TI) const;
321
322 // Check if it is safe to hoist values tracked by CHI in the range
323 // [Begin, End) and accumulate them in Safe.
324 void checkSafety(CHIArgs C, BasicBlock *BB, InsKind K,
325 SmallVectorImpl<CHIArg> &Safe);
326
327 using RenameStackType = DenseMap<VNType, SmallVector<Instruction *, 2>>;
328
329 // Push all the VNs corresponding to BB into RenameStack.
330 void fillRenameStack(BasicBlock *BB, InValuesType &ValueBBs,
331 RenameStackType &RenameStack);
332
333 void fillChiArgs(BasicBlock *BB, OutValuesType &CHIBBs,
334 RenameStackType &RenameStack);
335
336 // Walk the post-dominator tree top-down and use a stack for each value to
337 // store the last value you see. When you hit a CHI from a given edge, the
338 // value to use as the argument is at the top of the stack, add the value to
339 // CHI and pop.
340 void insertCHI(InValuesType &ValueBBs, OutValuesType &CHIBBs) {
341 auto Root = PDT->getNode(nullptr);
342 if (!Root)
343 return;
344 // Depth first walk on PDom tree to fill the CHIargs at each PDF.
345 for (auto *Node : depth_first(Root)) {
346 BasicBlock *BB = Node->getBlock();
347 if (!BB)
348 continue;
349
350 RenameStackType RenameStack;
351 // Collect all values in BB and push to stack.
352 fillRenameStack(BB, ValueBBs, RenameStack);
353
354 // Fill outgoing values in each CHI corresponding to BB.
355 fillChiArgs(BB, CHIBBs, RenameStack);
356 }
357 }
358
359 // Walk all the CHI-nodes to find ones which have a empty-entry and remove
360 // them Then collect all the instructions which are safe to hoist and see if
361 // they form a list of anticipable values. OutValues contains CHIs
362 // corresponding to each basic block.
363 void findHoistableCandidates(OutValuesType &CHIBBs, InsKind K,
364 HoistingPointList &HPL);
365
366 // Compute insertion points for each values which can be fully anticipated at
367 // a dominator. HPL contains all such values.
368 void computeInsertionPoints(const VNtoInsns &Map, HoistingPointList &HPL,
369 InsKind K) {
370 // Sort VNs based on their rankings
371 std::vector<VNType> Ranks;
372 for (const auto &Entry : Map) {
373 Ranks.push_back(Entry.first);
374 }
375
376 // TODO: Remove fully-redundant expressions.
377 // Get instruction from the Map, assume that all the Instructions
378 // with same VNs have same rank (this is an approximation).
379 llvm::sort(Ranks, [this, &Map](const VNType &r1, const VNType &r2) {
380 return (rank(*Map.lookup(r1).begin()) < rank(*Map.lookup(r2).begin()));
381 });
382
383 // - Sort VNs according to their rank, and start with lowest ranked VN
384 // - Take a VN and for each instruction with same VN
385 // - Find the dominance frontier in the inverse graph (PDF)
386 // - Insert the chi-node at PDF
387 // - Remove the chi-nodes with missing entries
388 // - Remove values from CHI-nodes which do not truly flow out, e.g.,
389 // modified along the path.
390 // - Collect the remaining values that are still anticipable
392 ReverseIDFCalculator IDFs(*PDT);
393 OutValuesType OutValue;
394 InValuesType InValue;
395 for (const auto &R : Ranks) {
396 const SmallVecInsn &V = Map.lookup(R);
397 if (V.size() < 2)
398 continue;
399 const VNType &VN = R;
400 SmallPtrSet<BasicBlock *, 2> VNBlocks;
401 for (const auto &I : V) {
402 BasicBlock *BBI = I->getParent();
403 if (!hasEH(BBI))
404 VNBlocks.insert(BBI);
405 }
406 // Compute the Post Dominance Frontiers of each basic block
407 // The dominance frontier of a live block X in the reverse
408 // control graph is the set of blocks upon which X is control
409 // dependent. The following sequence computes the set of blocks
410 // which currently have dead terminators that are control
411 // dependence sources of a block which is in NewLiveBlocks.
412 IDFs.setDefiningBlocks(VNBlocks);
413 IDFBlocks.clear();
414 IDFs.calculate(IDFBlocks);
415
416 // Make a map of BB vs instructions to be hoisted.
417 for (unsigned i = 0; i < V.size(); ++i) {
418 InValue[V[i]->getParent()].push_back(std::make_pair(VN, V[i]));
419 }
420 // Insert empty CHI node for this VN. This is used to factor out
421 // basic blocks where the ANTIC can potentially change.
422 CHIArg EmptyChi = {VN, nullptr, nullptr};
423 for (auto *IDFBB : IDFBlocks) {
424 for (unsigned i = 0; i < V.size(); ++i) {
425 // Ignore spurious PDFs.
426 if (DT->properlyDominates(IDFBB, V[i]->getParent())) {
427 OutValue[IDFBB].push_back(EmptyChi);
428 LLVM_DEBUG(dbgs() << "\nInserting a CHI for BB: "
429 << IDFBB->getName() << ", for Insn: " << *V[i]);
430 }
431 }
432 }
433 }
434
435 // Insert CHI args at each PDF to iterate on factored graph of
436 // control dependence.
437 insertCHI(InValue, OutValue);
438 // Using the CHI args inserted at each PDF, find fully anticipable values.
439 findHoistableCandidates(OutValue, K, HPL);
440 }
441
442 // Return true when all operands of Instr are available at insertion point
443 // HoistPt. When limiting the number of hoisted expressions, one could hoist
444 // a load without hoisting its access function. So before hoisting any
445 // expression, make sure that all its operands are available at insert point.
446 bool allOperandsAvailable(const Instruction *I,
447 const BasicBlock *HoistPt) const;
448
449 // Same as allOperandsAvailable with recursive check for GEP operands.
450 bool allGepOperandsAvailable(const Instruction *I,
451 const BasicBlock *HoistPt) const;
452
453 // Make all operands of the GEP available.
454 void makeGepsAvailable(Instruction *Repl, BasicBlock *HoistPt,
455 const SmallVecInsn &InstructionsToHoist,
456 Instruction *Gep) const;
457
458 void updateAlignment(Instruction *I, Instruction *Repl);
459
460 // Remove all the instructions in Candidates and replace their usage with
461 // Repl. Returns the number of instructions removed.
462 unsigned rauw(const SmallVecInsn &Candidates, Instruction *Repl,
463 MemoryUseOrDef *NewMemAcc);
464
465 // Replace all Memory PHI usage with NewMemAcc.
466 void raMPHIuw(MemoryUseOrDef *NewMemAcc);
467
468 // Remove all other instructions and replace them with Repl.
469 unsigned removeAndReplace(const SmallVecInsn &Candidates, Instruction *Repl,
470 BasicBlock *DestBB, bool MoveAccess);
471
472 // In the case Repl is a load or a store, we make all their GEPs
473 // available: GEPs are not hoisted by default to avoid the address
474 // computations to be hoisted without the associated load or store.
475 bool makeGepOperandsAvailable(Instruction *Repl, BasicBlock *HoistPt,
476 const SmallVecInsn &InstructionsToHoist) const;
477
478 std::pair<unsigned, unsigned> hoist(HoistingPointList &HPL);
479
480 // Hoist all expressions. Returns Number of scalars hoisted
481 // and number of non-scalars hoisted.
482 std::pair<unsigned, unsigned> hoistExpressions(Function &F);
483};
484
486 NumFuncArgs = F.arg_size();
487 VN.setDomTree(DT);
488 VN.setAliasAnalysis(AA);
489 // TODO: Is this actually needed?
490 VN.setMemorySSA(MSSA, true);
491 bool Res = false;
492 // Perform DFS Numbering of instructions.
493 unsigned BBI = 0;
494 for (const BasicBlock *BB : depth_first(&F.getEntryBlock())) {
495 DFSNumber[BB] = ++BBI;
496 unsigned I = 0;
497 for (const auto &Inst : *BB)
498 DFSNumber[&Inst] = ++I;
499 }
500
501 int ChainLength = 0;
502
503 // FIXME: use lazy evaluation of VN to avoid the fix-point computation.
504 while (true) {
505 if (Opts.gvn_hoist_max_chain_length != -1 &&
506 ++ChainLength >= Opts.gvn_hoist_max_chain_length)
507 return Res;
508
509 auto HoistStat = hoistExpressions(F);
510 if (HoistStat.first + HoistStat.second == 0)
511 return Res;
512
513 if (HoistStat.second > 0)
514 // To address a limitation of the current GVN, we need to rerun the
515 // hoisting after we hoisted loads or stores in order to be able to
516 // hoist all scalars dependent on the hoisted ld/st.
517 VN.clear();
518
519 Res = true;
520 }
521
522 return Res;
523}
524
525unsigned int GVNHoist::rank(const Value *V) const {
526 // Prefer constants to undef to anything else
527 // Undef is a constant, have to check it first.
528 // Prefer smaller constants to constantexprs
529 if (isa<ConstantExpr>(V))
530 return 2;
531 if (isa<UndefValue>(V))
532 return 1;
533 if (isa<Constant>(V))
534 return 0;
535 else if (auto *A = dyn_cast<Argument>(V))
536 return 3 + A->getArgNo();
537
538 // Need to shift the instruction DFS by number of arguments + 3 to account
539 // for the constant and argument ranking above.
540 auto Result = DFSNumber.lookup(V);
541 if (Result > 0)
542 return 4 + NumFuncArgs + Result;
543 // Unreachable or something else, just return a really large number.
544 return ~0;
545}
546
547bool GVNHoist::hasEH(const BasicBlock *BB) {
548 auto [It, Inserted] = BBSideEffects.try_emplace(BB);
549 if (!Inserted)
550 return It->second;
551
552 if (BB->isEHPad() || BB->hasAddressTaken()) {
553 It->second = true;
554 return true;
555 }
556
557 if (BB->getTerminator()->mayThrow()) {
558 It->second = true;
559 return true;
560 }
561
562 return false;
563}
564
565bool GVNHoist::hasMemoryUse(const Instruction *NewPt, MemoryDef *Def,
566 const BasicBlock *BB) {
567 const MemorySSA::AccessList *Acc = MSSA->getBlockAccesses(BB);
568 if (!Acc)
569 return false;
570
571 Instruction *OldPt = Def->getMemoryInst();
572 const BasicBlock *OldBB = OldPt->getParent();
573 const BasicBlock *NewBB = NewPt->getParent();
574 bool ReachedNewPt = false;
575
576 for (const MemoryAccess &MA : *Acc)
577 if (const MemoryUse *MU = dyn_cast<MemoryUse>(&MA)) {
578 Instruction *Insn = MU->getMemoryInst();
579
580 // Do not check whether MU aliases Def when MU occurs after OldPt.
581 if (BB == OldBB && firstInBB(OldPt, Insn))
582 break;
583
584 // Do not check whether MU aliases Def when MU occurs before NewPt.
585 if (BB == NewBB) {
586 if (!ReachedNewPt) {
587 if (firstInBB(Insn, NewPt))
588 continue;
589 ReachedNewPt = true;
590 }
591 }
592 if (MemorySSAUtil::defClobbersUseOrDef(Def, MU, *AA))
593 return true;
594 }
595
596 return false;
597}
598
599bool GVNHoist::hasEHhelper(const BasicBlock *BB, const BasicBlock *SrcBB,
600 int &NBBsOnAllPaths) {
601 // Stop walk once the limit is reached.
602 if (NBBsOnAllPaths == 0)
603 return true;
604
605 // Impossible to hoist with exceptions on the path.
606 if (hasEH(BB))
607 return true;
608
609 // No such instruction after HoistBarrier in a basic block was
610 // selected for hoisting so instructions selected within basic block with
611 // a hoist barrier can be hoisted.
612 if ((BB != SrcBB) && HoistBarrier.count(BB))
613 return true;
614
615 return false;
616}
617
618bool GVNHoist::hasEHOrLoadsOnPath(const Instruction *NewPt, MemoryDef *Def,
619 int &NBBsOnAllPaths) {
620 const BasicBlock *NewBB = NewPt->getParent();
621 const BasicBlock *OldBB = Def->getBlock();
622 assert(DT->dominates(NewBB, OldBB) && "invalid path");
623 assert(DT->dominates(Def->getDefiningAccess()->getBlock(), NewBB) &&
624 "def does not dominate new hoisting point");
625
626 // Walk all basic blocks reachable in depth-first iteration on the inverse
627 // CFG from OldBB to NewBB. These blocks are all the blocks that may be
628 // executed between the execution of NewBB and OldBB. Hoisting an expression
629 // from OldBB into NewBB has to be safe on all execution paths.
630 for (auto I = idf_begin(OldBB), E = idf_end(OldBB); I != E;) {
631 const BasicBlock *BB = *I;
632 if (BB == NewBB) {
633 // Stop traversal when reaching HoistPt.
634 I.skipChildren();
635 continue;
636 }
637
638 if (hasEHhelper(BB, OldBB, NBBsOnAllPaths))
639 return true;
640
641 // Check that we do not move a store past loads.
642 if (hasMemoryUse(NewPt, Def, BB))
643 return true;
644
645 // -1 is unlimited number of blocks on all paths.
646 if (NBBsOnAllPaths != -1)
647 --NBBsOnAllPaths;
648
649 ++I;
650 }
651
652 return false;
653}
654
655bool GVNHoist::hasEHOnPath(const BasicBlock *HoistPt, const BasicBlock *SrcBB,
656 int &NBBsOnAllPaths) {
657 assert(DT->dominates(HoistPt, SrcBB) && "Invalid path");
658
659 // Walk all basic blocks reachable in depth-first iteration on
660 // the inverse CFG from BBInsn to NewHoistPt. These blocks are all the
661 // blocks that may be executed between the execution of NewHoistPt and
662 // BBInsn. Hoisting an expression from BBInsn into NewHoistPt has to be safe
663 // on all execution paths.
664 for (auto I = idf_begin(SrcBB), E = idf_end(SrcBB); I != E;) {
665 const BasicBlock *BB = *I;
666 if (BB == HoistPt) {
667 // Stop traversal when reaching NewHoistPt.
668 I.skipChildren();
669 continue;
670 }
671
672 if (hasEHhelper(BB, SrcBB, NBBsOnAllPaths))
673 return true;
674
675 // -1 is unlimited number of blocks on all paths.
676 if (NBBsOnAllPaths != -1)
677 --NBBsOnAllPaths;
678
679 ++I;
680 }
681
682 return false;
683}
684
685bool GVNHoist::safeToHoistLdSt(const Instruction *NewPt,
686 const Instruction *OldPt, MemoryUseOrDef *U,
687 GVNHoist::InsKind K, int &NBBsOnAllPaths) {
688 // In place hoisting is safe.
689 if (NewPt == OldPt)
690 return true;
691
692 const BasicBlock *NewBB = NewPt->getParent();
693 const BasicBlock *OldBB = OldPt->getParent();
694 const BasicBlock *UBB = U->getBlock();
695
696 // Check for dependences on the Memory SSA.
697 MemoryAccess *D = U->getDefiningAccess();
698 BasicBlock *DBB = D->getBlock();
699 if (DT->properlyDominates(NewBB, DBB))
700 // Cannot move the load or store to NewBB above its definition in DBB.
701 return false;
702
703 if (NewBB == DBB && !MSSA->isLiveOnEntryDef(D))
704 if (auto *UD = dyn_cast<MemoryUseOrDef>(D))
705 if (!firstInBB(UD->getMemoryInst(), NewPt))
706 // Cannot move the load or store to NewPt above its definition in D.
707 return false;
708
709 // Check for unsafe hoistings due to side effects.
710 if (K == InsKind::Store) {
711 if (hasEHOrLoadsOnPath(NewPt, cast<MemoryDef>(U), NBBsOnAllPaths))
712 return false;
713 } else if (hasEHOnPath(NewBB, OldBB, NBBsOnAllPaths))
714 return false;
715
716 if (UBB == NewBB) {
717 if (DT->properlyDominates(DBB, NewBB))
718 return true;
719 assert(UBB == DBB);
720 assert(MSSA->locallyDominates(D, U));
721 }
722
723 // No side effects: it is safe to hoist.
724 return true;
725}
726
727bool GVNHoist::valueAnticipable(CHIArgs C, Instruction *TI) const {
728 if (TI->getNumSuccessors() > (unsigned)size(C))
729 return false; // Not enough args in this CHI.
730
731 for (auto CHI : C) {
732 // Find if all the edges have values flowing out of BB.
733 if (!llvm::is_contained(successors(TI), CHI.Dest))
734 return false;
735 }
736 return true;
737}
738
739void GVNHoist::checkSafety(CHIArgs C, BasicBlock *BB, GVNHoist::InsKind K,
741 int NumBBsOnAllPaths = Opts.gvn_hoist_max_bbs;
742 const Instruction *T = BB->getTerminator();
743 for (auto CHI : C) {
744 Instruction *Insn = CHI.I;
745 if (!Insn) // No instruction was inserted in this CHI.
746 continue;
747 // If the Terminator is some kind of "exotic terminator" that produces a
748 // value (such as InvokeInst, CallBrInst, or CatchSwitchInst) which the CHI
749 // uses, it is not safe to hoist the use above the def.
750 if (!T->use_empty() && is_contained(Insn->operands(), cast<const Value>(T)))
751 continue;
752 if (K == InsKind::Scalar) {
753 if (safeToHoistScalar(BB, Insn->getParent(), NumBBsOnAllPaths))
754 Safe.push_back(CHI);
755 } else {
756 if (MemoryUseOrDef *UD = MSSA->getMemoryAccess(Insn))
757 if (safeToHoistLdSt(T, Insn, UD, K, NumBBsOnAllPaths))
758 Safe.push_back(CHI);
759 }
760 }
761}
762
763void GVNHoist::fillRenameStack(BasicBlock *BB, InValuesType &ValueBBs,
764 GVNHoist::RenameStackType &RenameStack) {
765 auto it1 = ValueBBs.find(BB);
766 if (it1 != ValueBBs.end()) {
767 // Iterate in reverse order to keep lower ranked values on the top.
768 LLVM_DEBUG(dbgs() << "\nVisiting: " << BB->getName()
769 << " for pushing instructions on stack";);
770 for (std::pair<VNType, Instruction *> &VI : reverse(it1->second)) {
771 // Get the value of instruction I
772 LLVM_DEBUG(dbgs() << "\nPushing on stack: " << *VI.second);
773 RenameStack[VI.first].push_back(VI.second);
774 }
775 }
776}
777
778void GVNHoist::fillChiArgs(BasicBlock *BB, OutValuesType &CHIBBs,
779 GVNHoist::RenameStackType &RenameStack) {
780 // For each *predecessor* (because Post-DOM) of BB check if it has a CHI
781 for (auto *Pred : predecessors(BB)) {
782 auto P = CHIBBs.find(Pred);
783 if (P == CHIBBs.end()) {
784 continue;
785 }
786 LLVM_DEBUG(dbgs() << "\nLooking at CHIs in: " << Pred->getName(););
787 // A CHI is found (BB -> Pred is an edge in the CFG)
788 // Pop the stack until Top(V) = Ve.
789 auto &VCHI = P->second;
790 for (auto It = VCHI.begin(), E = VCHI.end(); It != E;) {
791 CHIArg &C = *It;
792 if (!C.Dest) {
793 auto si = RenameStack.find(C.VN);
794 // The Basic Block where CHI is must dominate the value we want to
795 // track in a CHI. In the PDom walk, there can be values in the
796 // stack which are not control dependent e.g., nested loop.
797 if (si != RenameStack.end() && si->second.size() &&
798 DT->properlyDominates(Pred, si->second.back()->getParent())) {
799 C.Dest = BB; // Assign the edge
800 C.I = si->second.pop_back_val(); // Assign the argument
802 << "\nCHI Inserted in BB: " << C.Dest->getName() << *C.I
803 << ", VN: " << C.VN.first << ", " << C.VN.second);
804 }
805 // Move to next CHI of a different value
806 It = std::find_if(It, VCHI.end(), not_equal_to(*It));
807 } else
808 ++It;
809 }
810 }
811}
812
813void GVNHoist::findHoistableCandidates(OutValuesType &CHIBBs,
814 GVNHoist::InsKind K,
815 HoistingPointList &HPL) {
816 auto cmpVN = [](const CHIArg &A, const CHIArg &B) { return A.VN < B.VN; };
817
818 // CHIArgs now have the outgoing values, so check for anticipability and
819 // accumulate hoistable candidates in HPL.
820 for (auto &A : CHIBBs) {
821 BasicBlock *BB = A.first;
822 SmallVectorImpl<CHIArg> &CHIs = A.second;
823 // Vector of PHIs contains PHIs for different instructions.
824 // Sort the args according to their VNs, such that identical
825 // instructions are together.
826 llvm::stable_sort(CHIs, cmpVN);
827 auto TI = BB->getTerminator();
828 auto B = CHIs.begin();
829 // [PreIt, PHIIt) form a range of CHIs which have identical VNs.
830 auto PHIIt = llvm::find_if(CHIs, not_equal_to(*B));
831 auto PrevIt = CHIs.begin();
832 while (PrevIt != PHIIt) {
833 // Collect values which satisfy safety checks.
835 // We check for safety first because there might be multiple values in
836 // the same path, some of which are not safe to be hoisted, but overall
837 // each edge has at least one value which can be hoisted, making the
838 // value anticipable along that path.
839 checkSafety(make_range(PrevIt, PHIIt), BB, K, Safe);
840
841 // List of safe values should be anticipable at TI.
842 if (valueAnticipable(make_range(Safe.begin(), Safe.end()), TI)) {
843 HPL.push_back({BB, SmallVecInsn()});
844 SmallVecInsn &V = HPL.back().second;
845 for (auto B : Safe)
846 V.push_back(B.I);
847 }
848
849 // Check other VNs
850 PrevIt = PHIIt;
851 PHIIt = std::find_if(PrevIt, CHIs.end(),
852 [PrevIt](CHIArg &A) { return A != *PrevIt; });
853 }
854 }
855}
856
857bool GVNHoist::allOperandsAvailable(const Instruction *I,
858 const BasicBlock *HoistPt) const {
859 for (const Use &Op : I->operands())
860 if (const auto *Inst = dyn_cast<Instruction>(&Op))
861 if (!DT->dominates(Inst->getParent(), HoistPt))
862 return false;
863
864 return true;
865}
866
867bool GVNHoist::allGepOperandsAvailable(const Instruction *I,
868 const BasicBlock *HoistPt) const {
869 for (const Use &Op : I->operands())
870 if (const auto *Inst = dyn_cast<Instruction>(&Op))
871 if (!DT->dominates(Inst->getParent(), HoistPt)) {
872 if (const GetElementPtrInst *GepOp =
874 if (!allGepOperandsAvailable(GepOp, HoistPt))
875 return false;
876 // Gep is available if all operands of GepOp are available.
877 } else {
878 // Gep is not available if it has operands other than GEPs that are
879 // defined in blocks not dominating HoistPt.
880 return false;
881 }
882 }
883 return true;
884}
885
886void GVNHoist::makeGepsAvailable(Instruction *Repl, BasicBlock *HoistPt,
887 const SmallVecInsn &InstructionsToHoist,
888 Instruction *Gep) const {
889 assert(allGepOperandsAvailable(Gep, HoistPt) && "GEP operands not available");
890
891 Instruction *ClonedGep = Gep->clone();
892 for (unsigned i = 0, e = Gep->getNumOperands(); i != e; ++i)
893 if (Instruction *Op = dyn_cast<Instruction>(Gep->getOperand(i))) {
894 // Check whether the operand is already available.
895 if (DT->dominates(Op->getParent(), HoistPt))
896 continue;
897
898 // As a GEP can refer to other GEPs, recursively make all the operands
899 // of this GEP available at HoistPt.
900 if (GetElementPtrInst *GepOp = dyn_cast<GetElementPtrInst>(Op))
901 makeGepsAvailable(ClonedGep, HoistPt, InstructionsToHoist, GepOp);
902 }
903
904 // Copy Gep and replace its uses in Repl with ClonedGep.
905 ClonedGep->insertBefore(HoistPt->getTerminator()->getIterator());
906
907 // Conservatively discard any optimization hints, they may differ on the
908 // other paths.
909 ClonedGep->dropUnknownNonDebugMetadata();
910
911 // If we have optimization hints which agree with each other along different
912 // paths, preserve them.
913 for (const Instruction *OtherInst : InstructionsToHoist) {
914 const GetElementPtrInst *OtherGep;
915 if (auto *OtherLd = dyn_cast<LoadInst>(OtherInst))
916 OtherGep = cast<GetElementPtrInst>(OtherLd->getPointerOperand());
917 else
918 OtherGep = cast<GetElementPtrInst>(
919 cast<StoreInst>(OtherInst)->getPointerOperand());
920 ClonedGep->andIRFlags(OtherGep);
921
922 // Merge debug locations of GEPs, because the hoisted GEP replaces those
923 // in branches. When cloning, ClonedGep preserves the debug location of
924 // Gepd, so Gep is skipped to avoid merging it twice.
925 if (OtherGep != Gep) {
926 ClonedGep->applyMergedLocation(ClonedGep->getDebugLoc(),
927 OtherGep->getDebugLoc());
928 }
929 }
930
931 // Replace uses of Gep with ClonedGep in Repl.
932 Repl->replaceUsesOfWith(Gep, ClonedGep);
933}
934
935void GVNHoist::updateAlignment(Instruction *I, Instruction *Repl) {
936 if (auto *ReplacementLoad = dyn_cast<LoadInst>(Repl)) {
937 ReplacementLoad->setAlignment(
938 std::min(ReplacementLoad->getAlign(), cast<LoadInst>(I)->getAlign()));
939 ++NumLoadsRemoved;
940 } else if (auto *ReplacementStore = dyn_cast<StoreInst>(Repl)) {
941 ReplacementStore->setAlignment(
942 std::min(ReplacementStore->getAlign(), cast<StoreInst>(I)->getAlign()));
943 ++NumStoresRemoved;
944 } else if (auto *ReplacementAlloca = dyn_cast<AllocaInst>(Repl)) {
945 ReplacementAlloca->setAlignment(std::max(ReplacementAlloca->getAlign(),
946 cast<AllocaInst>(I)->getAlign()));
947 } else if (isa<CallInst>(Repl)) {
948 ++NumCallsRemoved;
949 }
950}
951
952unsigned GVNHoist::rauw(const SmallVecInsn &Candidates, Instruction *Repl,
953 MemoryUseOrDef *NewMemAcc) {
954 unsigned NR = 0;
955 for (Instruction *I : Candidates) {
956 if (I != Repl) {
957 ++NR;
958 updateAlignment(I, Repl);
959 if (NewMemAcc) {
960 // Update the uses of the old MSSA access with NewMemAcc.
961 MemoryAccess *OldMA = MSSA->getMemoryAccess(I);
962 OldMA->replaceAllUsesWith(NewMemAcc);
963 MSSAUpdater->removeMemoryAccess(OldMA);
964 } else if (MemoryAccess *OldMA = MSSA->getMemoryAccess(I)) {
965 MSSAUpdater->removeMemoryAccess(OldMA);
966 }
967
968 combineMetadataForCSE(Repl, I, true);
969 Repl->andIRFlags(I);
970 I->replaceAllUsesWith(Repl);
971 I->eraseFromParent();
972 }
973 }
974 return NR;
975}
976
977void GVNHoist::raMPHIuw(MemoryUseOrDef *NewMemAcc) {
978 SmallPtrSet<MemoryPhi *, 4> UsePhis;
979 for (User *U : NewMemAcc->users())
980 if (MemoryPhi *Phi = dyn_cast<MemoryPhi>(U))
981 UsePhis.insert(Phi);
982
983 for (MemoryPhi *Phi : UsePhis) {
984 auto In = Phi->incoming_values();
985 if (llvm::all_of(In, equal_to(NewMemAcc))) {
986 Phi->replaceAllUsesWith(NewMemAcc);
987 MSSAUpdater->removeMemoryAccess(Phi);
988 }
989 }
990}
991
992unsigned GVNHoist::removeAndReplace(const SmallVecInsn &Candidates,
993 Instruction *Repl, BasicBlock *DestBB,
994 bool MoveAccess) {
995 MemoryUseOrDef *NewMemAcc = MSSA->getMemoryAccess(Repl);
996 if (MoveAccess && NewMemAcc) {
997 // The definition of this ld/st will not change: ld/st hoisting is
998 // legal when the ld/st is not moved past its current definition.
999 MSSAUpdater->moveToPlace(NewMemAcc, DestBB, MemorySSA::BeforeTerminator);
1000 }
1001
1002 // Replace all other instructions with Repl with memory access NewMemAcc.
1003 unsigned NR = rauw(Candidates, Repl, NewMemAcc);
1004
1005 // Remove MemorySSA phi nodes with the same arguments.
1006 if (NewMemAcc)
1007 raMPHIuw(NewMemAcc);
1008 return NR;
1009}
1010
1011bool GVNHoist::makeGepOperandsAvailable(
1012 Instruction *Repl, BasicBlock *HoistPt,
1013 const SmallVecInsn &InstructionsToHoist) const {
1014 // Check whether the GEP of a ld/st can be synthesized at HoistPt.
1015 GetElementPtrInst *Gep = nullptr;
1016 Instruction *Val = nullptr;
1017 if (auto *Ld = dyn_cast<LoadInst>(Repl)) {
1018 Gep = dyn_cast<GetElementPtrInst>(Ld->getPointerOperand());
1019 } else if (auto *St = dyn_cast<StoreInst>(Repl)) {
1020 Gep = dyn_cast<GetElementPtrInst>(St->getPointerOperand());
1021 Val = dyn_cast<Instruction>(St->getValueOperand());
1022 // Check that the stored value is available.
1023 if (Val) {
1024 if (isa<GetElementPtrInst>(Val)) {
1025 // Check whether we can compute the GEP at HoistPt.
1026 if (!allGepOperandsAvailable(Val, HoistPt))
1027 return false;
1028 } else if (!DT->dominates(Val->getParent(), HoistPt))
1029 return false;
1030 }
1031 }
1032
1033 // Check whether we can compute the Gep at HoistPt.
1034 if (!Gep || !allGepOperandsAvailable(Gep, HoistPt))
1035 return false;
1036
1037 makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Gep);
1038
1039 if (Val && isa<GetElementPtrInst>(Val))
1040 makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Val);
1041
1042 return true;
1043}
1044
1045std::pair<unsigned, unsigned> GVNHoist::hoist(HoistingPointList &HPL) {
1046 unsigned NI = 0, NL = 0, NS = 0, NC = 0, NR = 0;
1047 for (const HoistingPointInfo &HP : HPL) {
1048 // Find out whether we already have one of the instructions in HoistPt,
1049 // in which case we do not have to move it.
1050 BasicBlock *DestBB = HP.first;
1051 const SmallVecInsn &InstructionsToHoist = HP.second;
1052 Instruction *Repl = nullptr;
1053 for (Instruction *I : InstructionsToHoist)
1054 if (I->getParent() == DestBB)
1055 // If there are two instructions in HoistPt to be hoisted in place:
1056 // update Repl to be the first one, such that we can rename the uses
1057 // of the second based on the first.
1058 if (!Repl || firstInBB(I, Repl))
1059 Repl = I;
1060
1061 // Keep track of whether we moved the instruction so we know whether we
1062 // should move the MemoryAccess.
1063 bool MoveAccess = true;
1064 if (Repl) {
1065 // Repl is already in HoistPt: it remains in place.
1066 assert(allOperandsAvailable(Repl, DestBB) &&
1067 "instruction depends on operands that are not available");
1068 MoveAccess = false;
1069 } else {
1070 // When we do not find Repl in HoistPt, select the first in the list
1071 // and move it to HoistPt.
1072 Repl = InstructionsToHoist.front();
1073
1074 // We can move Repl in HoistPt only when all operands are available.
1075 // The order in which hoistings are done may influence the availability
1076 // of operands.
1077 if (!allOperandsAvailable(Repl, DestBB)) {
1078 // When HoistingGeps there is nothing more we can do to make the
1079 // operands available: just continue.
1080 if (HoistingGeps)
1081 continue;
1082
1083 // When not HoistingGeps we need to copy the GEPs.
1084 if (!makeGepOperandsAvailable(Repl, DestBB, InstructionsToHoist))
1085 continue;
1086 }
1087
1088 // Move the instruction at the end of HoistPt.
1089 Instruction *Last = DestBB->getTerminator();
1090 if (auto *MUD = MSSA->getMemoryAccess(Repl))
1091 MSSAUpdater->moveToPlace(MUD, DestBB, MemorySSA::BeforeTerminator);
1092 Repl->moveBefore(Last->getIterator());
1093
1094 DFSNumber[Repl] = DFSNumber[Last]++;
1095 }
1096
1097 // Drop debug location as per debug info update guide.
1098 Repl->dropLocation();
1099 NR += removeAndReplace(InstructionsToHoist, Repl, DestBB, MoveAccess);
1100
1101 if (isa<LoadInst>(Repl))
1102 ++NL;
1103 else if (isa<StoreInst>(Repl))
1104 ++NS;
1105 else if (isa<CallInst>(Repl))
1106 ++NC;
1107 else // Scalar
1108 ++NI;
1109 }
1110
1111 if (MSSA && VerifyMemorySSA)
1112 MSSA->verifyMemorySSA();
1113
1114 NumHoisted += NL + NS + NC + NI;
1115 NumRemoved += NR;
1116 NumLoadsHoisted += NL;
1117 NumStoresHoisted += NS;
1118 NumCallsHoisted += NC;
1119 return {NI, NL + NC + NS};
1120}
1121
1122std::pair<unsigned, unsigned> GVNHoist::hoistExpressions(Function &F) {
1123 InsnInfo II;
1124 LoadInfo LI;
1125 StoreInfo SI;
1126 CallInfo CI;
1127 for (BasicBlock *BB : depth_first(&F.getEntryBlock())) {
1128 int InstructionNb = 0;
1129 for (Instruction &I1 : *BB) {
1130 // If I1 cannot guarantee progress, subsequent instructions
1131 // in BB cannot be hoisted anyways.
1133 HoistBarrier.insert(BB);
1134 break;
1135 }
1136 // Only hoist the first instructions in BB up to MaxDepthInBB. Hoisting
1137 // deeper may increase the register pressure and compilation time.
1138 if (Opts.gvn_hoist_max_depth != -1 &&
1139 InstructionNb++ >= Opts.gvn_hoist_max_depth)
1140 break;
1141
1142 // Do not value number terminator instructions.
1143 if (I1.isTerminator())
1144 break;
1145
1146 if (auto *Load = dyn_cast<LoadInst>(&I1))
1147 LI.insert(Load, VN);
1148 else if (auto *Store = dyn_cast<StoreInst>(&I1))
1149 SI.insert(Store, VN);
1150 else if (auto *Call = dyn_cast<CallInst>(&I1)) {
1151 if (auto *Intr = dyn_cast<IntrinsicInst>(Call)) {
1152 if (Intr->getIntrinsicID() == Intrinsic::assume ||
1153 Intr->getIntrinsicID() == Intrinsic::sideeffect)
1154 continue;
1155 }
1156 if (Call->mayHaveSideEffects())
1157 break;
1158
1159 if (Call->isConvergent())
1160 break;
1161
1162 CI.insert(Call, VN);
1163 } else if (HoistingGeps || !isa<GetElementPtrInst>(&I1))
1164 // Do not hoist scalars past calls that may write to memory because
1165 // that could result in spills later. geps are handled separately.
1166 // TODO: We can relax this for targets like AArch64 as they have more
1167 // registers than X86.
1168 II.insert(&I1, VN);
1169 }
1170 }
1171
1173 computeInsertionPoints(II.getVNTable(), HPL, InsKind::Scalar);
1174 computeInsertionPoints(LI.getVNTable(), HPL, InsKind::Load);
1175 computeInsertionPoints(SI.getVNTable(), HPL, InsKind::Store);
1176 computeInsertionPoints(CI.getScalarVNTable(), HPL, InsKind::Scalar);
1177 computeInsertionPoints(CI.getLoadVNTable(), HPL, InsKind::Load);
1178 computeInsertionPoints(CI.getStoreVNTable(), HPL, InsKind::Store);
1179 return hoist(HPL);
1180}
1181
1182} // end namespace llvm
1183
1188 MemorySSA &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA();
1189 const ScalarOptions &Opts = getScalarOptions(F);
1190 GVNHoist G(Opts, &DT, &PDT, &AA, &MSSA);
1191 if (!G.run(F))
1192 return PreservedAnalyses::all();
1193
1197 return PA;
1198}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file provides the interface for the GVNHoist pass.
This file provides a data structure for mapping values and expressions to congruence class IDs.
This is the interface for a simple mod/ref and alias analysis over globals.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
#define T
uint64_t IntrinsicInst * II
#define P(N)
static void r2(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, int I, uint32_t *Buf)
Definition SHA1.cpp:51
static void r1(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, int I, uint32_t *Buf)
Definition SHA1.cpp:45
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
A manager for alias analyses.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
Definition BasicBlock.h:666
bool isEHPad() const
Return true if this basic block is an exception handling block.
Definition BasicBlock.h:683
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
bool isConvergent() const
Determine if the invoke is convergent.
void insert(CallInst *Call, GVNValueTable &VN)
Definition GVNHoist.cpp:199
const VNtoInsns & getLoadVNTable() const
Definition GVNHoist.cpp:215
const VNtoInsns & getScalarVNTable() const
Definition GVNHoist.cpp:214
const VNtoInsns & getStoreVNTable() const
Definition GVNHoist.cpp:216
This class represents a function call, abstracting a target machine's calling convention.
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:793
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:856
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
bool run(Function &F)
Definition GVNHoist.cpp:485
GVNHoist(const ScalarOptions &Opts, DominatorTree *DT, PostDominatorTree *PDT, AliasAnalysis *AA, MemorySSA *MSSA)
Definition GVNHoist.cpp:224
unsigned int rank(const Value *V) const
Definition GVNHoist.cpp:525
This class holds the mapping between values and value numbers.
LLVM_ABI uint32_t lookupOrAdd(MemoryAccess *MA)
Definition GVN.cpp:909
void insert(Instruction *I, GVNValueTable &VN)
Definition GVNHoist.cpp:145
const VNtoInsns & getVNTable() const
Definition GVNHoist.cpp:151
LLVM_ABI bool mayThrow(bool IncludePhaseOneUnwind=false) const LLVM_READONLY
Return true if this instruction may throw an exception.
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI void dropLocation()
Drop the instruction's debug location.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
LLVM_ABI void dropUnknownNonDebugMetadata(ArrayRef< unsigned > KnownIDs={})
Drop all unknown metadata except for debug locations.
LLVM_ABI void applyMergedLocation(DebugLoc LocA, DebugLoc LocB)
Merge 2 debug locations and apply it to the Instruction.
const VNtoInsns & getVNTable() const
Definition GVNHoist.cpp:169
void insert(LoadInst *Load, GVNValueTable &VN)
Definition GVNHoist.cpp:160
An instruction for reading from memory.
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
Definition MemorySSA.h:372
An analysis that produces MemorySSA for a function.
Definition MemorySSA.h:917
static LLVM_ABI bool defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU, AliasAnalysis &AA)
Encapsulates MemorySSA, including all data associated with memory accesses.
Definition MemorySSA.h:696
iplist< MemoryAccess, ilist_tag< MSSAHelpers::AllAccessTag > > AccessList
Definition MemorySSA.h:747
Class that has the common methods + fields of memory uses/defs.
Definition MemorySSA.h:251
Analysis pass which computes a PostDominatorTree.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void insert(StoreInst *Store, GVNValueTable &VN)
Definition GVNHoist.cpp:179
const VNtoInsns & getVNTable() const
Definition GVNHoist.cpp:188
An instruction for storing to memory.
op_range operands()
Definition User.h:267
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:25
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
iterator_range< user_iterator > users()
Definition Value.h:428
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
A range adaptor for a pair of iterators.
CallInst * Call
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
Abstract Attribute helper functions.
Definition Attributor.h:164
@ Entry
Definition COFF.h:862
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
NodeAddr< DefNode * > Def
Definition RDFGraph.h:384
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
DenseMap< BasicBlock *, SmallVector< std::pair< VNType, Instruction * >, 2 > > InValuesType
Definition GVNHoist.cpp:132
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
Definition STLExtras.h:2196
@ InvalidVN
Definition GVNHoist.cpp:137
void stable_sort(R &&Range)
Definition STLExtras.h:2132
SmallVector< HoistingPointInfo, 4 > HoistingPointList
Definition GVNHoist.cpp:99
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1685
@ Unknown
Not known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto successors(const MachineBasicBlock *BB)
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
const ScalarOptions & getScalarOptions(const LLVMContext &C)
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
Definition STLExtras.h:2189
SmallVector< Instruction *, 4 > SmallVecInsn
Definition GVNHoist.cpp:93
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
SmallVectorImpl< CHIArg >::iterator CHIIt
Definition GVNHoist.cpp:129
DenseMap< VNType, SmallVector< Instruction *, 4 > > VNtoInsns
Definition GVNHoist.cpp:104
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
std::pair< unsigned, uintptr_t > VNType
Definition GVNHoist.cpp:102
IDFCalculator< true > ReverseIDFCalculator
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
std::pair< BasicBlock *, SmallVecInsn > HoistingPointInfo
Definition GVNHoist.cpp:97
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
Definition MemorySSA.cpp:76
idf_iterator< T > idf_end(const T &G)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI void combineMetadataForCSE(Instruction *K, const Instruction *J, bool DoesKMove)
Combine the metadata of two instructions so that K can replace J.
Definition Local.cpp:3126
DWARFExpression::Operation Op
idf_iterator< T > idf_begin(const T &G)
DenseMap< BasicBlock *, SmallVector< CHIArg, 2 > > OutValuesType
Definition GVNHoist.cpp:131
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
iterator_range< CHIIt > CHIArgs
Definition GVNHoist.cpp:130
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
DenseMap< const BasicBlock *, bool > BBSideEffectsSet
Definition GVNHoist.cpp:92
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
#define NC
Definition regutils.h:42
bool operator!=(const CHIArg &A) const
Definition GVNHoist.cpp:126
BasicBlock * Dest
Definition GVNHoist.cpp:120
Instruction * I
Definition GVNHoist.cpp:123
bool operator==(const CHIArg &A) const
Definition GVNHoist.cpp:125
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.