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 840b57cec5SDimitry 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 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: 1190b57cec5SDimitry Andric LockstepReverseIterator(ArrayRef<BasicBlock *> Blocks) : Blocks(Blocks) { 1200b57cec5SDimitry Andric reset(); 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 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 1410b57cec5SDimitry Andric bool isValid() const { return !Fail; } 1420b57cec5SDimitry 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. 1500b57cec5SDimitry Andric SmallSetVector<BasicBlock *, 4> &getActiveBlocks() { return ActiveBlocks; } 1510b57cec5SDimitry Andric 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 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 1950b57cec5SDimitry 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 2040b57cec5SDimitry Andric bool operator>(const SinkingInstructionCandidate &Other) const { 2050b57cec5SDimitry Andric return Cost > Other.Cost; 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric }; 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric #ifndef NDEBUG 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 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! 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 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. 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. 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. 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 3150b57cec5SDimitry Andric ArrayRef<Value *> getValues() const { return Values; } 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric bool areAllIncomingValuesSame() const { 318bdd1243dSDimitry Andric return llvm::all_equal(Values); 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric 3210b57cec5SDimitry 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 3260b57cec5SDimitry 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 3310b57cec5SDimitry 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 3360b57cec5SDimitry 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 { 3420b57cec5SDimitry Andric static inline ModelledPHI &getEmptyKey() { 3430b57cec5SDimitry Andric static ModelledPHI Dummy = ModelledPHI::createDummy(0); 3440b57cec5SDimitry Andric return Dummy; 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric static inline ModelledPHI &getTombstoneKey() { 3480b57cec5SDimitry Andric static ModelledPHI Dummy = ModelledPHI::createDummy(1); 3490b57cec5SDimitry Andric return Dummy; 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric static unsigned getHashValue(const ModelledPHI &V) { return V.hash(); } 3530b57cec5SDimitry Andric 3540b57cec5SDimitry 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: 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 3950b57cec5SDimitry Andric void setMemoryUseOrder(unsigned MUO) { MemoryUseOrder = MUO; } 3960b57cec5SDimitry Andric void setVolatile(bool V) { Volatile = V; } 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric hash_code getHashValue() const override { 3990b57cec5SDimitry Andric return hash_combine(GVNExpression::BasicExpression::getHashValue(), 4005ffd83dbSDimitry Andric MemoryUseOrder, Volatile, ShuffleMask); 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 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(). 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. 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. 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. 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. 5530b57cec5SDimitry 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. 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. 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: 602*0fca6ea1SDimitry Andric GVNSink() {} 6030b57cec5SDimitry Andric 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 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. 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. 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> 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 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 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 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