xref: /freebsd/contrib/llvm-project/llvm/lib/Transforms/Scalar/GVNSink.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- GVNSink.cpp - sink expressions into successors ---------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric /// \file GVNSink.cpp
100b57cec5SDimitry Andric /// This pass attempts to sink instructions into successors, reducing static
110b57cec5SDimitry Andric /// instruction count and enabling if-conversion.
120b57cec5SDimitry Andric ///
130b57cec5SDimitry Andric /// We use a variant of global value numbering to decide what can be sunk.
140b57cec5SDimitry Andric /// Consider:
150b57cec5SDimitry Andric ///
160b57cec5SDimitry Andric /// [ %a1 = add i32 %b, 1  ]   [ %c1 = add i32 %d, 1  ]
170b57cec5SDimitry Andric /// [ %a2 = xor i32 %a1, 1 ]   [ %c2 = xor i32 %c1, 1 ]
180b57cec5SDimitry Andric ///                  \           /
190b57cec5SDimitry Andric ///            [ %e = phi i32 %a2, %c2 ]
200b57cec5SDimitry Andric ///            [ add i32 %e, 4         ]
210b57cec5SDimitry Andric ///
220b57cec5SDimitry Andric ///
230b57cec5SDimitry Andric /// GVN would number %a1 and %c1 differently because they compute different
240b57cec5SDimitry Andric /// results - the VN of an instruction is a function of its opcode and the
250b57cec5SDimitry Andric /// transitive closure of its operands. This is the key property for hoisting
260b57cec5SDimitry Andric /// and CSE.
270b57cec5SDimitry Andric ///
280b57cec5SDimitry Andric /// What we want when sinking however is for a numbering that is a function of
290b57cec5SDimitry Andric /// the *uses* of an instruction, which allows us to answer the question "if I
300b57cec5SDimitry Andric /// replace %a1 with %c1, will it contribute in an equivalent way to all
310b57cec5SDimitry Andric /// successive instructions?". The PostValueTable class in GVN provides this
320b57cec5SDimitry Andric /// mapping.
330b57cec5SDimitry Andric //
340b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
370b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
380b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h"
390b57cec5SDimitry Andric #include "llvm/ADT/Hashing.h"
400b57cec5SDimitry Andric #include "llvm/ADT/PostOrderIterator.h"
410b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
420b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
430b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
440b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
450b57cec5SDimitry Andric #include "llvm/Analysis/GlobalsModRef.h"
460b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
470b57cec5SDimitry Andric #include "llvm/IR/CFG.h"
480b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
490b57cec5SDimitry Andric #include "llvm/IR/Function.h"
500b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
510b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
520b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
530b57cec5SDimitry Andric #include "llvm/IR/PassManager.h"
540b57cec5SDimitry Andric #include "llvm/IR/Type.h"
550b57cec5SDimitry Andric #include "llvm/IR/Use.h"
560b57cec5SDimitry Andric #include "llvm/IR/Value.h"
570b57cec5SDimitry Andric #include "llvm/Support/Allocator.h"
580b57cec5SDimitry Andric #include "llvm/Support/ArrayRecycler.h"
590b57cec5SDimitry Andric #include "llvm/Support/AtomicOrdering.h"
600b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
610b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
620b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
630b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
640b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/GVN.h"
650b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/GVNExpression.h"
660b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h"
67480093f4SDimitry Andric #include "llvm/Transforms/Utils/Local.h"
680b57cec5SDimitry Andric #include <algorithm>
690b57cec5SDimitry Andric #include <cassert>
700b57cec5SDimitry Andric #include <cstddef>
710b57cec5SDimitry Andric #include <cstdint>
720b57cec5SDimitry Andric #include <iterator>
730b57cec5SDimitry Andric #include <utility>
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric using namespace llvm;
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric #define DEBUG_TYPE "gvn-sink"
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric STATISTIC(NumRemoved, "Number of instructions removed");
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric namespace llvm {
820b57cec5SDimitry Andric namespace GVNExpression {
830b57cec5SDimitry Andric 
dump() const840b57cec5SDimitry Andric LLVM_DUMP_METHOD void Expression::dump() const {
850b57cec5SDimitry Andric   print(dbgs());
860b57cec5SDimitry Andric   dbgs() << "\n";
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric } // end namespace GVNExpression
900b57cec5SDimitry Andric } // end namespace llvm
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric namespace {
930b57cec5SDimitry Andric 
isMemoryInst(const Instruction * I)940b57cec5SDimitry Andric static bool isMemoryInst(const Instruction *I) {
950b57cec5SDimitry Andric   return isa<LoadInst>(I) || isa<StoreInst>(I) ||
960b57cec5SDimitry Andric          (isa<InvokeInst>(I) && !cast<InvokeInst>(I)->doesNotAccessMemory()) ||
970b57cec5SDimitry Andric          (isa<CallInst>(I) && !cast<CallInst>(I)->doesNotAccessMemory());
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric /// Iterates through instructions in a set of blocks in reverse order from the
1010b57cec5SDimitry Andric /// first non-terminator. For example (assume all blocks have size n):
1020b57cec5SDimitry Andric ///   LockstepReverseIterator I([B1, B2, B3]);
1030b57cec5SDimitry Andric ///   *I-- = [B1[n], B2[n], B3[n]];
1040b57cec5SDimitry Andric ///   *I-- = [B1[n-1], B2[n-1], B3[n-1]];
1050b57cec5SDimitry Andric ///   *I-- = [B1[n-2], B2[n-2], B3[n-2]];
1060b57cec5SDimitry Andric ///   ...
1070b57cec5SDimitry Andric ///
1080b57cec5SDimitry Andric /// It continues until all blocks have been exhausted. Use \c getActiveBlocks()
1090b57cec5SDimitry Andric /// to
1100b57cec5SDimitry Andric /// determine which blocks are still going and the order they appear in the
1110b57cec5SDimitry Andric /// list returned by operator*.
1120b57cec5SDimitry Andric class LockstepReverseIterator {
1130b57cec5SDimitry Andric   ArrayRef<BasicBlock *> Blocks;
1140b57cec5SDimitry Andric   SmallSetVector<BasicBlock *, 4> ActiveBlocks;
1150b57cec5SDimitry Andric   SmallVector<Instruction *, 4> Insts;
1160b57cec5SDimitry Andric   bool Fail;
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric public:
LockstepReverseIterator(ArrayRef<BasicBlock * > Blocks)1190b57cec5SDimitry Andric   LockstepReverseIterator(ArrayRef<BasicBlock *> Blocks) : Blocks(Blocks) {
1200b57cec5SDimitry Andric     reset();
1210b57cec5SDimitry Andric   }
1220b57cec5SDimitry Andric 
reset()1230b57cec5SDimitry Andric   void reset() {
1240b57cec5SDimitry Andric     Fail = false;
1250b57cec5SDimitry Andric     ActiveBlocks.clear();
1260b57cec5SDimitry Andric     for (BasicBlock *BB : Blocks)
1270b57cec5SDimitry Andric       ActiveBlocks.insert(BB);
1280b57cec5SDimitry Andric     Insts.clear();
1290b57cec5SDimitry Andric     for (BasicBlock *BB : Blocks) {
1300b57cec5SDimitry Andric       if (BB->size() <= 1) {
1310b57cec5SDimitry Andric         // Block wasn't big enough - only contained a terminator.
1320b57cec5SDimitry Andric         ActiveBlocks.remove(BB);
1330b57cec5SDimitry Andric         continue;
1340b57cec5SDimitry Andric       }
135*0fca6ea1SDimitry Andric       Insts.push_back(BB->getTerminator()->getPrevNonDebugInstruction());
1360b57cec5SDimitry Andric     }
1370b57cec5SDimitry Andric     if (Insts.empty())
1380b57cec5SDimitry Andric       Fail = true;
1390b57cec5SDimitry Andric   }
1400b57cec5SDimitry Andric 
isValid() const1410b57cec5SDimitry Andric   bool isValid() const { return !Fail; }
operator *() const1420b57cec5SDimitry Andric   ArrayRef<Instruction *> operator*() const { return Insts; }
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   // Note: This needs to return a SmallSetVector as the elements of
1450b57cec5SDimitry Andric   // ActiveBlocks will be later copied to Blocks using std::copy. The
1460b57cec5SDimitry Andric   // resultant order of elements in Blocks needs to be deterministic.
1470b57cec5SDimitry Andric   // Using SmallPtrSet instead causes non-deterministic order while
1480b57cec5SDimitry Andric   // copying. And we cannot simply sort Blocks as they need to match the
1490b57cec5SDimitry Andric   // corresponding Values.
getActiveBlocks()1500b57cec5SDimitry Andric   SmallSetVector<BasicBlock *, 4> &getActiveBlocks() { return ActiveBlocks; }
1510b57cec5SDimitry Andric 
restrictToBlocks(SmallSetVector<BasicBlock *,4> & Blocks)1520b57cec5SDimitry Andric   void restrictToBlocks(SmallSetVector<BasicBlock *, 4> &Blocks) {
1530b57cec5SDimitry Andric     for (auto II = Insts.begin(); II != Insts.end();) {
15406c3fb27SDimitry Andric       if (!Blocks.contains((*II)->getParent())) {
1550b57cec5SDimitry Andric         ActiveBlocks.remove((*II)->getParent());
1560b57cec5SDimitry Andric         II = Insts.erase(II);
1570b57cec5SDimitry Andric       } else {
1580b57cec5SDimitry Andric         ++II;
1590b57cec5SDimitry Andric       }
1600b57cec5SDimitry Andric     }
1610b57cec5SDimitry Andric   }
1620b57cec5SDimitry Andric 
operator --()1630b57cec5SDimitry Andric   void operator--() {
1640b57cec5SDimitry Andric     if (Fail)
1650b57cec5SDimitry Andric       return;
1660b57cec5SDimitry Andric     SmallVector<Instruction *, 4> NewInsts;
1670b57cec5SDimitry Andric     for (auto *Inst : Insts) {
1680b57cec5SDimitry Andric       if (Inst == &Inst->getParent()->front())
1690b57cec5SDimitry Andric         ActiveBlocks.remove(Inst->getParent());
1700b57cec5SDimitry Andric       else
171*0fca6ea1SDimitry Andric         NewInsts.push_back(Inst->getPrevNonDebugInstruction());
1720b57cec5SDimitry Andric     }
1730b57cec5SDimitry Andric     if (NewInsts.empty()) {
1740b57cec5SDimitry Andric       Fail = true;
1750b57cec5SDimitry Andric       return;
1760b57cec5SDimitry Andric     }
1770b57cec5SDimitry Andric     Insts = NewInsts;
1780b57cec5SDimitry Andric   }
1790b57cec5SDimitry Andric };
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric /// Candidate solution for sinking. There may be different ways to
1840b57cec5SDimitry Andric /// sink instructions, differing in the number of instructions sunk,
1850b57cec5SDimitry Andric /// the number of predecessors sunk from and the number of PHIs
1860b57cec5SDimitry Andric /// required.
1870b57cec5SDimitry Andric struct SinkingInstructionCandidate {
1880b57cec5SDimitry Andric   unsigned NumBlocks;
1890b57cec5SDimitry Andric   unsigned NumInstructions;
1900b57cec5SDimitry Andric   unsigned NumPHIs;
1910b57cec5SDimitry Andric   unsigned NumMemoryInsts;
1920b57cec5SDimitry Andric   int Cost = -1;
1930b57cec5SDimitry Andric   SmallVector<BasicBlock *, 4> Blocks;
1940b57cec5SDimitry Andric 
calculateCost__anonac6bc9b30111::SinkingInstructionCandidate1950b57cec5SDimitry Andric   void calculateCost(unsigned NumOrigPHIs, unsigned NumOrigBlocks) {
1960b57cec5SDimitry Andric     unsigned NumExtraPHIs = NumPHIs - NumOrigPHIs;
1970b57cec5SDimitry Andric     unsigned SplitEdgeCost = (NumOrigBlocks > NumBlocks) ? 2 : 0;
1980b57cec5SDimitry Andric     Cost = (NumInstructions * (NumBlocks - 1)) -
1990b57cec5SDimitry Andric            (NumExtraPHIs *
2000b57cec5SDimitry Andric             NumExtraPHIs) // PHIs are expensive, so make sure they're worth it.
2010b57cec5SDimitry Andric            - SplitEdgeCost;
2020b57cec5SDimitry Andric   }
2030b57cec5SDimitry Andric 
operator >__anonac6bc9b30111::SinkingInstructionCandidate2040b57cec5SDimitry Andric   bool operator>(const SinkingInstructionCandidate &Other) const {
2050b57cec5SDimitry Andric     return Cost > Other.Cost;
2060b57cec5SDimitry Andric   }
2070b57cec5SDimitry Andric };
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric #ifndef NDEBUG
operator <<(raw_ostream & OS,const SinkingInstructionCandidate & C)2100b57cec5SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SinkingInstructionCandidate &C) {
2110b57cec5SDimitry Andric   OS << "<Candidate Cost=" << C.Cost << " #Blocks=" << C.NumBlocks
2120b57cec5SDimitry Andric      << " #Insts=" << C.NumInstructions << " #PHIs=" << C.NumPHIs << ">";
2130b57cec5SDimitry Andric   return OS;
2140b57cec5SDimitry Andric }
2150b57cec5SDimitry Andric #endif
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric /// Describes a PHI node that may or may not exist. These track the PHIs
2200b57cec5SDimitry Andric /// that must be created if we sunk a sequence of instructions. It provides
2210b57cec5SDimitry Andric /// a hash function for efficient equality comparisons.
2220b57cec5SDimitry Andric class ModelledPHI {
2230b57cec5SDimitry Andric   SmallVector<Value *, 4> Values;
2240b57cec5SDimitry Andric   SmallVector<BasicBlock *, 4> Blocks;
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric public:
2270b57cec5SDimitry Andric   ModelledPHI() = default;
2280b57cec5SDimitry Andric 
ModelledPHI(const PHINode * PN,const DenseMap<const BasicBlock *,unsigned> & BlockOrder)229*0fca6ea1SDimitry Andric   ModelledPHI(const PHINode *PN,
230*0fca6ea1SDimitry Andric               const DenseMap<const BasicBlock *, unsigned> &BlockOrder) {
231*0fca6ea1SDimitry Andric     // BasicBlock comes first so we sort by basic block pointer order,
232*0fca6ea1SDimitry Andric     // then by value pointer order. No need to call `verifyModelledPHI`
233*0fca6ea1SDimitry Andric     // As the Values and Blocks are populated in a deterministic order.
234*0fca6ea1SDimitry Andric     using OpsType = std::pair<BasicBlock *, Value *>;
235*0fca6ea1SDimitry Andric     SmallVector<OpsType, 4> Ops;
2360b57cec5SDimitry Andric     for (unsigned I = 0, E = PN->getNumIncomingValues(); I != E; ++I)
2370b57cec5SDimitry Andric       Ops.push_back({PN->getIncomingBlock(I), PN->getIncomingValue(I)});
238*0fca6ea1SDimitry Andric 
239*0fca6ea1SDimitry Andric     auto ComesBefore = [BlockOrder](OpsType O1, OpsType O2) {
240*0fca6ea1SDimitry Andric       return BlockOrder.lookup(O1.first) < BlockOrder.lookup(O2.first);
241*0fca6ea1SDimitry Andric     };
242*0fca6ea1SDimitry Andric     // Sort in a deterministic order.
243*0fca6ea1SDimitry Andric     llvm::sort(Ops, ComesBefore);
244*0fca6ea1SDimitry Andric 
2450b57cec5SDimitry Andric     for (auto &P : Ops) {
2460b57cec5SDimitry Andric       Blocks.push_back(P.first);
2470b57cec5SDimitry Andric       Values.push_back(P.second);
2480b57cec5SDimitry Andric     }
2490b57cec5SDimitry Andric   }
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   /// Create a dummy ModelledPHI that will compare unequal to any other ModelledPHI
2520b57cec5SDimitry Andric   /// without the same ID.
2530b57cec5SDimitry Andric   /// \note This is specifically for DenseMapInfo - do not use this!
createDummy(size_t ID)2540b57cec5SDimitry Andric   static ModelledPHI createDummy(size_t ID) {
2550b57cec5SDimitry Andric     ModelledPHI M;
2560b57cec5SDimitry Andric     M.Values.push_back(reinterpret_cast<Value*>(ID));
2570b57cec5SDimitry Andric     return M;
2580b57cec5SDimitry Andric   }
2590b57cec5SDimitry Andric 
260*0fca6ea1SDimitry Andric   void
verifyModelledPHI(const DenseMap<const BasicBlock *,unsigned> & BlockOrder)261*0fca6ea1SDimitry Andric   verifyModelledPHI(const DenseMap<const BasicBlock *, unsigned> &BlockOrder) {
262*0fca6ea1SDimitry Andric     assert(Values.size() > 1 && Blocks.size() > 1 &&
263*0fca6ea1SDimitry Andric            "Modelling PHI with less than 2 values");
264*0fca6ea1SDimitry Andric     auto ComesBefore = [BlockOrder](const BasicBlock *BB1,
265*0fca6ea1SDimitry Andric                                     const BasicBlock *BB2) {
266*0fca6ea1SDimitry Andric       return BlockOrder.lookup(BB1) < BlockOrder.lookup(BB2);
267*0fca6ea1SDimitry Andric     };
268*0fca6ea1SDimitry Andric     assert(llvm::is_sorted(Blocks, ComesBefore));
269*0fca6ea1SDimitry Andric     int C = 0;
270*0fca6ea1SDimitry Andric     for (const Value *V : Values) {
271*0fca6ea1SDimitry Andric       if (!isa<UndefValue>(V)) {
272*0fca6ea1SDimitry Andric         assert(cast<Instruction>(V)->getParent() == Blocks[C]);
273*0fca6ea1SDimitry Andric         (void)C;
274*0fca6ea1SDimitry Andric       }
275*0fca6ea1SDimitry Andric       C++;
276*0fca6ea1SDimitry Andric     }
277*0fca6ea1SDimitry Andric   }
2780b57cec5SDimitry Andric   /// Create a PHI from an array of incoming values and incoming blocks.
ModelledPHI(SmallVectorImpl<Instruction * > & V,SmallSetVector<BasicBlock *,4> & B,const DenseMap<const BasicBlock *,unsigned> & BlockOrder)279*0fca6ea1SDimitry Andric   ModelledPHI(SmallVectorImpl<Instruction *> &V,
280*0fca6ea1SDimitry Andric               SmallSetVector<BasicBlock *, 4> &B,
281*0fca6ea1SDimitry Andric               const DenseMap<const BasicBlock *, unsigned> &BlockOrder) {
282*0fca6ea1SDimitry Andric     // The order of Values and Blocks are already ordered by the caller.
2830b57cec5SDimitry Andric     llvm::copy(V, std::back_inserter(Values));
2840b57cec5SDimitry Andric     llvm::copy(B, std::back_inserter(Blocks));
285*0fca6ea1SDimitry Andric     verifyModelledPHI(BlockOrder);
2860b57cec5SDimitry Andric   }
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric   /// Create a PHI from [I[OpNum] for I in Insts].
289*0fca6ea1SDimitry Andric   /// TODO: Figure out a way to verifyModelledPHI in this constructor.
ModelledPHI(ArrayRef<Instruction * > Insts,unsigned OpNum,SmallSetVector<BasicBlock *,4> & B)290*0fca6ea1SDimitry Andric   ModelledPHI(ArrayRef<Instruction *> Insts, unsigned OpNum,
291*0fca6ea1SDimitry Andric               SmallSetVector<BasicBlock *, 4> &B) {
2920b57cec5SDimitry Andric     llvm::copy(B, std::back_inserter(Blocks));
2930b57cec5SDimitry Andric     for (auto *I : Insts)
2940b57cec5SDimitry Andric       Values.push_back(I->getOperand(OpNum));
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric   /// Restrict the PHI's contents down to only \c NewBlocks.
2980b57cec5SDimitry Andric   /// \c NewBlocks must be a subset of \c this->Blocks.
restrictToBlocks(const SmallSetVector<BasicBlock *,4> & NewBlocks)2990b57cec5SDimitry Andric   void restrictToBlocks(const SmallSetVector<BasicBlock *, 4> &NewBlocks) {
3000b57cec5SDimitry Andric     auto BI = Blocks.begin();
3010b57cec5SDimitry Andric     auto VI = Values.begin();
3020b57cec5SDimitry Andric     while (BI != Blocks.end()) {
3030b57cec5SDimitry Andric       assert(VI != Values.end());
30406c3fb27SDimitry Andric       if (!NewBlocks.contains(*BI)) {
3050b57cec5SDimitry Andric         BI = Blocks.erase(BI);
3060b57cec5SDimitry Andric         VI = Values.erase(VI);
3070b57cec5SDimitry Andric       } else {
3080b57cec5SDimitry Andric         ++BI;
3090b57cec5SDimitry Andric         ++VI;
3100b57cec5SDimitry Andric       }
3110b57cec5SDimitry Andric     }
3120b57cec5SDimitry Andric     assert(Blocks.size() == NewBlocks.size());
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric 
getValues() const3150b57cec5SDimitry Andric   ArrayRef<Value *> getValues() const { return Values; }
3160b57cec5SDimitry Andric 
areAllIncomingValuesSame() const3170b57cec5SDimitry Andric   bool areAllIncomingValuesSame() const {
318bdd1243dSDimitry Andric     return llvm::all_equal(Values);
3190b57cec5SDimitry Andric   }
3200b57cec5SDimitry Andric 
areAllIncomingValuesSameType() const3210b57cec5SDimitry Andric   bool areAllIncomingValuesSameType() const {
3220b57cec5SDimitry Andric     return llvm::all_of(
3230b57cec5SDimitry Andric         Values, [&](Value *V) { return V->getType() == Values[0]->getType(); });
3240b57cec5SDimitry Andric   }
3250b57cec5SDimitry Andric 
areAnyIncomingValuesConstant() const3260b57cec5SDimitry Andric   bool areAnyIncomingValuesConstant() const {
3270b57cec5SDimitry Andric     return llvm::any_of(Values, [&](Value *V) { return isa<Constant>(V); });
3280b57cec5SDimitry Andric   }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric   // Hash functor
hash() const3310b57cec5SDimitry Andric   unsigned hash() const {
332*0fca6ea1SDimitry Andric     // Is deterministic because Values are saved in a specific order.
3330b57cec5SDimitry Andric     return (unsigned)hash_combine_range(Values.begin(), Values.end());
3340b57cec5SDimitry Andric   }
3350b57cec5SDimitry Andric 
operator ==(const ModelledPHI & Other) const3360b57cec5SDimitry Andric   bool operator==(const ModelledPHI &Other) const {
3370b57cec5SDimitry Andric     return Values == Other.Values && Blocks == Other.Blocks;
3380b57cec5SDimitry Andric   }
3390b57cec5SDimitry Andric };
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric template <typename ModelledPHI> struct DenseMapInfo {
getEmptyKey__anonac6bc9b30111::DenseMapInfo3420b57cec5SDimitry Andric   static inline ModelledPHI &getEmptyKey() {
3430b57cec5SDimitry Andric     static ModelledPHI Dummy = ModelledPHI::createDummy(0);
3440b57cec5SDimitry Andric     return Dummy;
3450b57cec5SDimitry Andric   }
3460b57cec5SDimitry Andric 
getTombstoneKey__anonac6bc9b30111::DenseMapInfo3470b57cec5SDimitry Andric   static inline ModelledPHI &getTombstoneKey() {
3480b57cec5SDimitry Andric     static ModelledPHI Dummy = ModelledPHI::createDummy(1);
3490b57cec5SDimitry Andric     return Dummy;
3500b57cec5SDimitry Andric   }
3510b57cec5SDimitry Andric 
getHashValue__anonac6bc9b30111::DenseMapInfo3520b57cec5SDimitry Andric   static unsigned getHashValue(const ModelledPHI &V) { return V.hash(); }
3530b57cec5SDimitry Andric 
isEqual__anonac6bc9b30111::DenseMapInfo3540b57cec5SDimitry Andric   static bool isEqual(const ModelledPHI &LHS, const ModelledPHI &RHS) {
3550b57cec5SDimitry Andric     return LHS == RHS;
3560b57cec5SDimitry Andric   }
3570b57cec5SDimitry Andric };
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric using ModelledPHISet = DenseSet<ModelledPHI, DenseMapInfo<ModelledPHI>>;
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3620b57cec5SDimitry Andric //                             ValueTable
3630b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3640b57cec5SDimitry Andric // This is a value number table where the value number is a function of the
3650b57cec5SDimitry Andric // *uses* of a value, rather than its operands. Thus, if VN(A) == VN(B) we know
3660b57cec5SDimitry Andric // that the program would be equivalent if we replaced A with PHI(A, B).
3670b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric /// A GVN expression describing how an instruction is used. The operands
3700b57cec5SDimitry Andric /// field of BasicExpression is used to store uses, not operands.
3710b57cec5SDimitry Andric ///
3720b57cec5SDimitry Andric /// This class also contains fields for discriminators used when determining
3730b57cec5SDimitry Andric /// equivalence of instructions with sideeffects.
3740b57cec5SDimitry Andric class InstructionUseExpr : public GVNExpression::BasicExpression {
3750b57cec5SDimitry Andric   unsigned MemoryUseOrder = -1;
3760b57cec5SDimitry Andric   bool Volatile = false;
3775ffd83dbSDimitry Andric   ArrayRef<int> ShuffleMask;
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric public:
InstructionUseExpr(Instruction * I,ArrayRecycler<Value * > & R,BumpPtrAllocator & A)3800b57cec5SDimitry Andric   InstructionUseExpr(Instruction *I, ArrayRecycler<Value *> &R,
3810b57cec5SDimitry Andric                      BumpPtrAllocator &A)
3820b57cec5SDimitry Andric       : GVNExpression::BasicExpression(I->getNumUses()) {
3830b57cec5SDimitry Andric     allocateOperands(R, A);
3840b57cec5SDimitry Andric     setOpcode(I->getOpcode());
3850b57cec5SDimitry Andric     setType(I->getType());
3860b57cec5SDimitry Andric 
3875ffd83dbSDimitry Andric     if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(I))
3885ffd83dbSDimitry Andric       ShuffleMask = SVI->getShuffleMask().copy(A);
3895ffd83dbSDimitry Andric 
3900b57cec5SDimitry Andric     for (auto &U : I->uses())
3910b57cec5SDimitry Andric       op_push_back(U.getUser());
3920b57cec5SDimitry Andric     llvm::sort(op_begin(), op_end());
3930b57cec5SDimitry Andric   }
3940b57cec5SDimitry Andric 
setMemoryUseOrder(unsigned MUO)3950b57cec5SDimitry Andric   void setMemoryUseOrder(unsigned MUO) { MemoryUseOrder = MUO; }
setVolatile(bool V)3960b57cec5SDimitry Andric   void setVolatile(bool V) { Volatile = V; }
3970b57cec5SDimitry Andric 
getHashValue() const3980b57cec5SDimitry Andric   hash_code getHashValue() const override {
3990b57cec5SDimitry Andric     return hash_combine(GVNExpression::BasicExpression::getHashValue(),
4005ffd83dbSDimitry Andric                         MemoryUseOrder, Volatile, ShuffleMask);
4010b57cec5SDimitry Andric   }
4020b57cec5SDimitry Andric 
getHashValue(Function MapFn)4030b57cec5SDimitry Andric   template <typename Function> hash_code getHashValue(Function MapFn) {
4045ffd83dbSDimitry Andric     hash_code H = hash_combine(getOpcode(), getType(), MemoryUseOrder, Volatile,
4055ffd83dbSDimitry Andric                                ShuffleMask);
4060b57cec5SDimitry Andric     for (auto *V : operands())
4070b57cec5SDimitry Andric       H = hash_combine(H, MapFn(V));
4080b57cec5SDimitry Andric     return H;
4090b57cec5SDimitry Andric   }
4100b57cec5SDimitry Andric };
4110b57cec5SDimitry Andric 
41281ad6265SDimitry Andric using BasicBlocksSet = SmallPtrSet<const BasicBlock *, 32>;
41381ad6265SDimitry Andric 
4140b57cec5SDimitry Andric class ValueTable {
4150b57cec5SDimitry Andric   DenseMap<Value *, uint32_t> ValueNumbering;
4160b57cec5SDimitry Andric   DenseMap<GVNExpression::Expression *, uint32_t> ExpressionNumbering;
4170b57cec5SDimitry Andric   DenseMap<size_t, uint32_t> HashNumbering;
4180b57cec5SDimitry Andric   BumpPtrAllocator Allocator;
4190b57cec5SDimitry Andric   ArrayRecycler<Value *> Recycler;
4200b57cec5SDimitry Andric   uint32_t nextValueNumber = 1;
42181ad6265SDimitry Andric   BasicBlocksSet ReachableBBs;
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric   /// Create an expression for I based on its opcode and its uses. If I
4240b57cec5SDimitry Andric   /// touches or reads memory, the expression is also based upon its memory
4250b57cec5SDimitry Andric   /// order - see \c getMemoryUseOrder().
createExpr(Instruction * I)4260b57cec5SDimitry Andric   InstructionUseExpr *createExpr(Instruction *I) {
4270b57cec5SDimitry Andric     InstructionUseExpr *E =
4280b57cec5SDimitry Andric         new (Allocator) InstructionUseExpr(I, Recycler, Allocator);
4290b57cec5SDimitry Andric     if (isMemoryInst(I))
4300b57cec5SDimitry Andric       E->setMemoryUseOrder(getMemoryUseOrder(I));
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric     if (CmpInst *C = dyn_cast<CmpInst>(I)) {
4330b57cec5SDimitry Andric       CmpInst::Predicate Predicate = C->getPredicate();
4340b57cec5SDimitry Andric       E->setOpcode((C->getOpcode() << 8) | Predicate);
4350b57cec5SDimitry Andric     }
4360b57cec5SDimitry Andric     return E;
4370b57cec5SDimitry Andric   }
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric   /// Helper to compute the value number for a memory instruction
4400b57cec5SDimitry Andric   /// (LoadInst/StoreInst), including checking the memory ordering and
4410b57cec5SDimitry Andric   /// volatility.
createMemoryExpr(Inst * I)4420b57cec5SDimitry Andric   template <class Inst> InstructionUseExpr *createMemoryExpr(Inst *I) {
4430b57cec5SDimitry Andric     if (isStrongerThanUnordered(I->getOrdering()) || I->isAtomic())
4440b57cec5SDimitry Andric       return nullptr;
4450b57cec5SDimitry Andric     InstructionUseExpr *E = createExpr(I);
4460b57cec5SDimitry Andric     E->setVolatile(I->isVolatile());
4470b57cec5SDimitry Andric     return E;
4480b57cec5SDimitry Andric   }
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric public:
4510b57cec5SDimitry Andric   ValueTable() = default;
4520b57cec5SDimitry Andric 
45381ad6265SDimitry Andric   /// Set basic blocks reachable from entry block.
setReachableBBs(const BasicBlocksSet & ReachableBBs)45481ad6265SDimitry Andric   void setReachableBBs(const BasicBlocksSet &ReachableBBs) {
45581ad6265SDimitry Andric     this->ReachableBBs = ReachableBBs;
45681ad6265SDimitry Andric   }
45781ad6265SDimitry Andric 
4580b57cec5SDimitry Andric   /// Returns the value number for the specified value, assigning
4590b57cec5SDimitry Andric   /// it a new number if it did not have one before.
lookupOrAdd(Value * V)4600b57cec5SDimitry Andric   uint32_t lookupOrAdd(Value *V) {
4610b57cec5SDimitry Andric     auto VI = ValueNumbering.find(V);
4620b57cec5SDimitry Andric     if (VI != ValueNumbering.end())
4630b57cec5SDimitry Andric       return VI->second;
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric     if (!isa<Instruction>(V)) {
4660b57cec5SDimitry Andric       ValueNumbering[V] = nextValueNumber;
4670b57cec5SDimitry Andric       return nextValueNumber++;
4680b57cec5SDimitry Andric     }
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric     Instruction *I = cast<Instruction>(V);
47181ad6265SDimitry Andric     if (!ReachableBBs.contains(I->getParent()))
47281ad6265SDimitry Andric       return ~0U;
47381ad6265SDimitry Andric 
4740b57cec5SDimitry Andric     InstructionUseExpr *exp = nullptr;
4750b57cec5SDimitry Andric     switch (I->getOpcode()) {
4760b57cec5SDimitry Andric     case Instruction::Load:
4770b57cec5SDimitry Andric       exp = createMemoryExpr(cast<LoadInst>(I));
4780b57cec5SDimitry Andric       break;
4790b57cec5SDimitry Andric     case Instruction::Store:
4800b57cec5SDimitry Andric       exp = createMemoryExpr(cast<StoreInst>(I));
4810b57cec5SDimitry Andric       break;
4820b57cec5SDimitry Andric     case Instruction::Call:
4830b57cec5SDimitry Andric     case Instruction::Invoke:
4840b57cec5SDimitry Andric     case Instruction::FNeg:
4850b57cec5SDimitry Andric     case Instruction::Add:
4860b57cec5SDimitry Andric     case Instruction::FAdd:
4870b57cec5SDimitry Andric     case Instruction::Sub:
4880b57cec5SDimitry Andric     case Instruction::FSub:
4890b57cec5SDimitry Andric     case Instruction::Mul:
4900b57cec5SDimitry Andric     case Instruction::FMul:
4910b57cec5SDimitry Andric     case Instruction::UDiv:
4920b57cec5SDimitry Andric     case Instruction::SDiv:
4930b57cec5SDimitry Andric     case Instruction::FDiv:
4940b57cec5SDimitry Andric     case Instruction::URem:
4950b57cec5SDimitry Andric     case Instruction::SRem:
4960b57cec5SDimitry Andric     case Instruction::FRem:
4970b57cec5SDimitry Andric     case Instruction::Shl:
4980b57cec5SDimitry Andric     case Instruction::LShr:
4990b57cec5SDimitry Andric     case Instruction::AShr:
5000b57cec5SDimitry Andric     case Instruction::And:
5010b57cec5SDimitry Andric     case Instruction::Or:
5020b57cec5SDimitry Andric     case Instruction::Xor:
5030b57cec5SDimitry Andric     case Instruction::ICmp:
5040b57cec5SDimitry Andric     case Instruction::FCmp:
5050b57cec5SDimitry Andric     case Instruction::Trunc:
5060b57cec5SDimitry Andric     case Instruction::ZExt:
5070b57cec5SDimitry Andric     case Instruction::SExt:
5080b57cec5SDimitry Andric     case Instruction::FPToUI:
5090b57cec5SDimitry Andric     case Instruction::FPToSI:
5100b57cec5SDimitry Andric     case Instruction::UIToFP:
5110b57cec5SDimitry Andric     case Instruction::SIToFP:
5120b57cec5SDimitry Andric     case Instruction::FPTrunc:
5130b57cec5SDimitry Andric     case Instruction::FPExt:
5140b57cec5SDimitry Andric     case Instruction::PtrToInt:
5150b57cec5SDimitry Andric     case Instruction::IntToPtr:
5160b57cec5SDimitry Andric     case Instruction::BitCast:
5175ffd83dbSDimitry Andric     case Instruction::AddrSpaceCast:
5180b57cec5SDimitry Andric     case Instruction::Select:
5190b57cec5SDimitry Andric     case Instruction::ExtractElement:
5200b57cec5SDimitry Andric     case Instruction::InsertElement:
5210b57cec5SDimitry Andric     case Instruction::ShuffleVector:
5220b57cec5SDimitry Andric     case Instruction::InsertValue:
5230b57cec5SDimitry Andric     case Instruction::GetElementPtr:
5240b57cec5SDimitry Andric       exp = createExpr(I);
5250b57cec5SDimitry Andric       break;
5260b57cec5SDimitry Andric     default:
5270b57cec5SDimitry Andric       break;
5280b57cec5SDimitry Andric     }
5290b57cec5SDimitry Andric 
5300b57cec5SDimitry Andric     if (!exp) {
5310b57cec5SDimitry Andric       ValueNumbering[V] = nextValueNumber;
5320b57cec5SDimitry Andric       return nextValueNumber++;
5330b57cec5SDimitry Andric     }
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric     uint32_t e = ExpressionNumbering[exp];
5360b57cec5SDimitry Andric     if (!e) {
5370b57cec5SDimitry Andric       hash_code H = exp->getHashValue([=](Value *V) { return lookupOrAdd(V); });
5380b57cec5SDimitry Andric       auto I = HashNumbering.find(H);
5390b57cec5SDimitry Andric       if (I != HashNumbering.end()) {
5400b57cec5SDimitry Andric         e = I->second;
5410b57cec5SDimitry Andric       } else {
5420b57cec5SDimitry Andric         e = nextValueNumber++;
5430b57cec5SDimitry Andric         HashNumbering[H] = e;
5440b57cec5SDimitry Andric         ExpressionNumbering[exp] = e;
5450b57cec5SDimitry Andric       }
5460b57cec5SDimitry Andric     }
5470b57cec5SDimitry Andric     ValueNumbering[V] = e;
5480b57cec5SDimitry Andric     return e;
5490b57cec5SDimitry Andric   }
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric   /// Returns the value number of the specified value. Fails if the value has
5520b57cec5SDimitry Andric   /// not yet been numbered.
lookup(Value * V) const5530b57cec5SDimitry Andric   uint32_t lookup(Value *V) const {
5540b57cec5SDimitry Andric     auto VI = ValueNumbering.find(V);
5550b57cec5SDimitry Andric     assert(VI != ValueNumbering.end() && "Value not numbered?");
5560b57cec5SDimitry Andric     return VI->second;
5570b57cec5SDimitry Andric   }
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric   /// Removes all value numberings and resets the value table.
clear()5600b57cec5SDimitry Andric   void clear() {
5610b57cec5SDimitry Andric     ValueNumbering.clear();
5620b57cec5SDimitry Andric     ExpressionNumbering.clear();
5630b57cec5SDimitry Andric     HashNumbering.clear();
5640b57cec5SDimitry Andric     Recycler.clear(Allocator);
5650b57cec5SDimitry Andric     nextValueNumber = 1;
5660b57cec5SDimitry Andric   }
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   /// \c Inst uses or touches memory. Return an ID describing the memory state
5690b57cec5SDimitry Andric   /// at \c Inst such that if getMemoryUseOrder(I1) == getMemoryUseOrder(I2),
5700b57cec5SDimitry Andric   /// the exact same memory operations happen after I1 and I2.
5710b57cec5SDimitry Andric   ///
5720b57cec5SDimitry Andric   /// This is a very hard problem in general, so we use domain-specific
5730b57cec5SDimitry Andric   /// knowledge that we only ever check for equivalence between blocks sharing a
5740b57cec5SDimitry Andric   /// single immediate successor that is common, and when determining if I1 ==
5750b57cec5SDimitry Andric   /// I2 we will have already determined that next(I1) == next(I2). This
5760b57cec5SDimitry Andric   /// inductive property allows us to simply return the value number of the next
5770b57cec5SDimitry Andric   /// instruction that defines memory.
getMemoryUseOrder(Instruction * Inst)5780b57cec5SDimitry Andric   uint32_t getMemoryUseOrder(Instruction *Inst) {
5790b57cec5SDimitry Andric     auto *BB = Inst->getParent();
5800b57cec5SDimitry Andric     for (auto I = std::next(Inst->getIterator()), E = BB->end();
5810b57cec5SDimitry Andric          I != E && !I->isTerminator(); ++I) {
5820b57cec5SDimitry Andric       if (!isMemoryInst(&*I))
5830b57cec5SDimitry Andric         continue;
5840b57cec5SDimitry Andric       if (isa<LoadInst>(&*I))
5850b57cec5SDimitry Andric         continue;
5860b57cec5SDimitry Andric       CallInst *CI = dyn_cast<CallInst>(&*I);
5870b57cec5SDimitry Andric       if (CI && CI->onlyReadsMemory())
5880b57cec5SDimitry Andric         continue;
5890b57cec5SDimitry Andric       InvokeInst *II = dyn_cast<InvokeInst>(&*I);
5900b57cec5SDimitry Andric       if (II && II->onlyReadsMemory())
5910b57cec5SDimitry Andric         continue;
5920b57cec5SDimitry Andric       return lookupOrAdd(&*I);
5930b57cec5SDimitry Andric     }
5940b57cec5SDimitry Andric     return 0;
5950b57cec5SDimitry Andric   }
5960b57cec5SDimitry Andric };
5970b57cec5SDimitry Andric 
5980b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric class GVNSink {
6010b57cec5SDimitry Andric public:
GVNSink()602*0fca6ea1SDimitry Andric   GVNSink() {}
6030b57cec5SDimitry Andric 
run(Function & F)6040b57cec5SDimitry Andric   bool run(Function &F) {
6050b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "GVNSink: running on function @" << F.getName()
6060b57cec5SDimitry Andric                       << "\n");
6070b57cec5SDimitry Andric 
6080b57cec5SDimitry Andric     unsigned NumSunk = 0;
6090b57cec5SDimitry Andric     ReversePostOrderTraversal<Function*> RPOT(&F);
61081ad6265SDimitry Andric     VN.setReachableBBs(BasicBlocksSet(RPOT.begin(), RPOT.end()));
611*0fca6ea1SDimitry Andric     // Populate reverse post-order to order basic blocks in deterministic
612*0fca6ea1SDimitry Andric     // order. Any arbitrary ordering will work in this case as long as they are
613*0fca6ea1SDimitry Andric     // deterministic. The node ordering of newly created basic blocks
614*0fca6ea1SDimitry Andric     // are irrelevant because RPOT(for computing sinkable candidates) is also
615*0fca6ea1SDimitry Andric     // obtained ahead of time and only their order are relevant for this pass.
616*0fca6ea1SDimitry Andric     unsigned NodeOrdering = 0;
617*0fca6ea1SDimitry Andric     RPOTOrder[*RPOT.begin()] = ++NodeOrdering;
618*0fca6ea1SDimitry Andric     for (auto *BB : RPOT)
619*0fca6ea1SDimitry Andric       if (!pred_empty(BB))
620*0fca6ea1SDimitry Andric         RPOTOrder[BB] = ++NodeOrdering;
6210b57cec5SDimitry Andric     for (auto *N : RPOT)
6220b57cec5SDimitry Andric       NumSunk += sinkBB(N);
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric     return NumSunk > 0;
6250b57cec5SDimitry Andric   }
6260b57cec5SDimitry Andric 
6270b57cec5SDimitry Andric private:
6280b57cec5SDimitry Andric   ValueTable VN;
629*0fca6ea1SDimitry Andric   DenseMap<const BasicBlock *, unsigned> RPOTOrder;
6300b57cec5SDimitry Andric 
shouldAvoidSinkingInstruction(Instruction * I)6315ffd83dbSDimitry Andric   bool shouldAvoidSinkingInstruction(Instruction *I) {
6320b57cec5SDimitry Andric     // These instructions may change or break semantics if moved.
6330b57cec5SDimitry Andric     if (isa<PHINode>(I) || I->isEHPad() || isa<AllocaInst>(I) ||
6340b57cec5SDimitry Andric         I->getType()->isTokenTy())
6350b57cec5SDimitry Andric       return true;
6360b57cec5SDimitry Andric     return false;
6370b57cec5SDimitry Andric   }
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric   /// The main heuristic function. Analyze the set of instructions pointed to by
6400b57cec5SDimitry Andric   /// LRI and return a candidate solution if these instructions can be sunk, or
641bdd1243dSDimitry Andric   /// std::nullopt otherwise.
642bdd1243dSDimitry Andric   std::optional<SinkingInstructionCandidate> analyzeInstructionForSinking(
6430b57cec5SDimitry Andric       LockstepReverseIterator &LRI, unsigned &InstNum, unsigned &MemoryInstNum,
6440b57cec5SDimitry Andric       ModelledPHISet &NeededPHIs, SmallPtrSetImpl<Value *> &PHIContents);
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric   /// Create a ModelledPHI for each PHI in BB, adding to PHIs.
analyzeInitialPHIs(BasicBlock * BB,ModelledPHISet & PHIs,SmallPtrSetImpl<Value * > & PHIContents)6470b57cec5SDimitry Andric   void analyzeInitialPHIs(BasicBlock *BB, ModelledPHISet &PHIs,
6480b57cec5SDimitry Andric                           SmallPtrSetImpl<Value *> &PHIContents) {
6490b57cec5SDimitry Andric     for (PHINode &PN : BB->phis()) {
650*0fca6ea1SDimitry Andric       auto MPHI = ModelledPHI(&PN, RPOTOrder);
6510b57cec5SDimitry Andric       PHIs.insert(MPHI);
6520b57cec5SDimitry Andric       for (auto *V : MPHI.getValues())
6530b57cec5SDimitry Andric         PHIContents.insert(V);
6540b57cec5SDimitry Andric     }
6550b57cec5SDimitry Andric   }
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric   /// The main instruction sinking driver. Set up state and try and sink
6580b57cec5SDimitry Andric   /// instructions into BBEnd from its predecessors.
6590b57cec5SDimitry Andric   unsigned sinkBB(BasicBlock *BBEnd);
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric   /// Perform the actual mechanics of sinking an instruction from Blocks into
6620b57cec5SDimitry Andric   /// BBEnd, which is their only successor.
6630b57cec5SDimitry Andric   void sinkLastInstruction(ArrayRef<BasicBlock *> Blocks, BasicBlock *BBEnd);
6640b57cec5SDimitry Andric 
6650b57cec5SDimitry Andric   /// Remove PHIs that all have the same incoming value.
foldPointlessPHINodes(BasicBlock * BB)6660b57cec5SDimitry Andric   void foldPointlessPHINodes(BasicBlock *BB) {
6670b57cec5SDimitry Andric     auto I = BB->begin();
6680b57cec5SDimitry Andric     while (PHINode *PN = dyn_cast<PHINode>(I++)) {
6690b57cec5SDimitry Andric       if (!llvm::all_of(PN->incoming_values(), [&](const Value *V) {
6700b57cec5SDimitry Andric             return V == PN->getIncomingValue(0);
6710b57cec5SDimitry Andric           }))
6720b57cec5SDimitry Andric         continue;
6730b57cec5SDimitry Andric       if (PN->getIncomingValue(0) != PN)
6740b57cec5SDimitry Andric         PN->replaceAllUsesWith(PN->getIncomingValue(0));
6750b57cec5SDimitry Andric       else
676bdd1243dSDimitry Andric         PN->replaceAllUsesWith(PoisonValue::get(PN->getType()));
6770b57cec5SDimitry Andric       PN->eraseFromParent();
6780b57cec5SDimitry Andric     }
6790b57cec5SDimitry Andric   }
6800b57cec5SDimitry Andric };
6810b57cec5SDimitry Andric 
682bdd1243dSDimitry Andric std::optional<SinkingInstructionCandidate>
analyzeInstructionForSinking(LockstepReverseIterator & LRI,unsigned & InstNum,unsigned & MemoryInstNum,ModelledPHISet & NeededPHIs,SmallPtrSetImpl<Value * > & PHIContents)683bdd1243dSDimitry Andric GVNSink::analyzeInstructionForSinking(LockstepReverseIterator &LRI,
684bdd1243dSDimitry Andric                                       unsigned &InstNum,
685bdd1243dSDimitry Andric                                       unsigned &MemoryInstNum,
686bdd1243dSDimitry Andric                                       ModelledPHISet &NeededPHIs,
687bdd1243dSDimitry Andric                                       SmallPtrSetImpl<Value *> &PHIContents) {
6880b57cec5SDimitry Andric   auto Insts = *LRI;
6890b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << " -- Analyzing instruction set: [\n"; for (auto *I
6900b57cec5SDimitry Andric                                                                   : Insts) {
6910b57cec5SDimitry Andric     I->dump();
6920b57cec5SDimitry Andric   } dbgs() << " ]\n";);
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric   DenseMap<uint32_t, unsigned> VNums;
6950b57cec5SDimitry Andric   for (auto *I : Insts) {
6960b57cec5SDimitry Andric     uint32_t N = VN.lookupOrAdd(I);
6970b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << " VN=" << Twine::utohexstr(N) << " for" << *I << "\n");
6980b57cec5SDimitry Andric     if (N == ~0U)
699bdd1243dSDimitry Andric       return std::nullopt;
7000b57cec5SDimitry Andric     VNums[N]++;
7010b57cec5SDimitry Andric   }
702*0fca6ea1SDimitry Andric   unsigned VNumToSink = llvm::max_element(VNums, llvm::less_second())->first;
7030b57cec5SDimitry Andric 
7040b57cec5SDimitry Andric   if (VNums[VNumToSink] == 1)
7050b57cec5SDimitry Andric     // Can't sink anything!
706bdd1243dSDimitry Andric     return std::nullopt;
7070b57cec5SDimitry Andric 
7080b57cec5SDimitry Andric   // Now restrict the number of incoming blocks down to only those with
7090b57cec5SDimitry Andric   // VNumToSink.
7100b57cec5SDimitry Andric   auto &ActivePreds = LRI.getActiveBlocks();
7110b57cec5SDimitry Andric   unsigned InitialActivePredSize = ActivePreds.size();
7120b57cec5SDimitry Andric   SmallVector<Instruction *, 4> NewInsts;
7130b57cec5SDimitry Andric   for (auto *I : Insts) {
7140b57cec5SDimitry Andric     if (VN.lookup(I) != VNumToSink)
7150b57cec5SDimitry Andric       ActivePreds.remove(I->getParent());
7160b57cec5SDimitry Andric     else
7170b57cec5SDimitry Andric       NewInsts.push_back(I);
7180b57cec5SDimitry Andric   }
7190b57cec5SDimitry Andric   for (auto *I : NewInsts)
7205ffd83dbSDimitry Andric     if (shouldAvoidSinkingInstruction(I))
721bdd1243dSDimitry Andric       return std::nullopt;
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric   // If we've restricted the incoming blocks, restrict all needed PHIs also
7240b57cec5SDimitry Andric   // to that set.
7250b57cec5SDimitry Andric   bool RecomputePHIContents = false;
7260b57cec5SDimitry Andric   if (ActivePreds.size() != InitialActivePredSize) {
7270b57cec5SDimitry Andric     ModelledPHISet NewNeededPHIs;
7280b57cec5SDimitry Andric     for (auto P : NeededPHIs) {
7290b57cec5SDimitry Andric       P.restrictToBlocks(ActivePreds);
7300b57cec5SDimitry Andric       NewNeededPHIs.insert(P);
7310b57cec5SDimitry Andric     }
7320b57cec5SDimitry Andric     NeededPHIs = NewNeededPHIs;
7330b57cec5SDimitry Andric     LRI.restrictToBlocks(ActivePreds);
7340b57cec5SDimitry Andric     RecomputePHIContents = true;
7350b57cec5SDimitry Andric   }
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric   // The sunk instruction's results.
738*0fca6ea1SDimitry Andric   ModelledPHI NewPHI(NewInsts, ActivePreds, RPOTOrder);
7390b57cec5SDimitry Andric 
7400b57cec5SDimitry Andric   // Does sinking this instruction render previous PHIs redundant?
741e8d8bef9SDimitry Andric   if (NeededPHIs.erase(NewPHI))
7420b57cec5SDimitry Andric     RecomputePHIContents = true;
7430b57cec5SDimitry Andric 
7440b57cec5SDimitry Andric   if (RecomputePHIContents) {
7450b57cec5SDimitry Andric     // The needed PHIs have changed, so recompute the set of all needed
7460b57cec5SDimitry Andric     // values.
7470b57cec5SDimitry Andric     PHIContents.clear();
7480b57cec5SDimitry Andric     for (auto &PHI : NeededPHIs)
7490b57cec5SDimitry Andric       PHIContents.insert(PHI.getValues().begin(), PHI.getValues().end());
7500b57cec5SDimitry Andric   }
7510b57cec5SDimitry Andric 
7520b57cec5SDimitry Andric   // Is this instruction required by a later PHI that doesn't match this PHI?
7530b57cec5SDimitry Andric   // if so, we can't sink this instruction.
7540b57cec5SDimitry Andric   for (auto *V : NewPHI.getValues())
7550b57cec5SDimitry Andric     if (PHIContents.count(V))
7560b57cec5SDimitry Andric       // V exists in this PHI, but the whole PHI is different to NewPHI
7570b57cec5SDimitry Andric       // (else it would have been removed earlier). We cannot continue
7580b57cec5SDimitry Andric       // because this isn't representable.
759bdd1243dSDimitry Andric       return std::nullopt;
7600b57cec5SDimitry Andric 
7610b57cec5SDimitry Andric   // Which operands need PHIs?
7620b57cec5SDimitry Andric   // FIXME: If any of these fail, we should partition up the candidates to
7630b57cec5SDimitry Andric   // try and continue making progress.
7640b57cec5SDimitry Andric   Instruction *I0 = NewInsts[0];
7650b57cec5SDimitry Andric 
766*0fca6ea1SDimitry Andric   auto isNotSameOperation = [&I0](Instruction *I) {
767*0fca6ea1SDimitry Andric     return !I0->isSameOperationAs(I);
7680b57cec5SDimitry Andric   };
769*0fca6ea1SDimitry Andric 
770*0fca6ea1SDimitry Andric   if (any_of(NewInsts, isNotSameOperation))
771bdd1243dSDimitry Andric     return std::nullopt;
7720b57cec5SDimitry Andric 
7730b57cec5SDimitry Andric   for (unsigned OpNum = 0, E = I0->getNumOperands(); OpNum != E; ++OpNum) {
7740b57cec5SDimitry Andric     ModelledPHI PHI(NewInsts, OpNum, ActivePreds);
7750b57cec5SDimitry Andric     if (PHI.areAllIncomingValuesSame())
7760b57cec5SDimitry Andric       continue;
7770b57cec5SDimitry Andric     if (!canReplaceOperandWithVariable(I0, OpNum))
7780b57cec5SDimitry Andric       // We can 't create a PHI from this instruction!
779bdd1243dSDimitry Andric       return std::nullopt;
7800b57cec5SDimitry Andric     if (NeededPHIs.count(PHI))
7810b57cec5SDimitry Andric       continue;
7820b57cec5SDimitry Andric     if (!PHI.areAllIncomingValuesSameType())
783bdd1243dSDimitry Andric       return std::nullopt;
7840b57cec5SDimitry Andric     // Don't create indirect calls! The called value is the final operand.
7850b57cec5SDimitry Andric     if ((isa<CallInst>(I0) || isa<InvokeInst>(I0)) && OpNum == E - 1 &&
7860b57cec5SDimitry Andric         PHI.areAnyIncomingValuesConstant())
787bdd1243dSDimitry Andric       return std::nullopt;
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric     NeededPHIs.reserve(NeededPHIs.size());
7900b57cec5SDimitry Andric     NeededPHIs.insert(PHI);
7910b57cec5SDimitry Andric     PHIContents.insert(PHI.getValues().begin(), PHI.getValues().end());
7920b57cec5SDimitry Andric   }
7930b57cec5SDimitry Andric 
7940b57cec5SDimitry Andric   if (isMemoryInst(NewInsts[0]))
7950b57cec5SDimitry Andric     ++MemoryInstNum;
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric   SinkingInstructionCandidate Cand;
7980b57cec5SDimitry Andric   Cand.NumInstructions = ++InstNum;
7990b57cec5SDimitry Andric   Cand.NumMemoryInsts = MemoryInstNum;
8000b57cec5SDimitry Andric   Cand.NumBlocks = ActivePreds.size();
8010b57cec5SDimitry Andric   Cand.NumPHIs = NeededPHIs.size();
802e8d8bef9SDimitry Andric   append_range(Cand.Blocks, ActivePreds);
8030b57cec5SDimitry Andric 
8040b57cec5SDimitry Andric   return Cand;
8050b57cec5SDimitry Andric }
8060b57cec5SDimitry Andric 
sinkBB(BasicBlock * BBEnd)8070b57cec5SDimitry Andric unsigned GVNSink::sinkBB(BasicBlock *BBEnd) {
8080b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "GVNSink: running on basic block ";
8090b57cec5SDimitry Andric              BBEnd->printAsOperand(dbgs()); dbgs() << "\n");
8100b57cec5SDimitry Andric   SmallVector<BasicBlock *, 4> Preds;
8110b57cec5SDimitry Andric   for (auto *B : predecessors(BBEnd)) {
812*0fca6ea1SDimitry Andric     // Bailout on basic blocks without predecessor(PR42346).
813*0fca6ea1SDimitry Andric     if (!RPOTOrder.count(B))
814*0fca6ea1SDimitry Andric       return 0;
8150b57cec5SDimitry Andric     auto *T = B->getTerminator();
8160b57cec5SDimitry Andric     if (isa<BranchInst>(T) || isa<SwitchInst>(T))
8170b57cec5SDimitry Andric       Preds.push_back(B);
8180b57cec5SDimitry Andric     else
8190b57cec5SDimitry Andric       return 0;
8200b57cec5SDimitry Andric   }
8210b57cec5SDimitry Andric   if (Preds.size() < 2)
8220b57cec5SDimitry Andric     return 0;
823*0fca6ea1SDimitry Andric   auto ComesBefore = [this](const BasicBlock *BB1, const BasicBlock *BB2) {
824*0fca6ea1SDimitry Andric     return RPOTOrder.lookup(BB1) < RPOTOrder.lookup(BB2);
825*0fca6ea1SDimitry Andric   };
826*0fca6ea1SDimitry Andric   // Sort in a deterministic order.
827*0fca6ea1SDimitry Andric   llvm::sort(Preds, ComesBefore);
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric   unsigned NumOrigPreds = Preds.size();
8300b57cec5SDimitry Andric   // We can only sink instructions through unconditional branches.
83181ad6265SDimitry Andric   llvm::erase_if(Preds, [](BasicBlock *BB) {
83281ad6265SDimitry Andric     return BB->getTerminator()->getNumSuccessors() != 1;
83381ad6265SDimitry Andric   });
8340b57cec5SDimitry Andric 
8350b57cec5SDimitry Andric   LockstepReverseIterator LRI(Preds);
8360b57cec5SDimitry Andric   SmallVector<SinkingInstructionCandidate, 4> Candidates;
8370b57cec5SDimitry Andric   unsigned InstNum = 0, MemoryInstNum = 0;
8380b57cec5SDimitry Andric   ModelledPHISet NeededPHIs;
8390b57cec5SDimitry Andric   SmallPtrSet<Value *, 4> PHIContents;
8400b57cec5SDimitry Andric   analyzeInitialPHIs(BBEnd, NeededPHIs, PHIContents);
8410b57cec5SDimitry Andric   unsigned NumOrigPHIs = NeededPHIs.size();
8420b57cec5SDimitry Andric 
8430b57cec5SDimitry Andric   while (LRI.isValid()) {
8440b57cec5SDimitry Andric     auto Cand = analyzeInstructionForSinking(LRI, InstNum, MemoryInstNum,
8450b57cec5SDimitry Andric                                              NeededPHIs, PHIContents);
8460b57cec5SDimitry Andric     if (!Cand)
8470b57cec5SDimitry Andric       break;
8480b57cec5SDimitry Andric     Cand->calculateCost(NumOrigPHIs, Preds.size());
8490b57cec5SDimitry Andric     Candidates.emplace_back(*Cand);
8500b57cec5SDimitry Andric     --LRI;
8510b57cec5SDimitry Andric   }
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric   llvm::stable_sort(Candidates, std::greater<SinkingInstructionCandidate>());
8540b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << " -- Sinking candidates:\n"; for (auto &C
8550b57cec5SDimitry Andric                                                          : Candidates) dbgs()
8560b57cec5SDimitry Andric                                                     << "  " << C << "\n";);
8570b57cec5SDimitry Andric 
8580b57cec5SDimitry Andric   // Pick the top candidate, as long it is positive!
8590b57cec5SDimitry Andric   if (Candidates.empty() || Candidates.front().Cost <= 0)
8600b57cec5SDimitry Andric     return 0;
8610b57cec5SDimitry Andric   auto C = Candidates.front();
8620b57cec5SDimitry Andric 
8630b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << " -- Sinking: " << C << "\n");
8640b57cec5SDimitry Andric   BasicBlock *InsertBB = BBEnd;
8650b57cec5SDimitry Andric   if (C.Blocks.size() < NumOrigPreds) {
8660b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << " -- Splitting edge to ";
8670b57cec5SDimitry Andric                BBEnd->printAsOperand(dbgs()); dbgs() << "\n");
8680b57cec5SDimitry Andric     InsertBB = SplitBlockPredecessors(BBEnd, C.Blocks, ".gvnsink.split");
8690b57cec5SDimitry Andric     if (!InsertBB) {
8700b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << " -- FAILED to split edge!\n");
8710b57cec5SDimitry Andric       // Edge couldn't be split.
8720b57cec5SDimitry Andric       return 0;
8730b57cec5SDimitry Andric     }
8740b57cec5SDimitry Andric   }
8750b57cec5SDimitry Andric 
8760b57cec5SDimitry Andric   for (unsigned I = 0; I < C.NumInstructions; ++I)
8770b57cec5SDimitry Andric     sinkLastInstruction(C.Blocks, InsertBB);
8780b57cec5SDimitry Andric 
8790b57cec5SDimitry Andric   return C.NumInstructions;
8800b57cec5SDimitry Andric }
8810b57cec5SDimitry Andric 
sinkLastInstruction(ArrayRef<BasicBlock * > Blocks,BasicBlock * BBEnd)8820b57cec5SDimitry Andric void GVNSink::sinkLastInstruction(ArrayRef<BasicBlock *> Blocks,
8830b57cec5SDimitry Andric                                   BasicBlock *BBEnd) {
8840b57cec5SDimitry Andric   SmallVector<Instruction *, 4> Insts;
8850b57cec5SDimitry Andric   for (BasicBlock *BB : Blocks)
886*0fca6ea1SDimitry Andric     Insts.push_back(BB->getTerminator()->getPrevNonDebugInstruction());
8870b57cec5SDimitry Andric   Instruction *I0 = Insts.front();
8880b57cec5SDimitry Andric 
8890b57cec5SDimitry Andric   SmallVector<Value *, 4> NewOperands;
8900b57cec5SDimitry Andric   for (unsigned O = 0, E = I0->getNumOperands(); O != E; ++O) {
8910b57cec5SDimitry Andric     bool NeedPHI = llvm::any_of(Insts, [&I0, O](const Instruction *I) {
8920b57cec5SDimitry Andric       return I->getOperand(O) != I0->getOperand(O);
8930b57cec5SDimitry Andric     });
8940b57cec5SDimitry Andric     if (!NeedPHI) {
8950b57cec5SDimitry Andric       NewOperands.push_back(I0->getOperand(O));
8960b57cec5SDimitry Andric       continue;
8970b57cec5SDimitry Andric     }
8980b57cec5SDimitry Andric 
8990b57cec5SDimitry Andric     // Create a new PHI in the successor block and populate it.
9000b57cec5SDimitry Andric     auto *Op = I0->getOperand(O);
9010b57cec5SDimitry Andric     assert(!Op->getType()->isTokenTy() && "Can't PHI tokens!");
9025f757f3fSDimitry Andric     auto *PN =
9035f757f3fSDimitry Andric         PHINode::Create(Op->getType(), Insts.size(), Op->getName() + ".sink");
9045f757f3fSDimitry Andric     PN->insertBefore(BBEnd->begin());
9050b57cec5SDimitry Andric     for (auto *I : Insts)
9060b57cec5SDimitry Andric       PN->addIncoming(I->getOperand(O), I->getParent());
9070b57cec5SDimitry Andric     NewOperands.push_back(PN);
9080b57cec5SDimitry Andric   }
9090b57cec5SDimitry Andric 
9100b57cec5SDimitry Andric   // Arbitrarily use I0 as the new "common" instruction; remap its operands
9110b57cec5SDimitry Andric   // and move it to the start of the successor block.
9120b57cec5SDimitry Andric   for (unsigned O = 0, E = I0->getNumOperands(); O != E; ++O)
9130b57cec5SDimitry Andric     I0->getOperandUse(O).set(NewOperands[O]);
9140b57cec5SDimitry Andric   I0->moveBefore(&*BBEnd->getFirstInsertionPt());
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric   // Update metadata and IR flags.
9170b57cec5SDimitry Andric   for (auto *I : Insts)
9180b57cec5SDimitry Andric     if (I != I0) {
9190b57cec5SDimitry Andric       combineMetadataForCSE(I0, I, true);
9200b57cec5SDimitry Andric       I0->andIRFlags(I);
9210b57cec5SDimitry Andric     }
9220b57cec5SDimitry Andric 
9230b57cec5SDimitry Andric   for (auto *I : Insts)
924*0fca6ea1SDimitry Andric     if (I != I0) {
9250b57cec5SDimitry Andric       I->replaceAllUsesWith(I0);
926*0fca6ea1SDimitry Andric       I0->applyMergedLocation(I0->getDebugLoc(), I->getDebugLoc());
927*0fca6ea1SDimitry Andric     }
9280b57cec5SDimitry Andric   foldPointlessPHINodes(BBEnd);
9290b57cec5SDimitry Andric 
9300b57cec5SDimitry Andric   // Finally nuke all instructions apart from the common instruction.
9310b57cec5SDimitry Andric   for (auto *I : Insts)
9320b57cec5SDimitry Andric     if (I != I0)
9330b57cec5SDimitry Andric       I->eraseFromParent();
9340b57cec5SDimitry Andric 
9350b57cec5SDimitry Andric   NumRemoved += Insts.size() - 1;
9360b57cec5SDimitry Andric }
9370b57cec5SDimitry Andric 
9380b57cec5SDimitry Andric } // end anonymous namespace
9390b57cec5SDimitry Andric 
run(Function & F,FunctionAnalysisManager & AM)9400b57cec5SDimitry Andric PreservedAnalyses GVNSinkPass::run(Function &F, FunctionAnalysisManager &AM) {
9410b57cec5SDimitry Andric   GVNSink G;
9420b57cec5SDimitry Andric   if (!G.run(F))
9430b57cec5SDimitry Andric     return PreservedAnalyses::all();
944*0fca6ea1SDimitry Andric 
945fe6060f1SDimitry Andric   return PreservedAnalyses::none();
9460b57cec5SDimitry Andric }
947