xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/GVN.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===- GVN.h - Eliminate redundant values and loads -------------*- C++ -*-===//
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 /// \file
9 /// This file provides the interface for LLVM's Global Value Numbering pass
10 /// which eliminates fully redundant instructions. It also does somewhat Ad-Hoc
11 /// PRE and dead load elimination.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_TRANSFORMS_SCALAR_GVN_H
16 #define LLVM_TRANSFORMS_SCALAR_GVN_H
17 
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/MapVector.h"
20 #include "llvm/ADT/SetVector.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/IR/Dominators.h"
23 #include "llvm/IR/InstrTypes.h"
24 #include "llvm/IR/PassManager.h"
25 #include "llvm/IR/ValueHandle.h"
26 #include "llvm/Support/Allocator.h"
27 #include "llvm/Support/Compiler.h"
28 #include <cstdint>
29 #include <optional>
30 #include <utility>
31 #include <vector>
32 
33 namespace llvm {
34 
35 class AAResults;
36 class AssumeInst;
37 class AssumptionCache;
38 class BasicBlock;
39 class BranchInst;
40 class CallInst;
41 class ExtractValueInst;
42 class Function;
43 class FunctionPass;
44 class GetElementPtrInst;
45 class ImplicitControlFlowTracking;
46 class LoadInst;
47 class LoopInfo;
48 class MemDepResult;
49 class MemoryDependenceResults;
50 class MemorySSA;
51 class MemorySSAUpdater;
52 class NonLocalDepResult;
53 class OptimizationRemarkEmitter;
54 class PHINode;
55 class TargetLibraryInfo;
56 class Value;
57 /// A private "module" namespace for types and utilities used by GVN. These
58 /// are implementation details and should not be used by clients.
59 namespace LLVM_LIBRARY_VISIBILITY gvn {
60 
61 struct AvailableValue;
62 struct AvailableValueInBlock;
63 class GVNLegacyPass;
64 
65 } // end namespace gvn
66 
67 /// A set of parameters to control various transforms performed by GVN pass.
68 //  Each of the optional boolean parameters can be set to:
69 ///      true - enabling the transformation.
70 ///      false - disabling the transformation.
71 ///      None - relying on a global default.
72 /// Intended use is to create a default object, modify parameters with
73 /// additional setters and then pass it to GVN.
74 struct GVNOptions {
75   std::optional<bool> AllowPRE;
76   std::optional<bool> AllowLoadPRE;
77   std::optional<bool> AllowLoadInLoopPRE;
78   std::optional<bool> AllowLoadPRESplitBackedge;
79   std::optional<bool> AllowMemDep;
80 
81   GVNOptions() = default;
82 
83   /// Enables or disables PRE in GVN.
setPREGVNOptions84   GVNOptions &setPRE(bool PRE) {
85     AllowPRE = PRE;
86     return *this;
87   }
88 
89   /// Enables or disables PRE of loads in GVN.
setLoadPREGVNOptions90   GVNOptions &setLoadPRE(bool LoadPRE) {
91     AllowLoadPRE = LoadPRE;
92     return *this;
93   }
94 
setLoadInLoopPREGVNOptions95   GVNOptions &setLoadInLoopPRE(bool LoadInLoopPRE) {
96     AllowLoadInLoopPRE = LoadInLoopPRE;
97     return *this;
98   }
99 
100   /// Enables or disables PRE of loads in GVN.
setLoadPRESplitBackedgeGVNOptions101   GVNOptions &setLoadPRESplitBackedge(bool LoadPRESplitBackedge) {
102     AllowLoadPRESplitBackedge = LoadPRESplitBackedge;
103     return *this;
104   }
105 
106   /// Enables or disables use of MemDepAnalysis.
setMemDepGVNOptions107   GVNOptions &setMemDep(bool MemDep) {
108     AllowMemDep = MemDep;
109     return *this;
110   }
111 };
112 
113 /// The core GVN pass object.
114 ///
115 /// FIXME: We should have a good summary of the GVN algorithm implemented by
116 /// this particular pass here.
117 class GVNPass : public PassInfoMixin<GVNPass> {
118   GVNOptions Options;
119 
120 public:
121   struct Expression;
122 
Options(Options)123   GVNPass(GVNOptions Options = {}) : Options(Options) {}
124 
125   /// Run the pass over the function.
126   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
127 
128   void printPipeline(raw_ostream &OS,
129                      function_ref<StringRef(StringRef)> MapClassName2PassName);
130 
131   /// This removes the specified instruction from
132   /// our various maps and marks it for deletion.
markInstructionForDeletion(Instruction * I)133   void markInstructionForDeletion(Instruction *I) {
134     VN.erase(I);
135     InstrsToErase.push_back(I);
136   }
137 
getDominatorTree()138   DominatorTree &getDominatorTree() const { return *DT; }
getAliasAnalysis()139   AAResults *getAliasAnalysis() const { return VN.getAliasAnalysis(); }
getMemDep()140   MemoryDependenceResults &getMemDep() const { return *MD; }
141 
142   bool isPREEnabled() const;
143   bool isLoadPREEnabled() const;
144   bool isLoadInLoopPREEnabled() const;
145   bool isLoadPRESplitBackedgeEnabled() const;
146   bool isMemDepEnabled() const;
147 
148   /// This class holds the mapping between values and value numbers.  It is used
149   /// as an efficient mechanism to determine the expression-wise equivalence of
150   /// two values.
151   class ValueTable {
152     DenseMap<Value *, uint32_t> valueNumbering;
153     DenseMap<Expression, uint32_t> expressionNumbering;
154 
155     // Expressions is the vector of Expression. ExprIdx is the mapping from
156     // value number to the index of Expression in Expressions. We use it
157     // instead of a DenseMap because filling such mapping is faster than
158     // filling a DenseMap and the compile time is a little better.
159     uint32_t nextExprNumber = 0;
160 
161     std::vector<Expression> Expressions;
162     std::vector<uint32_t> ExprIdx;
163 
164     // Value number to PHINode mapping. Used for phi-translate in scalarpre.
165     DenseMap<uint32_t, PHINode *> NumberingPhi;
166 
167     // Cache for phi-translate in scalarpre.
168     using PhiTranslateMap =
169         DenseMap<std::pair<uint32_t, const BasicBlock *>, uint32_t>;
170     PhiTranslateMap PhiTranslateTable;
171 
172     AAResults *AA = nullptr;
173     MemoryDependenceResults *MD = nullptr;
174     DominatorTree *DT = nullptr;
175 
176     uint32_t nextValueNumber = 1;
177 
178     Expression createExpr(Instruction *I);
179     Expression createCmpExpr(unsigned Opcode, CmpInst::Predicate Predicate,
180                              Value *LHS, Value *RHS);
181     Expression createExtractvalueExpr(ExtractValueInst *EI);
182     Expression createGEPExpr(GetElementPtrInst *GEP);
183     uint32_t lookupOrAddCall(CallInst *C);
184     uint32_t phiTranslateImpl(const BasicBlock *BB, const BasicBlock *PhiBlock,
185                               uint32_t Num, GVNPass &Gvn);
186     bool areCallValsEqual(uint32_t Num, uint32_t NewNum, const BasicBlock *Pred,
187                           const BasicBlock *PhiBlock, GVNPass &Gvn);
188     std::pair<uint32_t, bool> assignExpNewValueNum(Expression &exp);
189     bool areAllValsInBB(uint32_t num, const BasicBlock *BB, GVNPass &Gvn);
190 
191   public:
192     ValueTable();
193     ValueTable(const ValueTable &Arg);
194     ValueTable(ValueTable &&Arg);
195     ~ValueTable();
196     ValueTable &operator=(const ValueTable &Arg);
197 
198     uint32_t lookupOrAdd(Value *V);
199     uint32_t lookup(Value *V, bool Verify = true) const;
200     uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred,
201                             Value *LHS, Value *RHS);
202     uint32_t phiTranslate(const BasicBlock *BB, const BasicBlock *PhiBlock,
203                           uint32_t Num, GVNPass &Gvn);
204     void eraseTranslateCacheEntry(uint32_t Num, const BasicBlock &CurrBlock);
205     bool exists(Value *V) const;
206     void add(Value *V, uint32_t num);
207     void clear();
208     void erase(Value *v);
setAliasAnalysis(AAResults * A)209     void setAliasAnalysis(AAResults *A) { AA = A; }
getAliasAnalysis()210     AAResults *getAliasAnalysis() const { return AA; }
setMemDep(MemoryDependenceResults * M)211     void setMemDep(MemoryDependenceResults *M) { MD = M; }
setDomTree(DominatorTree * D)212     void setDomTree(DominatorTree *D) { DT = D; }
getNextUnusedValueNumber()213     uint32_t getNextUnusedValueNumber() { return nextValueNumber; }
214     void verifyRemoved(const Value *) const;
215   };
216 
217 private:
218   friend class gvn::GVNLegacyPass;
219   friend struct DenseMapInfo<Expression>;
220 
221   MemoryDependenceResults *MD = nullptr;
222   DominatorTree *DT = nullptr;
223   const TargetLibraryInfo *TLI = nullptr;
224   AssumptionCache *AC = nullptr;
225   SetVector<BasicBlock *> DeadBlocks;
226   OptimizationRemarkEmitter *ORE = nullptr;
227   ImplicitControlFlowTracking *ICF = nullptr;
228   LoopInfo *LI = nullptr;
229   MemorySSAUpdater *MSSAU = nullptr;
230 
231   ValueTable VN;
232 
233   /// A mapping from value numbers to lists of Value*'s that
234   /// have that value number.  Use findLeader to query it.
235   class LeaderMap {
236   public:
237     struct LeaderTableEntry {
238       Value *Val;
239       const BasicBlock *BB;
240     };
241 
242   private:
243     struct LeaderListNode {
244       LeaderTableEntry Entry;
245       LeaderListNode *Next;
246     };
247     DenseMap<uint32_t, LeaderListNode> NumToLeaders;
248     BumpPtrAllocator TableAllocator;
249 
250   public:
251     class leader_iterator {
252       const LeaderListNode *Current;
253 
254     public:
255       using iterator_category = std::forward_iterator_tag;
256       using value_type = const LeaderTableEntry;
257       using difference_type = std::ptrdiff_t;
258       using pointer = value_type *;
259       using reference = value_type &;
260 
261       leader_iterator(const LeaderListNode *C) : Current(C) {}
262       leader_iterator &operator++() {
263         assert(Current && "Dereferenced end of leader list!");
264         Current = Current->Next;
265         return *this;
266       }
267       bool operator==(const leader_iterator &Other) const {
268         return Current == Other.Current;
269       }
270       bool operator!=(const leader_iterator &Other) const {
271         return Current != Other.Current;
272       }
273       reference operator*() const { return Current->Entry; }
274     };
275 
276     iterator_range<leader_iterator> getLeaders(uint32_t N) {
277       auto I = NumToLeaders.find(N);
278       if (I == NumToLeaders.end()) {
279         return iterator_range(leader_iterator(nullptr),
280                               leader_iterator(nullptr));
281       }
282 
283       return iterator_range(leader_iterator(&I->second),
284                             leader_iterator(nullptr));
285     }
286 
287     void insert(uint32_t N, Value *V, const BasicBlock *BB);
288     void erase(uint32_t N, Instruction *I, const BasicBlock *BB);
289     void verifyRemoved(const Value *Inst) const;
290     void clear() {
291       NumToLeaders.clear();
292       TableAllocator.Reset();
293     }
294   };
295   LeaderMap LeaderTable;
296 
297   // Block-local map of equivalent values to their leader, does not
298   // propagate to any successors. Entries added mid-block are applied
299   // to the remaining instructions in the block.
300   SmallMapVector<Value *, Value *, 4> ReplaceOperandsWithMap;
301   SmallVector<Instruction *, 8> InstrsToErase;
302 
303   // Map the block to reversed postorder traversal number. It is used to
304   // find back edge easily.
305   DenseMap<AssertingVH<BasicBlock>, uint32_t> BlockRPONumber;
306 
307   // This is set 'true' initially and also when new blocks have been added to
308   // the function being analyzed. This boolean is used to control the updating
309   // of BlockRPONumber prior to accessing the contents of BlockRPONumber.
310   bool InvalidBlockRPONumbers = true;
311 
312   using LoadDepVect = SmallVector<NonLocalDepResult, 64>;
313   using AvailValInBlkVect = SmallVector<gvn::AvailableValueInBlock, 64>;
314   using UnavailBlkVect = SmallVector<BasicBlock *, 64>;
315 
316   bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
317                const TargetLibraryInfo &RunTLI, AAResults &RunAA,
318                MemoryDependenceResults *RunMD, LoopInfo &LI,
319                OptimizationRemarkEmitter *ORE, MemorySSA *MSSA = nullptr);
320 
321   // List of critical edges to be split between iterations.
322   SmallVector<std::pair<Instruction *, unsigned>, 4> toSplit;
323 
324   // Helper functions of redundant load elimination
325   bool processLoad(LoadInst *L);
326   bool processNonLocalLoad(LoadInst *L);
327   bool processAssumeIntrinsic(AssumeInst *II);
328 
329   /// Given a local dependency (Def or Clobber) determine if a value is
330   /// available for the load.
331   std::optional<gvn::AvailableValue>
332   AnalyzeLoadAvailability(LoadInst *Load, MemDepResult DepInfo, Value *Address);
333 
334   /// Given a list of non-local dependencies, determine if a value is
335   /// available for the load in each specified block.  If it is, add it to
336   /// ValuesPerBlock.  If not, add it to UnavailableBlocks.
337   void AnalyzeLoadAvailability(LoadInst *Load, LoadDepVect &Deps,
338                                AvailValInBlkVect &ValuesPerBlock,
339                                UnavailBlkVect &UnavailableBlocks);
340 
341   /// Given a critical edge from Pred to LoadBB, find a load instruction
342   /// which is identical to Load from another successor of Pred.
343   LoadInst *findLoadToHoistIntoPred(BasicBlock *Pred, BasicBlock *LoadBB,
344                                     LoadInst *Load);
345 
346   bool PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
347                       UnavailBlkVect &UnavailableBlocks);
348 
349   /// Try to replace a load which executes on each loop iteraiton with Phi
350   /// translation of load in preheader and load(s) in conditionally executed
351   /// paths.
352   bool performLoopLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
353                           UnavailBlkVect &UnavailableBlocks);
354 
355   /// Eliminates partially redundant \p Load, replacing it with \p
356   /// AvailableLoads (connected by Phis if needed).
357   void eliminatePartiallyRedundantLoad(
358       LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
359       MapVector<BasicBlock *, Value *> &AvailableLoads,
360       MapVector<BasicBlock *, LoadInst *> *CriticalEdgePredAndLoad);
361 
362   // Other helper routines
363   bool processInstruction(Instruction *I);
364   bool processBlock(BasicBlock *BB);
365   void dump(DenseMap<uint32_t, Value *> &d) const;
366   bool iterateOnFunction(Function &F);
367   bool performPRE(Function &F);
368   bool performScalarPRE(Instruction *I);
369   bool performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
370                                  BasicBlock *Curr, unsigned int ValNo);
371   Value *findLeader(const BasicBlock *BB, uint32_t num);
372   void cleanupGlobalSets();
373   void removeInstruction(Instruction *I);
374   void verifyRemoved(const Instruction *I) const;
375   bool splitCriticalEdges();
376   BasicBlock *splitCriticalEdges(BasicBlock *Pred, BasicBlock *Succ);
377   bool replaceOperandsForInBlockEquality(Instruction *I) const;
378   bool propagateEquality(Value *LHS, Value *RHS, const BasicBlockEdge &Root,
379                          bool DominatesByEdge);
380   bool processFoldableCondBr(BranchInst *BI);
381   void addDeadBlock(BasicBlock *BB);
382   void assignValNumForDeadCode();
383   void assignBlockRPONumber(Function &F);
384 };
385 
386 /// Create a legacy GVN pass. This also allows parameterizing whether or not
387 /// MemDep is enabled.
388 FunctionPass *createGVNPass(bool NoMemDepAnalysis = false);
389 
390 /// A simple and fast domtree-based GVN pass to hoist common expressions
391 /// from sibling branches.
392 struct GVNHoistPass : PassInfoMixin<GVNHoistPass> {
393   /// Run the pass over the function.
394   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
395 };
396 
397 /// Uses an "inverted" value numbering to decide the similarity of
398 /// expressions and sinks similar expressions into successors.
399 struct GVNSinkPass : PassInfoMixin<GVNSinkPass> {
400   /// Run the pass over the function.
401   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
402 };
403 
404 } // end namespace llvm
405 
406 #endif // LLVM_TRANSFORMS_SCALAR_GVN_H
407