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