LLVM API Documentation

AArch64AddressTypePromotion.cpp
Go to the documentation of this file.
00001 //===-- AArch64AddressTypePromotion.cpp --- Promote type for addr accesses -==//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This pass tries to promote the computations use to obtained a sign extended
00011 // value used into memory accesses.
00012 // E.g.
00013 // a = add nsw i32 b, 3
00014 // d = sext i32 a to i64
00015 // e = getelementptr ..., i64 d
00016 //
00017 // =>
00018 // f = sext i32 b to i64
00019 // a = add nsw i64 f, 3
00020 // e = getelementptr ..., i64 a
00021 //
00022 // This is legal to do if the computations are marked with either nsw or nuw
00023 // markers.
00024 // Moreover, the current heuristic is simple: it does not create new sext
00025 // operations, i.e., it gives up when a sext would have forked (e.g., if
00026 // a = add i32 b, c, two sexts are required to promote the computation).
00027 //
00028 // FIXME: This pass may be useful for other targets too.
00029 // ===---------------------------------------------------------------------===//
00030 
00031 #include "AArch64.h"
00032 #include "llvm/ADT/DenseMap.h"
00033 #include "llvm/ADT/SmallPtrSet.h"
00034 #include "llvm/ADT/SmallVector.h"
00035 #include "llvm/IR/Constants.h"
00036 #include "llvm/IR/Dominators.h"
00037 #include "llvm/IR/Function.h"
00038 #include "llvm/IR/Instructions.h"
00039 #include "llvm/IR/Module.h"
00040 #include "llvm/IR/Operator.h"
00041 #include "llvm/Pass.h"
00042 #include "llvm/Support/CommandLine.h"
00043 #include "llvm/Support/Debug.h"
00044 
00045 using namespace llvm;
00046 
00047 #define DEBUG_TYPE "aarch64-type-promotion"
00048 
00049 static cl::opt<bool>
00050 EnableAddressTypePromotion("aarch64-type-promotion", cl::Hidden,
00051                            cl::desc("Enable the type promotion pass"),
00052                            cl::init(true));
00053 static cl::opt<bool>
00054 EnableMerge("aarch64-type-promotion-merge", cl::Hidden,
00055             cl::desc("Enable merging of redundant sexts when one is dominating"
00056                      " the other."),
00057             cl::init(true));
00058 
00059 //===----------------------------------------------------------------------===//
00060 //                       AArch64AddressTypePromotion
00061 //===----------------------------------------------------------------------===//
00062 
00063 namespace llvm {
00064 void initializeAArch64AddressTypePromotionPass(PassRegistry &);
00065 }
00066 
00067 namespace {
00068 class AArch64AddressTypePromotion : public FunctionPass {
00069 
00070 public:
00071   static char ID;
00072   AArch64AddressTypePromotion()
00073       : FunctionPass(ID), Func(nullptr), ConsideredSExtType(nullptr) {
00074     initializeAArch64AddressTypePromotionPass(*PassRegistry::getPassRegistry());
00075   }
00076 
00077   const char *getPassName() const override {
00078     return "AArch64 Address Type Promotion";
00079   }
00080 
00081   /// Iterate over the functions and promote the computation of interesting
00082   // sext instructions.
00083   bool runOnFunction(Function &F) override;
00084 
00085 private:
00086   /// The current function.
00087   Function *Func;
00088   /// Filter out all sexts that does not have this type.
00089   /// Currently initialized with Int64Ty.
00090   Type *ConsideredSExtType;
00091 
00092   // This transformation requires dominator info.
00093   void getAnalysisUsage(AnalysisUsage &AU) const override {
00094     AU.setPreservesCFG();
00095     AU.addRequired<DominatorTreeWrapperPass>();
00096     AU.addPreserved<DominatorTreeWrapperPass>();
00097     FunctionPass::getAnalysisUsage(AU);
00098   }
00099 
00100   typedef SmallPtrSet<Instruction *, 32> SetOfInstructions;
00101   typedef SmallVector<Instruction *, 16> Instructions;
00102   typedef DenseMap<Value *, Instructions> ValueToInsts;
00103 
00104   /// Check if it is profitable to move a sext through this instruction.
00105   /// Currently, we consider it is profitable if:
00106   /// - Inst is used only once (no need to insert truncate).
00107   /// - Inst has only one operand that will require a sext operation (we do
00108   ///   do not create new sext operation).
00109   bool shouldGetThrough(const Instruction *Inst);
00110 
00111   /// Check if it is possible and legal to move a sext through this
00112   /// instruction.
00113   /// Current heuristic considers that we can get through:
00114   /// - Arithmetic operation marked with the nsw or nuw flag.
00115   /// - Other sext operation.
00116   /// - Truncate operation if it was just dropping sign extended bits.
00117   bool canGetThrough(const Instruction *Inst);
00118 
00119   /// Move sext operations through safe to sext instructions.
00120   bool propagateSignExtension(Instructions &SExtInsts);
00121 
00122   /// Is this sext should be considered for code motion.
00123   /// We look for sext with ConsideredSExtType and uses in at least one
00124   // GetElementPtrInst.
00125   bool shouldConsiderSExt(const Instruction *SExt) const;
00126 
00127   /// Collect all interesting sext operations, i.e., the ones with the right
00128   /// type and used in memory accesses.
00129   /// More precisely, a sext instruction is considered as interesting if it
00130   /// is used in a "complex" getelementptr or it exits at least another
00131   /// sext instruction that sign extended the same initial value.
00132   /// A getelementptr is considered as "complex" if it has more than 2
00133   // operands.
00134   void analyzeSExtension(Instructions &SExtInsts);
00135 
00136   /// Merge redundant sign extension operations in common dominator.
00137   void mergeSExts(ValueToInsts &ValToSExtendedUses,
00138                   SetOfInstructions &ToRemove);
00139 };
00140 } // end anonymous namespace.
00141 
00142 char AArch64AddressTypePromotion::ID = 0;
00143 
00144 INITIALIZE_PASS_BEGIN(AArch64AddressTypePromotion, "aarch64-type-promotion",
00145                       "AArch64 Type Promotion Pass", false, false)
00146 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
00147 INITIALIZE_PASS_END(AArch64AddressTypePromotion, "aarch64-type-promotion",
00148                     "AArch64 Type Promotion Pass", false, false)
00149 
00150 FunctionPass *llvm::createAArch64AddressTypePromotionPass() {
00151   return new AArch64AddressTypePromotion();
00152 }
00153 
00154 bool AArch64AddressTypePromotion::canGetThrough(const Instruction *Inst) {
00155   if (isa<SExtInst>(Inst))
00156     return true;
00157 
00158   const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Inst);
00159   if (BinOp && isa<OverflowingBinaryOperator>(BinOp) &&
00160       (BinOp->hasNoUnsignedWrap() || BinOp->hasNoSignedWrap()))
00161     return true;
00162 
00163   // sext(trunc(sext)) --> sext
00164   if (isa<TruncInst>(Inst) && isa<SExtInst>(Inst->getOperand(0))) {
00165     const Instruction *Opnd = cast<Instruction>(Inst->getOperand(0));
00166     // Check that the truncate just drop sign extended bits.
00167     if (Inst->getType()->getIntegerBitWidth() >=
00168             Opnd->getOperand(0)->getType()->getIntegerBitWidth() &&
00169         Inst->getOperand(0)->getType()->getIntegerBitWidth() <=
00170             ConsideredSExtType->getIntegerBitWidth())
00171       return true;
00172   }
00173 
00174   return false;
00175 }
00176 
00177 bool AArch64AddressTypePromotion::shouldGetThrough(const Instruction *Inst) {
00178   // If the type of the sext is the same as the considered one, this sext
00179   // will become useless.
00180   // Otherwise, we will have to do something to preserve the original value,
00181   // unless it is used once.
00182   if (isa<SExtInst>(Inst) &&
00183       (Inst->getType() == ConsideredSExtType || Inst->hasOneUse()))
00184     return true;
00185 
00186   // If the Inst is used more that once, we may need to insert truncate
00187   // operations and we don't do that at the moment.
00188   if (!Inst->hasOneUse())
00189     return false;
00190 
00191   // This truncate is used only once, thus if we can get thourgh, it will become
00192   // useless.
00193   if (isa<TruncInst>(Inst))
00194     return true;
00195 
00196   // If both operands are not constant, a new sext will be created here.
00197   // Current heuristic is: each step should be profitable.
00198   // Therefore we don't allow to increase the number of sext even if it may
00199   // be profitable later on.
00200   if (isa<BinaryOperator>(Inst) && isa<ConstantInt>(Inst->getOperand(1)))
00201     return true;
00202 
00203   return false;
00204 }
00205 
00206 static bool shouldSExtOperand(const Instruction *Inst, int OpIdx) {
00207   if (isa<SelectInst>(Inst) && OpIdx == 0)
00208     return false;
00209   return true;
00210 }
00211 
00212 bool
00213 AArch64AddressTypePromotion::shouldConsiderSExt(const Instruction *SExt) const {
00214   if (SExt->getType() != ConsideredSExtType)
00215     return false;
00216 
00217   for (const User *U : SExt->users()) {
00218     if (isa<GetElementPtrInst>(U))
00219       return true;
00220   }
00221 
00222   return false;
00223 }
00224 
00225 // Input:
00226 // - SExtInsts contains all the sext instructions that are used directly in
00227 //   GetElementPtrInst, i.e., access to memory.
00228 // Algorithm:
00229 // - For each sext operation in SExtInsts:
00230 //   Let var be the operand of sext.
00231 //   while it is profitable (see shouldGetThrough), legal, and safe
00232 //   (see canGetThrough) to move sext through var's definition:
00233 //   * promote the type of var's definition.
00234 //   * fold var into sext uses.
00235 //   * move sext above var's definition.
00236 //   * update sext operand to use the operand of var that should be sign
00237 //     extended (by construction there is only one).
00238 //
00239 //   E.g.,
00240 //   a = ... i32 c, 3
00241 //   b = sext i32 a to i64 <- is it legal/safe/profitable to get through 'a'
00242 //   ...
00243 //   = b
00244 // => Yes, update the code
00245 //   b = sext i32 c to i64
00246 //   a = ... i64 b, 3
00247 //   ...
00248 //   = a
00249 // Iterate on 'c'.
00250 bool
00251 AArch64AddressTypePromotion::propagateSignExtension(Instructions &SExtInsts) {
00252   DEBUG(dbgs() << "*** Propagate Sign Extension ***\n");
00253 
00254   bool LocalChange = false;
00255   SetOfInstructions ToRemove;
00256   ValueToInsts ValToSExtendedUses;
00257   while (!SExtInsts.empty()) {
00258     // Get through simple chain.
00259     Instruction *SExt = SExtInsts.pop_back_val();
00260 
00261     DEBUG(dbgs() << "Consider:\n" << *SExt << '\n');
00262 
00263     // If this SExt has already been merged continue.
00264     if (SExt->use_empty() && ToRemove.count(SExt)) {
00265       DEBUG(dbgs() << "No uses => marked as delete\n");
00266       continue;
00267     }
00268 
00269     // Now try to get through the chain of definitions.
00270     while (auto *Inst = dyn_cast<Instruction>(SExt->getOperand(0))) {
00271       DEBUG(dbgs() << "Try to get through:\n" << *Inst << '\n');
00272       if (!canGetThrough(Inst) || !shouldGetThrough(Inst)) {
00273         // We cannot get through something that is not an Instruction
00274         // or not safe to SExt.
00275         DEBUG(dbgs() << "Cannot get through\n");
00276         break;
00277       }
00278 
00279       LocalChange = true;
00280       // If this is a sign extend, it becomes useless.
00281       if (isa<SExtInst>(Inst) || isa<TruncInst>(Inst)) {
00282         DEBUG(dbgs() << "SExt or trunc, mark it as to remove\n");
00283         // We cannot use replaceAllUsesWith here because we may trigger some
00284         // assertion on the type as all involved sext operation may have not
00285         // been moved yet.
00286         while (!Inst->use_empty()) {
00287           Use &U = *Inst->use_begin();
00288           Instruction *User = dyn_cast<Instruction>(U.getUser());
00289           assert(User && "User of sext is not an Instruction!");
00290           User->setOperand(U.getOperandNo(), SExt);
00291         }
00292         ToRemove.insert(Inst);
00293         SExt->setOperand(0, Inst->getOperand(0));
00294         SExt->moveBefore(Inst);
00295         continue;
00296       }
00297 
00298       // Get through the Instruction:
00299       // 1. Update its type.
00300       // 2. Replace the uses of SExt by Inst.
00301       // 3. Sign extend each operand that needs to be sign extended.
00302 
00303       // Step #1.
00304       Inst->mutateType(SExt->getType());
00305       // Step #2.
00306       SExt->replaceAllUsesWith(Inst);
00307       // Step #3.
00308       Instruction *SExtForOpnd = SExt;
00309 
00310       DEBUG(dbgs() << "Propagate SExt to operands\n");
00311       for (int OpIdx = 0, EndOpIdx = Inst->getNumOperands(); OpIdx != EndOpIdx;
00312            ++OpIdx) {
00313         DEBUG(dbgs() << "Operand:\n" << *(Inst->getOperand(OpIdx)) << '\n');
00314         if (Inst->getOperand(OpIdx)->getType() == SExt->getType() ||
00315             !shouldSExtOperand(Inst, OpIdx)) {
00316           DEBUG(dbgs() << "No need to propagate\n");
00317           continue;
00318         }
00319         // Check if we can statically sign extend the operand.
00320         Value *Opnd = Inst->getOperand(OpIdx);
00321         if (const ConstantInt *Cst = dyn_cast<ConstantInt>(Opnd)) {
00322           DEBUG(dbgs() << "Statically sign extend\n");
00323           Inst->setOperand(OpIdx, ConstantInt::getSigned(SExt->getType(),
00324                                                          Cst->getSExtValue()));
00325           continue;
00326         }
00327         // UndefValue are typed, so we have to statically sign extend them.
00328         if (isa<UndefValue>(Opnd)) {
00329           DEBUG(dbgs() << "Statically sign extend\n");
00330           Inst->setOperand(OpIdx, UndefValue::get(SExt->getType()));
00331           continue;
00332         }
00333 
00334         // Otherwise we have to explicity sign extend it.
00335         assert(SExtForOpnd &&
00336                "Only one operand should have been sign extended");
00337 
00338         SExtForOpnd->setOperand(0, Opnd);
00339 
00340         DEBUG(dbgs() << "Move before:\n" << *Inst << "\nSign extend\n");
00341         // Move the sign extension before the insertion point.
00342         SExtForOpnd->moveBefore(Inst);
00343         Inst->setOperand(OpIdx, SExtForOpnd);
00344         // If more sext are required, new instructions will have to be created.
00345         SExtForOpnd = nullptr;
00346       }
00347       if (SExtForOpnd == SExt) {
00348         DEBUG(dbgs() << "Sign extension is useless now\n");
00349         ToRemove.insert(SExt);
00350         break;
00351       }
00352     }
00353 
00354     // If the use is already of the right type, connect its uses to its argument
00355     // and delete it.
00356     // This can happen for an Instruction all uses of which are sign extended.
00357     if (!ToRemove.count(SExt) &&
00358         SExt->getType() == SExt->getOperand(0)->getType()) {
00359       DEBUG(dbgs() << "Sign extension is useless, attach its use to "
00360                       "its argument\n");
00361       SExt->replaceAllUsesWith(SExt->getOperand(0));
00362       ToRemove.insert(SExt);
00363     } else
00364       ValToSExtendedUses[SExt->getOperand(0)].push_back(SExt);
00365   }
00366 
00367   if (EnableMerge)
00368     mergeSExts(ValToSExtendedUses, ToRemove);
00369 
00370   // Remove all instructions marked as ToRemove.
00371   for (Instruction *I: ToRemove)
00372     I->eraseFromParent();
00373   return LocalChange;
00374 }
00375 
00376 void AArch64AddressTypePromotion::mergeSExts(ValueToInsts &ValToSExtendedUses,
00377                                              SetOfInstructions &ToRemove) {
00378   DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
00379 
00380   for (auto &Entry : ValToSExtendedUses) {
00381     Instructions &Insts = Entry.second;
00382     Instructions CurPts;
00383     for (Instruction *Inst : Insts) {
00384       if (ToRemove.count(Inst))
00385         continue;
00386       bool inserted = false;
00387       for (auto &Pt : CurPts) {
00388         if (DT.dominates(Inst, Pt)) {
00389           DEBUG(dbgs() << "Replace all uses of:\n" << *Pt << "\nwith:\n"
00390                        << *Inst << '\n');
00391           Pt->replaceAllUsesWith(Inst);
00392           ToRemove.insert(Pt);
00393           Pt = Inst;
00394           inserted = true;
00395           break;
00396         }
00397         if (!DT.dominates(Pt, Inst))
00398           // Give up if we need to merge in a common dominator as the
00399           // expermients show it is not profitable.
00400           continue;
00401 
00402         DEBUG(dbgs() << "Replace all uses of:\n" << *Inst << "\nwith:\n"
00403                      << *Pt << '\n');
00404         Inst->replaceAllUsesWith(Pt);
00405         ToRemove.insert(Inst);
00406         inserted = true;
00407         break;
00408       }
00409       if (!inserted)
00410         CurPts.push_back(Inst);
00411     }
00412   }
00413 }
00414 
00415 void AArch64AddressTypePromotion::analyzeSExtension(Instructions &SExtInsts) {
00416   DEBUG(dbgs() << "*** Analyze Sign Extensions ***\n");
00417 
00418   DenseMap<Value *, Instruction *> SeenChains;
00419 
00420   for (auto &BB : *Func) {
00421     for (auto &II : BB) {
00422       Instruction *SExt = &II;
00423 
00424       // Collect all sext operation per type.
00425       if (!isa<SExtInst>(SExt) || !shouldConsiderSExt(SExt))
00426         continue;
00427 
00428       DEBUG(dbgs() << "Found:\n" << (*SExt) << '\n');
00429 
00430       // Cases where we actually perform the optimization:
00431       // 1. SExt is used in a getelementptr with more than 2 operand =>
00432       //    likely we can merge some computation if they are done on 64 bits.
00433       // 2. The beginning of the SExt chain is SExt several time. =>
00434       //    code sharing is possible.
00435 
00436       bool insert = false;
00437       // #1.
00438       for (const User *U : SExt->users()) {
00439         const Instruction *Inst = dyn_cast<GetElementPtrInst>(U);
00440         if (Inst && Inst->getNumOperands() > 2) {
00441           DEBUG(dbgs() << "Interesting use in GetElementPtrInst\n" << *Inst
00442                        << '\n');
00443           insert = true;
00444           break;
00445         }
00446       }
00447 
00448       // #2.
00449       // Check the head of the chain.
00450       Instruction *Inst = SExt;
00451       Value *Last;
00452       do {
00453         int OpdIdx = 0;
00454         const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Inst);
00455         if (BinOp && isa<ConstantInt>(BinOp->getOperand(0)))
00456           OpdIdx = 1;
00457         Last = Inst->getOperand(OpdIdx);
00458         Inst = dyn_cast<Instruction>(Last);
00459       } while (Inst && canGetThrough(Inst) && shouldGetThrough(Inst));
00460 
00461       DEBUG(dbgs() << "Head of the chain:\n" << *Last << '\n');
00462       DenseMap<Value *, Instruction *>::iterator AlreadySeen =
00463           SeenChains.find(Last);
00464       if (insert || AlreadySeen != SeenChains.end()) {
00465         DEBUG(dbgs() << "Insert\n");
00466         SExtInsts.push_back(SExt);
00467         if (AlreadySeen != SeenChains.end() && AlreadySeen->second != nullptr) {
00468           DEBUG(dbgs() << "Insert chain member\n");
00469           SExtInsts.push_back(AlreadySeen->second);
00470           SeenChains[Last] = nullptr;
00471         }
00472       } else {
00473         DEBUG(dbgs() << "Record its chain membership\n");
00474         SeenChains[Last] = SExt;
00475       }
00476     }
00477   }
00478 }
00479 
00480 bool AArch64AddressTypePromotion::runOnFunction(Function &F) {
00481   if (!EnableAddressTypePromotion || F.isDeclaration())
00482     return false;
00483   Func = &F;
00484   ConsideredSExtType = Type::getInt64Ty(Func->getContext());
00485 
00486   DEBUG(dbgs() << "*** " << getPassName() << ": " << Func->getName() << '\n');
00487 
00488   Instructions SExtInsts;
00489   analyzeSExtension(SExtInsts);
00490   return propagateSignExtension(SExtInsts);
00491 }