1a686c60cSRoman Lebedev //===- DivRemPairs.cpp - Hoist/[dr]ecompose division and remainder --------===//
26fd4391dSSanjay Patel //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66fd4391dSSanjay Patel //
76fd4391dSSanjay Patel //===----------------------------------------------------------------------===//
86fd4391dSSanjay Patel //
9a686c60cSRoman Lebedev // This pass hoists and/or decomposes/recomposes integer division and remainder
106fd4391dSSanjay Patel // instructions to enable CFG improvements and better codegen.
116fd4391dSSanjay Patel //
126fd4391dSSanjay Patel //===----------------------------------------------------------------------===//
136fd4391dSSanjay Patel 
146fd4391dSSanjay Patel #include "llvm/Transforms/Scalar/DivRemPairs.h"
152af5f3c1SGeoff Berry #include "llvm/ADT/DenseMap.h"
162af5f3c1SGeoff Berry #include "llvm/ADT/MapVector.h"
176fd4391dSSanjay Patel #include "llvm/ADT/Statistic.h"
186fd4391dSSanjay Patel #include "llvm/Analysis/GlobalsModRef.h"
196fd4391dSSanjay Patel #include "llvm/Analysis/TargetTransformInfo.h"
206fd4391dSSanjay Patel #include "llvm/IR/Dominators.h"
216fd4391dSSanjay Patel #include "llvm/IR/Function.h"
22a686c60cSRoman Lebedev #include "llvm/IR/PatternMatch.h"
236fd4391dSSanjay Patel #include "llvm/Pass.h"
24213d1d23SGeorge Burgess IV #include "llvm/Support/DebugCounter.h"
256fd4391dSSanjay Patel #include "llvm/Transforms/Scalar.h"
266fd4391dSSanjay Patel #include "llvm/Transforms/Utils/BypassSlowDivision.h"
275f616901SRoman Lebedev 
286fd4391dSSanjay Patel using namespace llvm;
29a686c60cSRoman Lebedev using namespace llvm::PatternMatch;
306fd4391dSSanjay Patel 
316fd4391dSSanjay Patel #define DEBUG_TYPE "div-rem-pairs"
326fd4391dSSanjay Patel STATISTIC(NumPairs, "Number of div/rem pairs");
33a686c60cSRoman Lebedev STATISTIC(NumRecomposed, "Number of instructions recomposed");
346fd4391dSSanjay Patel STATISTIC(NumHoisted, "Number of instructions hoisted");
356fd4391dSSanjay Patel STATISTIC(NumDecomposed, "Number of instructions decomposed");
36213d1d23SGeorge Burgess IV DEBUG_COUNTER(DRPCounter, "div-rem-pairs-transform",
37213d1d23SGeorge Burgess IV               "Controls transformations in div-rem-pairs pass");
386fd4391dSSanjay Patel 
39a686c60cSRoman Lebedev namespace {
40a686c60cSRoman Lebedev struct ExpandedMatch {
41a686c60cSRoman Lebedev   DivRemMapKey Key;
42a686c60cSRoman Lebedev   Instruction *Value;
43a686c60cSRoman Lebedev };
44a686c60cSRoman Lebedev } // namespace
45a686c60cSRoman Lebedev 
46a686c60cSRoman Lebedev /// See if we can match: (which is the form we expand into)
47a686c60cSRoman Lebedev ///   X - ((X ?/ Y) * Y)
48a686c60cSRoman Lebedev /// which is equivalent to:
49a686c60cSRoman Lebedev ///   X ?% Y
50a686c60cSRoman Lebedev static llvm::Optional<ExpandedMatch> matchExpandedRem(Instruction &I) {
51a686c60cSRoman Lebedev   Value *Dividend, *XroundedDownToMultipleOfY;
52a686c60cSRoman Lebedev   if (!match(&I, m_Sub(m_Value(Dividend), m_Value(XroundedDownToMultipleOfY))))
53a686c60cSRoman Lebedev     return llvm::None;
54a686c60cSRoman Lebedev 
55a686c60cSRoman Lebedev   Value *Divisor;
56a686c60cSRoman Lebedev   Instruction *Div;
57a686c60cSRoman Lebedev   // Look for  ((X / Y) * Y)
58a686c60cSRoman Lebedev   if (!match(
59a686c60cSRoman Lebedev           XroundedDownToMultipleOfY,
60a686c60cSRoman Lebedev           m_c_Mul(m_CombineAnd(m_IDiv(m_Specific(Dividend), m_Value(Divisor)),
61a686c60cSRoman Lebedev                                m_Instruction(Div)),
62a686c60cSRoman Lebedev                   m_Deferred(Divisor))))
63a686c60cSRoman Lebedev     return llvm::None;
64a686c60cSRoman Lebedev 
65a686c60cSRoman Lebedev   ExpandedMatch M;
66a686c60cSRoman Lebedev   M.Key.SignedOp = Div->getOpcode() == Instruction::SDiv;
67a686c60cSRoman Lebedev   M.Key.Dividend = Dividend;
68a686c60cSRoman Lebedev   M.Key.Divisor = Divisor;
69a686c60cSRoman Lebedev   M.Value = &I;
70a686c60cSRoman Lebedev   return M;
71a686c60cSRoman Lebedev }
72a686c60cSRoman Lebedev 
735f616901SRoman Lebedev /// A thin wrapper to store two values that we matched as div-rem pair.
745f616901SRoman Lebedev /// We want this extra indirection to avoid dealing with RAUW'ing the map keys.
755f616901SRoman Lebedev struct DivRemPairWorklistEntry {
765f616901SRoman Lebedev   /// The actual udiv/sdiv instruction. Source of truth.
775f616901SRoman Lebedev   AssertingVH<Instruction> DivInst;
786fd4391dSSanjay Patel 
795f616901SRoman Lebedev   /// The instruction that we have matched as a remainder instruction.
805f616901SRoman Lebedev   /// Should only be used as Value, don't introspect it.
815f616901SRoman Lebedev   AssertingVH<Instruction> RemInst;
825f616901SRoman Lebedev 
835f616901SRoman Lebedev   DivRemPairWorklistEntry(Instruction *DivInst_, Instruction *RemInst_)
845f616901SRoman Lebedev       : DivInst(DivInst_), RemInst(RemInst_) {
855f616901SRoman Lebedev     assert((DivInst->getOpcode() == Instruction::UDiv ||
865f616901SRoman Lebedev             DivInst->getOpcode() == Instruction::SDiv) &&
875f616901SRoman Lebedev            "Not a division.");
885f616901SRoman Lebedev     assert(DivInst->getType() == RemInst->getType() && "Types should match.");
895f616901SRoman Lebedev     // We can't check anything else about remainder instruction,
905f616901SRoman Lebedev     // it's not strictly required to be a urem/srem.
915f616901SRoman Lebedev   }
925f616901SRoman Lebedev 
935f616901SRoman Lebedev   /// The type for this pair, identical for both the div and rem.
945f616901SRoman Lebedev   Type *getType() const { return DivInst->getType(); }
955f616901SRoman Lebedev 
965f616901SRoman Lebedev   /// Is this pair signed or unsigned?
975f616901SRoman Lebedev   bool isSigned() const { return DivInst->getOpcode() == Instruction::SDiv; }
985f616901SRoman Lebedev 
995f616901SRoman Lebedev   /// In this pair, what are the divident and divisor?
1005f616901SRoman Lebedev   Value *getDividend() const { return DivInst->getOperand(0); }
1015f616901SRoman Lebedev   Value *getDivisor() const { return DivInst->getOperand(1); }
102a686c60cSRoman Lebedev 
103a686c60cSRoman Lebedev   bool isRemExpanded() const {
104a686c60cSRoman Lebedev     switch (RemInst->getOpcode()) {
105a686c60cSRoman Lebedev     case Instruction::SRem:
106a686c60cSRoman Lebedev     case Instruction::URem:
107a686c60cSRoman Lebedev       return false; // single 'rem' instruction - unexpanded form.
108a686c60cSRoman Lebedev     default:
109a686c60cSRoman Lebedev       return true; // anything else means we have remainder in expanded form.
110a686c60cSRoman Lebedev     }
111a686c60cSRoman Lebedev   }
1125f616901SRoman Lebedev };
1135f616901SRoman Lebedev using DivRemWorklistTy = SmallVector<DivRemPairWorklistEntry, 4>;
1145f616901SRoman Lebedev 
1155f616901SRoman Lebedev /// Find matching pairs of integer div/rem ops (they have the same numerator,
1165f616901SRoman Lebedev /// denominator, and signedness). Place those pairs into a worklist for further
1175f616901SRoman Lebedev /// processing. This indirection is needed because we have to use TrackingVH<>
1185f616901SRoman Lebedev /// because we will be doing RAUW, and if one of the rem instructions we change
1195f616901SRoman Lebedev /// happens to be an input to another div/rem in the maps, we'd have problems.
1205f616901SRoman Lebedev static DivRemWorklistTy getWorklist(Function &F) {
1216fd4391dSSanjay Patel   // Insert all divide and remainder instructions into maps keyed by their
1226fd4391dSSanjay Patel   // operands and opcode (signed or unsigned).
1232af5f3c1SGeoff Berry   DenseMap<DivRemMapKey, Instruction *> DivMap;
1242af5f3c1SGeoff Berry   // Use a MapVector for RemMap so that instructions are moved/inserted in a
1252af5f3c1SGeoff Berry   // deterministic order.
1268e0cf076SRoman Lebedev   MapVector<DivRemMapKey, Instruction *> RemMap;
1276fd4391dSSanjay Patel   for (auto &BB : F) {
1286fd4391dSSanjay Patel     for (auto &I : BB) {
1296fd4391dSSanjay Patel       if (I.getOpcode() == Instruction::SDiv)
1306fd4391dSSanjay Patel         DivMap[DivRemMapKey(true, I.getOperand(0), I.getOperand(1))] = &I;
1316fd4391dSSanjay Patel       else if (I.getOpcode() == Instruction::UDiv)
1326fd4391dSSanjay Patel         DivMap[DivRemMapKey(false, I.getOperand(0), I.getOperand(1))] = &I;
1336fd4391dSSanjay Patel       else if (I.getOpcode() == Instruction::SRem)
1348e0cf076SRoman Lebedev         RemMap[DivRemMapKey(true, I.getOperand(0), I.getOperand(1))] = &I;
1356fd4391dSSanjay Patel       else if (I.getOpcode() == Instruction::URem)
1368e0cf076SRoman Lebedev         RemMap[DivRemMapKey(false, I.getOperand(0), I.getOperand(1))] = &I;
137a686c60cSRoman Lebedev       else if (auto Match = matchExpandedRem(I))
138a686c60cSRoman Lebedev         RemMap[Match->Key] = Match->Value;
1396fd4391dSSanjay Patel     }
1406fd4391dSSanjay Patel   }
1416fd4391dSSanjay Patel 
1425f616901SRoman Lebedev   // We'll accumulate the matching pairs of div-rem instructions here.
1435f616901SRoman Lebedev   DivRemWorklistTy Worklist;
1445f616901SRoman Lebedev 
1456fd4391dSSanjay Patel   // We can iterate over either map because we are only looking for matched
1466fd4391dSSanjay Patel   // pairs. Choose remainders for efficiency because they are usually even more
1476fd4391dSSanjay Patel   // rare than division.
1486fd4391dSSanjay Patel   for (auto &RemPair : RemMap) {
1496fd4391dSSanjay Patel     // Find the matching division instruction from the division map.
1502af5f3c1SGeoff Berry     Instruction *DivInst = DivMap[RemPair.first];
1516fd4391dSSanjay Patel     if (!DivInst)
1526fd4391dSSanjay Patel       continue;
1536fd4391dSSanjay Patel 
1545f616901SRoman Lebedev     // We have a matching pair of div/rem instructions.
1556fd4391dSSanjay Patel     NumPairs++;
1568e0cf076SRoman Lebedev     Instruction *RemInst = RemPair.second;
1575f616901SRoman Lebedev 
1585f616901SRoman Lebedev     // Place it in the worklist.
1595f616901SRoman Lebedev     Worklist.emplace_back(DivInst, RemInst);
1605f616901SRoman Lebedev   }
1615f616901SRoman Lebedev 
1625f616901SRoman Lebedev   return Worklist;
1635f616901SRoman Lebedev }
1645f616901SRoman Lebedev 
1655f616901SRoman Lebedev /// Find matching pairs of integer div/rem ops (they have the same numerator,
1665f616901SRoman Lebedev /// denominator, and signedness). If they exist in different basic blocks, bring
1675f616901SRoman Lebedev /// them together by hoisting or replace the common division operation that is
1685f616901SRoman Lebedev /// implicit in the remainder:
1695f616901SRoman Lebedev /// X % Y <--> X - ((X / Y) * Y).
1705f616901SRoman Lebedev ///
1715f616901SRoman Lebedev /// We can largely ignore the normal safety and cost constraints on speculation
1725f616901SRoman Lebedev /// of these ops when we find a matching pair. This is because we are already
1735f616901SRoman Lebedev /// guaranteed that any exceptions and most cost are already incurred by the
1745f616901SRoman Lebedev /// first member of the pair.
1755f616901SRoman Lebedev ///
1765f616901SRoman Lebedev /// Note: This transform could be an oddball enhancement to EarlyCSE, GVN, or
1775f616901SRoman Lebedev /// SimplifyCFG, but it's split off on its own because it's different enough
1785f616901SRoman Lebedev /// that it doesn't quite match the stated objectives of those passes.
1795f616901SRoman Lebedev static bool optimizeDivRem(Function &F, const TargetTransformInfo &TTI,
1805f616901SRoman Lebedev                            const DominatorTree &DT) {
1815f616901SRoman Lebedev   bool Changed = false;
1825f616901SRoman Lebedev 
1835f616901SRoman Lebedev   // Get the matching pairs of div-rem instructions. We want this extra
1845f616901SRoman Lebedev   // indirection to avoid dealing with having to RAUW the keys of the maps.
1855f616901SRoman Lebedev   DivRemWorklistTy Worklist = getWorklist(F);
1865f616901SRoman Lebedev 
1875f616901SRoman Lebedev   // Process each entry in the worklist.
1885f616901SRoman Lebedev   for (DivRemPairWorklistEntry &E : Worklist) {
189a686c60cSRoman Lebedev     if (!DebugCounter::shouldExecute(DRPCounter))
190a686c60cSRoman Lebedev       continue;
191a686c60cSRoman Lebedev 
1925f616901SRoman Lebedev     bool HasDivRemOp = TTI.hasDivRemOp(E.getType(), E.isSigned());
1935f616901SRoman Lebedev 
1945f616901SRoman Lebedev     auto &DivInst = E.DivInst;
1955f616901SRoman Lebedev     auto &RemInst = E.RemInst;
1966fd4391dSSanjay Patel 
197a686c60cSRoman Lebedev     const bool RemOriginallyWasInExpandedForm = E.isRemExpanded();
198*5e4e6b1fSRoman Lebedev     (void)RemOriginallyWasInExpandedForm; // suppress unused variable warning
199a686c60cSRoman Lebedev 
200a686c60cSRoman Lebedev     if (HasDivRemOp && E.isRemExpanded()) {
201a686c60cSRoman Lebedev       // The target supports div+rem but the rem is expanded.
202a686c60cSRoman Lebedev       // We should recompose it first.
203a686c60cSRoman Lebedev       Value *X = E.getDividend();
204a686c60cSRoman Lebedev       Value *Y = E.getDivisor();
205a686c60cSRoman Lebedev       Instruction *RealRem = E.isSigned() ? BinaryOperator::CreateSRem(X, Y)
206a686c60cSRoman Lebedev                                           : BinaryOperator::CreateURem(X, Y);
207a686c60cSRoman Lebedev       // Note that we place it right next to the original expanded instruction,
208a686c60cSRoman Lebedev       // and letting further handling to move it if needed.
209a686c60cSRoman Lebedev       RealRem->setName(RemInst->getName() + ".recomposed");
210a686c60cSRoman Lebedev       RealRem->insertAfter(RemInst);
211a686c60cSRoman Lebedev       Instruction *OrigRemInst = RemInst;
212a686c60cSRoman Lebedev       // Update AssertingVH<> with new instruction so it doesn't assert.
213a686c60cSRoman Lebedev       RemInst = RealRem;
214a686c60cSRoman Lebedev       // And replace the original instruction with the new one.
215a686c60cSRoman Lebedev       OrigRemInst->replaceAllUsesWith(RealRem);
216a686c60cSRoman Lebedev       OrigRemInst->eraseFromParent();
217a686c60cSRoman Lebedev       NumRecomposed++;
218a686c60cSRoman Lebedev       // Note that we have left ((X / Y) * Y) around.
219a686c60cSRoman Lebedev       // If it had other uses we could rewrite it as X - X % Y
220a686c60cSRoman Lebedev     }
221a686c60cSRoman Lebedev 
222a686c60cSRoman Lebedev     assert((!E.isRemExpanded() || !HasDivRemOp) &&
223a686c60cSRoman Lebedev            "*If* the target supports div-rem, then by now the RemInst *is* "
224a686c60cSRoman Lebedev            "Instruction::[US]Rem.");
225a686c60cSRoman Lebedev 
2266fd4391dSSanjay Patel     // If the target supports div+rem and the instructions are in the same block
2276fd4391dSSanjay Patel     // already, there's nothing to do. The backend should handle this. If the
2286fd4391dSSanjay Patel     // target does not support div+rem, then we will decompose the rem.
2296fd4391dSSanjay Patel     if (HasDivRemOp && RemInst->getParent() == DivInst->getParent())
2306fd4391dSSanjay Patel       continue;
2316fd4391dSSanjay Patel 
2326fd4391dSSanjay Patel     bool DivDominates = DT.dominates(DivInst, RemInst);
233a686c60cSRoman Lebedev     if (!DivDominates && !DT.dominates(RemInst, DivInst)) {
234a686c60cSRoman Lebedev       // We have matching div-rem pair, but they are in two different blocks,
235a686c60cSRoman Lebedev       // neither of which dominates one another.
236a686c60cSRoman Lebedev       assert(!RemOriginallyWasInExpandedForm &&
237a686c60cSRoman Lebedev              "Won't happen for expanded-form rem.");
238a686c60cSRoman Lebedev       // FIXME: We could hoist both ops to the common predecessor block?
2396fd4391dSSanjay Patel       continue;
240a686c60cSRoman Lebedev     }
2416fd4391dSSanjay Patel 
242a686c60cSRoman Lebedev     // The target does not have a single div/rem operation,
243a686c60cSRoman Lebedev     // and the rem is already in expanded form. Nothing to do.
244a686c60cSRoman Lebedev     if (!HasDivRemOp && E.isRemExpanded())
245213d1d23SGeorge Burgess IV       continue;
246213d1d23SGeorge Burgess IV 
2476fd4391dSSanjay Patel     if (HasDivRemOp) {
2486fd4391dSSanjay Patel       // The target has a single div/rem operation. Hoist the lower instruction
2496fd4391dSSanjay Patel       // to make the matched pair visible to the backend.
2506fd4391dSSanjay Patel       if (DivDominates)
2516fd4391dSSanjay Patel         RemInst->moveAfter(DivInst);
2526fd4391dSSanjay Patel       else
2536fd4391dSSanjay Patel         DivInst->moveAfter(RemInst);
2546fd4391dSSanjay Patel       NumHoisted++;
2556fd4391dSSanjay Patel     } else {
256a686c60cSRoman Lebedev       // The target does not have a single div/rem operation,
257a686c60cSRoman Lebedev       // and the rem is *not* in a already-expanded form.
258a686c60cSRoman Lebedev       // Decompose the remainder calculation as:
2596fd4391dSSanjay Patel       // X % Y --> X - ((X / Y) * Y).
260a686c60cSRoman Lebedev 
261a686c60cSRoman Lebedev       assert(!RemOriginallyWasInExpandedForm &&
262a686c60cSRoman Lebedev              "We should not be expanding if the rem was in expanded form to "
263a686c60cSRoman Lebedev              "begin with.");
264a686c60cSRoman Lebedev 
2655f616901SRoman Lebedev       Value *X = E.getDividend();
2665f616901SRoman Lebedev       Value *Y = E.getDivisor();
2676fd4391dSSanjay Patel       Instruction *Mul = BinaryOperator::CreateMul(DivInst, Y);
2686fd4391dSSanjay Patel       Instruction *Sub = BinaryOperator::CreateSub(X, Mul);
2696fd4391dSSanjay Patel 
2706fd4391dSSanjay Patel       // If the remainder dominates, then hoist the division up to that block:
2716fd4391dSSanjay Patel       //
2726fd4391dSSanjay Patel       // bb1:
2736fd4391dSSanjay Patel       //   %rem = srem %x, %y
2746fd4391dSSanjay Patel       // bb2:
2756fd4391dSSanjay Patel       //   %div = sdiv %x, %y
2766fd4391dSSanjay Patel       // -->
2776fd4391dSSanjay Patel       // bb1:
2786fd4391dSSanjay Patel       //   %div = sdiv %x, %y
2796fd4391dSSanjay Patel       //   %mul = mul %div, %y
2806fd4391dSSanjay Patel       //   %rem = sub %x, %mul
2816fd4391dSSanjay Patel       //
2826fd4391dSSanjay Patel       // If the division dominates, it's already in the right place. The mul+sub
2836fd4391dSSanjay Patel       // will be in a different block because we don't assume that they are
2846fd4391dSSanjay Patel       // cheap to speculatively execute:
2856fd4391dSSanjay Patel       //
2866fd4391dSSanjay Patel       // bb1:
2876fd4391dSSanjay Patel       //   %div = sdiv %x, %y
2886fd4391dSSanjay Patel       // bb2:
2896fd4391dSSanjay Patel       //   %rem = srem %x, %y
2906fd4391dSSanjay Patel       // -->
2916fd4391dSSanjay Patel       // bb1:
2926fd4391dSSanjay Patel       //   %div = sdiv %x, %y
2936fd4391dSSanjay Patel       // bb2:
2946fd4391dSSanjay Patel       //   %mul = mul %div, %y
2956fd4391dSSanjay Patel       //   %rem = sub %x, %mul
2966fd4391dSSanjay Patel       //
2976fd4391dSSanjay Patel       // If the div and rem are in the same block, we do the same transform,
2986fd4391dSSanjay Patel       // but any code movement would be within the same block.
2996fd4391dSSanjay Patel 
3006fd4391dSSanjay Patel       if (!DivDominates)
3016fd4391dSSanjay Patel         DivInst->moveBefore(RemInst);
3026fd4391dSSanjay Patel       Mul->insertAfter(RemInst);
3036fd4391dSSanjay Patel       Sub->insertAfter(Mul);
3046fd4391dSSanjay Patel 
3056fd4391dSSanjay Patel       // Now kill the explicit remainder. We have replaced it with:
3066fd4391dSSanjay Patel       // (sub X, (mul (div X, Y), Y)
3075f616901SRoman Lebedev       Sub->setName(RemInst->getName() + ".decomposed");
3085f616901SRoman Lebedev       Instruction *OrigRemInst = RemInst;
3095f616901SRoman Lebedev       // Update AssertingVH<> with new instruction so it doesn't assert.
3105f616901SRoman Lebedev       RemInst = Sub;
3115f616901SRoman Lebedev       // And replace the original instruction with the new one.
3125f616901SRoman Lebedev       OrigRemInst->replaceAllUsesWith(Sub);
3135f616901SRoman Lebedev       OrigRemInst->eraseFromParent();
3146fd4391dSSanjay Patel       NumDecomposed++;
3156fd4391dSSanjay Patel     }
3166fd4391dSSanjay Patel     Changed = true;
3176fd4391dSSanjay Patel   }
3186fd4391dSSanjay Patel 
3196fd4391dSSanjay Patel   return Changed;
3206fd4391dSSanjay Patel }
3216fd4391dSSanjay Patel 
3226fd4391dSSanjay Patel // Pass manager boilerplate below here.
3236fd4391dSSanjay Patel 
3246fd4391dSSanjay Patel namespace {
3256fd4391dSSanjay Patel struct DivRemPairsLegacyPass : public FunctionPass {
3266fd4391dSSanjay Patel   static char ID;
3276fd4391dSSanjay Patel   DivRemPairsLegacyPass() : FunctionPass(ID) {
3286fd4391dSSanjay Patel     initializeDivRemPairsLegacyPassPass(*PassRegistry::getPassRegistry());
3296fd4391dSSanjay Patel   }
3306fd4391dSSanjay Patel 
3316fd4391dSSanjay Patel   void getAnalysisUsage(AnalysisUsage &AU) const override {
3326fd4391dSSanjay Patel     AU.addRequired<DominatorTreeWrapperPass>();
3336fd4391dSSanjay Patel     AU.addRequired<TargetTransformInfoWrapperPass>();
3346fd4391dSSanjay Patel     AU.setPreservesCFG();
3356fd4391dSSanjay Patel     AU.addPreserved<DominatorTreeWrapperPass>();
3366fd4391dSSanjay Patel     AU.addPreserved<GlobalsAAWrapperPass>();
3376fd4391dSSanjay Patel     FunctionPass::getAnalysisUsage(AU);
3386fd4391dSSanjay Patel   }
3396fd4391dSSanjay Patel 
3406fd4391dSSanjay Patel   bool runOnFunction(Function &F) override {
3416fd4391dSSanjay Patel     if (skipFunction(F))
3426fd4391dSSanjay Patel       return false;
3436fd4391dSSanjay Patel     auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
3446fd4391dSSanjay Patel     auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
3456fd4391dSSanjay Patel     return optimizeDivRem(F, TTI, DT);
3466fd4391dSSanjay Patel   }
3476fd4391dSSanjay Patel };
3485f616901SRoman Lebedev } // namespace
3496fd4391dSSanjay Patel 
3506fd4391dSSanjay Patel char DivRemPairsLegacyPass::ID = 0;
3516fd4391dSSanjay Patel INITIALIZE_PASS_BEGIN(DivRemPairsLegacyPass, "div-rem-pairs",
3526fd4391dSSanjay Patel                       "Hoist/decompose integer division and remainder", false,
3536fd4391dSSanjay Patel                       false)
3546fd4391dSSanjay Patel INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
3556fd4391dSSanjay Patel INITIALIZE_PASS_END(DivRemPairsLegacyPass, "div-rem-pairs",
3566fd4391dSSanjay Patel                     "Hoist/decompose integer division and remainder", false,
3576fd4391dSSanjay Patel                     false)
3586fd4391dSSanjay Patel FunctionPass *llvm::createDivRemPairsPass() {
3596fd4391dSSanjay Patel   return new DivRemPairsLegacyPass();
3606fd4391dSSanjay Patel }
3616fd4391dSSanjay Patel 
3626fd4391dSSanjay Patel PreservedAnalyses DivRemPairsPass::run(Function &F,
3636fd4391dSSanjay Patel                                        FunctionAnalysisManager &FAM) {
3646fd4391dSSanjay Patel   TargetTransformInfo &TTI = FAM.getResult<TargetIRAnalysis>(F);
3656fd4391dSSanjay Patel   DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
3666fd4391dSSanjay Patel   if (!optimizeDivRem(F, TTI, DT))
3676fd4391dSSanjay Patel     return PreservedAnalyses::all();
3686fd4391dSSanjay Patel   // TODO: This pass just hoists/replaces math ops - all analyses are preserved?
3696fd4391dSSanjay Patel   PreservedAnalyses PA;
3706fd4391dSSanjay Patel   PA.preserveSet<CFGAnalyses>();
3716fd4391dSSanjay Patel   PA.preserve<GlobalsAA>();
3726fd4391dSSanjay Patel   return PA;
3736fd4391dSSanjay Patel }
374