Fix broken build
[oota-llvm.git] / lib / Target / ARM64 / ARM64PromoteConstant.cpp
index c19ade940cb29461ec7a5dc75dce0b344dd8385c..e61a62262d39a230b310070c73c6b3b2716ec1b6 100644 (file)
@@ -8,22 +8,19 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the ARM64PromoteConstant pass which promotes constant
-// to global variables when this is likely to be more efficient.
-// Currently only types related to constant vector (i.e., constant vector, array
-// of constant vectors, constant structure with a constant vector field, etc.)
-// are promoted to global variables.
-// Indeed, constant vector are likely to be lowered in target constant pool
-// during instruction selection.
-// Therefore, the access will remain the same (memory load), but the structures
-// types are not split into different constant pool accesses for each field.
-// The bonus side effect is that created globals may be merged by the global
-// merge pass.
+// This file implements the ARM64PromoteConstant pass which promotes constants
+// to global variables when this is likely to be more efficient. Currently only
+// types related to constant vector (i.e., constant vector, array of constant
+// vectors, constant structure with a constant vector field, etc.) are promoted
+// to global variables. Constant vectors are likely to be lowered in target
+// constant pool during instruction selection already; therefore, the access
+// will remain the same (memory load), but the structure types are not split
+// into different constant pool accesses for each field. A bonus side effect is
+// that created globals may be merged by the global merge pass.
 //
 // FIXME: This pass may be useful for other targets too.
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "arm64-promote-const"
 #include "ARM64.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/DenseMap.h"
@@ -44,6 +41,8 @@
 
 using namespace llvm;
 
+#define DEBUG_TYPE "arm64-promote-const"
+
 // Stress testing mode - disable heuristics.
 static cl::opt<bool> Stress("arm64-stress-promote-const", cl::Hidden,
                             cl::desc("Promote all vector constants"));
@@ -74,23 +73,25 @@ namespace {
 ///   return ret;
 /// }
 ///
-/// The constants in that example are folded into the uses. Thus, 4 different
+/// The constants in this example are folded into the uses. Thus, 4 different
 /// constants are created.
+///
 /// As their type is vector the cheapest way to create them is to load them
 /// for the memory.
-/// Therefore the final assembly final has 4 different load.
-/// With this pass enabled, only one load is issued for the constants.
+///
+/// Therefore the final assembly final has 4 different loads. With this pass
+/// enabled, only one load is issued for the constants.
 class ARM64PromoteConstant : public ModulePass {
 
 public:
   static char ID;
   ARM64PromoteConstant() : ModulePass(ID) {}
 
-  virtual const char *getPassName() const { return "ARM64 Promote Constant"; }
+  const char *getPassName() const override { return "ARM64 Promote Constant"; }
 
   /// Iterate over the functions and promote the interesting constants into
   /// global variables with module scope.
-  bool runOnModule(Module &M) {
+  bool runOnModule(Module &M) override {
     DEBUG(dbgs() << getPassName() << '\n');
     bool Changed = false;
     for (auto &MF : M) {
@@ -106,18 +107,18 @@ private:
   bool runOnFunction(Function &F);
 
   // This transformation requires dominator info
-  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesCFG();
     AU.addRequired<DominatorTreeWrapperPass>();
     AU.addPreserved<DominatorTreeWrapperPass>();
   }
 
-  /// Type to store a list of User
+  /// Type to store a list of User.
   typedef SmallVector<Value::user_iterator, 4> Users;
   /// Map an insertion point to all the uses it dominates.
   typedef DenseMap<Instruction *, Users> InsertionPoints;
   /// Map a function to the required insertion point of load for a
-  /// global variable
+  /// global variable.
   typedef DenseMap<Function *, InsertionPoints> InsertionPointsPerFunc;
 
   /// Find the closest point that dominates the given Use.
@@ -187,14 +188,14 @@ private:
                                              Value::user_iterator &UseIt,
                                              InsertionPoints::iterator &IPI,
                                              InsertionPoints &InsertPts) {
-    // Record the dominated use
+    // Record the dominated use.
     IPI->second.push_back(UseIt);
     // Transfer the dominated uses of IPI to NewPt
     // Inserting into the DenseMap may invalidate existing iterator.
     // Keep a copy of the key to find the iterator to erase.
     Instruction *OldInstr = IPI->first;
     InsertPts.insert(InsertionPoints::value_type(NewPt, IPI->second));
-    // Erase IPI
+    // Erase IPI.
     IPI = InsertPts.find(OldInstr);
     InsertPts.erase(IPI);
   }
@@ -243,26 +244,26 @@ static bool shouldConvertUse(const Constant *Cst, const Instruction *Instr,
   if (isa<const ShuffleVectorInst>(Instr) && OpIdx == 2)
     return false;
 
-  // extractvalue instruction expects a const idx
+  // extractvalue instruction expects a const idx.
   if (isa<const ExtractValueInst>(Instr) && OpIdx > 0)
     return false;
 
-  // extractvalue instruction expects a const idx
+  // extractvalue instruction expects a const idx.
   if (isa<const InsertValueInst>(Instr) && OpIdx > 1)
     return false;
 
   if (isa<const AllocaInst>(Instr) && OpIdx > 0)
     return false;
 
-  // Alignment argument must be constant
+  // Alignment argument must be constant.
   if (isa<const LoadInst>(Instr) && OpIdx > 0)
     return false;
 
-  // Alignment argument must be constant
+  // Alignment argument must be constant.
   if (isa<const StoreInst>(Instr) && OpIdx > 1)
     return false;
 
-  // Index must be constant
+  // Index must be constant.
   if (isa<const GetElementPtrInst>(Instr) && OpIdx > 0)
     return false;
 
@@ -271,19 +272,19 @@ static bool shouldConvertUse(const Constant *Cst, const Instruction *Instr,
   if (isa<const LandingPadInst>(Instr))
     return false;
 
-  // switch instruction expects constants to compare to
+  // Switch instruction expects constants to compare to.
   if (isa<const SwitchInst>(Instr))
     return false;
 
-  // Expected address must be a constant
+  // Expected address must be a constant.
   if (isa<const IndirectBrInst>(Instr))
     return false;
 
-  // Do not mess with intrinsic
+  // Do not mess with intrinsics.
   if (isa<const IntrinsicInst>(Instr))
     return false;
 
-  // Do not mess with inline asm
+  // Do not mess with inline asm.
   const CallInst *CI = dyn_cast<const CallInst>(Instr);
   if (CI && isa<const InlineAsm>(CI->getCalledValue()))
     return false;
@@ -331,7 +332,7 @@ static bool shouldConvert(const Constant *Cst) {
 Instruction *
 ARM64PromoteConstant::findInsertionPoint(Value::user_iterator &Use) {
   // If this user is a phi, the insertion point is in the related
-  // incoming basic block
+  // incoming basic block.
   PHINode *PhiInst = dyn_cast<PHINode>(*Use);
   Instruction *InsertionPoint;
   if (PhiInst)
@@ -350,23 +351,20 @@ bool ARM64PromoteConstant::isDominated(Instruction *NewPt,
   DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>(
       *NewPt->getParent()->getParent()).getDomTree();
 
-  // Traverse all the existing insertion point and check if one is dominating
-  // NewPt
-  for (InsertionPoints::iterator IPI = InsertPts.begin(),
-                                 EndIPI = InsertPts.end();
-       IPI != EndIPI; ++IPI) {
-    if (NewPt == IPI->first || DT.dominates(IPI->first, NewPt) ||
-        // When IPI->first is a terminator instruction, DT may think that
+  // Traverse all the existing insertion points and check if one is dominating
+  // NewPt. If it is, remember that.
+  for (auto &IPI : InsertPts) {
+    if (NewPt == IPI.first || DT.dominates(IPI.first, NewPt) ||
+        // When IPI.first is a terminator instruction, DT may think that
         // the result is defined on the edge.
         // Here we are testing the insertion point, not the definition.
-        (IPI->first->getParent() != NewPt->getParent() &&
-         DT.dominates(IPI->first->getParent(), NewPt->getParent()))) {
-      // No need to insert this point
-      // Record the dominated use
+        (IPI.first->getParent() != NewPt->getParent() &&
+         DT.dominates(IPI.first->getParent(), NewPt->getParent()))) {
+      // No need to insert this point. Just record the dominated use.
       DEBUG(dbgs() << "Insertion point dominated by:\n");
-      DEBUG(IPI->first->print(dbgs()));
+      DEBUG(IPI.first->print(dbgs()));
       DEBUG(dbgs() << '\n');
-      IPI->second.push_back(UseIt);
+      IPI.second.push_back(UseIt);
       return true;
     }
   }
@@ -382,7 +380,7 @@ bool ARM64PromoteConstant::tryAndMerge(Instruction *NewPt,
 
   // Traverse all the existing insertion point and check if one is dominated by
   // NewPt and thus useless or can be combined with NewPt into a common
-  // dominator
+  // dominator.
   for (InsertionPoints::iterator IPI = InsertPts.begin(),
                                  EndIPI = InsertPts.end();
        IPI != EndIPI; ++IPI) {
@@ -400,19 +398,19 @@ bool ARM64PromoteConstant::tryAndMerge(Instruction *NewPt,
 
     // Look for a common dominator
     BasicBlock *CommonDominator = DT.findNearestCommonDominator(NewBB, CurBB);
-    // If none exists, we cannot merge these two points
+    // If none exists, we cannot merge these two points.
     if (!CommonDominator)
       continue;
 
     if (CommonDominator != NewBB) {
-      // By construction, the CommonDominator cannot be CurBB
+      // By construction, the CommonDominator cannot be CurBB.
       assert(CommonDominator != CurBB &&
              "Instruction has not been rejected during isDominated check!");
       // Take the last instruction of the CommonDominator as insertion point
       NewPt = CommonDominator->getTerminator();
     }
     // else, CommonDominator is the block of NewBB, hence NewBB is the last
-    // possible insertion point in that block
+    // possible insertion point in that block.
     DEBUG(dbgs() << "Merge insertion point with:\n");
     DEBUG(IPI->first->print(dbgs()));
     DEBUG(dbgs() << '\n');
@@ -430,11 +428,11 @@ void ARM64PromoteConstant::computeInsertionPoints(
   for (Value::user_iterator UseIt = Val->user_begin(),
                             EndUseIt = Val->user_end();
        UseIt != EndUseIt; ++UseIt) {
-    // If the user is not an Instruction, we cannot modify it
+    // If the user is not an Instruction, we cannot modify it.
     if (!isa<Instruction>(*UseIt))
       continue;
 
-    // Filter out uses that should not be converted
+    // Filter out uses that should not be converted.
     if (!shouldConvertUse(Val, cast<Instruction>(*UseIt), UseIt.getOperandNo()))
       continue;
 
@@ -469,16 +467,16 @@ void ARM64PromoteConstant::computeInsertionPoints(
 bool
 ARM64PromoteConstant::insertDefinitions(Constant *Cst,
                                         InsertionPointsPerFunc &InsPtsPerFunc) {
-  // We will create one global variable per Module
+  // We will create one global variable per Module.
   DenseMap<Module *, GlobalVariable *> ModuleToMergedGV;
   bool HasChanged = false;
 
-  // Traverse all insertion points in all the function
+  // Traverse all insertion points in all the function.
   for (InsertionPointsPerFunc::iterator FctToInstPtsIt = InsPtsPerFunc.begin(),
                                         EndIt = InsPtsPerFunc.end();
        FctToInstPtsIt != EndIt; ++FctToInstPtsIt) {
     InsertionPoints &InsertPts = FctToInstPtsIt->second;
-// Do more check for debug purposes
+// Do more checking for debug purposes.
 #ifndef NDEBUG
     DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>(
         *FctToInstPtsIt->first).getDomTree();
@@ -491,8 +489,8 @@ ARM64PromoteConstant::insertDefinitions(Constant *Cst,
         ModuleToMergedGV.find(M);
     if (MapIt == ModuleToMergedGV.end()) {
       PromotedGV = new GlobalVariable(
-          *M, Cst->getType(), true, GlobalValue::InternalLinkage, 0,
-          "_PromotedConst", 0, GlobalVariable::NotThreadLocal);
+          *M, Cst->getType(), true, GlobalValue::InternalLinkage, nullptr,
+          "_PromotedConst", nullptr, GlobalVariable::NotThreadLocal);
       PromotedGV->setInitializer(Cst);
       ModuleToMergedGV[M] = PromotedGV;
       DEBUG(dbgs() << "Global replacement: ");
@@ -507,7 +505,7 @@ ARM64PromoteConstant::insertDefinitions(Constant *Cst,
     for (InsertionPoints::iterator IPI = InsertPts.begin(),
                                    EndIPI = InsertPts.end();
          IPI != EndIPI; ++IPI) {
-      // Create the load of the global variable
+      // Create the load of the global variable.
       IRBuilder<> Builder(IPI->first->getParent(), IPI->first);
       LoadInst *LoadedCst = Builder.CreateLoad(PromotedGV);
       DEBUG(dbgs() << "**********\n");
@@ -515,21 +513,19 @@ ARM64PromoteConstant::insertDefinitions(Constant *Cst,
       DEBUG(LoadedCst->print(dbgs()));
       DEBUG(dbgs() << '\n');
 
-      // Update the dominated uses
+      // Update the dominated uses.
       Users &DominatedUsers = IPI->second;
-      for (Users::iterator UseIt = DominatedUsers.begin(),
-                           EndIt = DominatedUsers.end();
-           UseIt != EndIt; ++UseIt) {
+      for (Value::user_iterator Use : DominatedUsers) {
 #ifndef NDEBUG
-        assert((DT.dominates(LoadedCst, cast<Instruction>(**UseIt)) ||
-                (isa<PHINode>(**UseIt) &&
-                 DT.dominates(LoadedCst, findInsertionPoint(*UseIt)))) &&
+        assert((DT.dominates(LoadedCst, cast<Instruction>(*Use)) ||
+                (isa<PHINode>(*Use) &&
+                 DT.dominates(LoadedCst, findInsertionPoint(Use)))) &&
                "Inserted definition does not dominate all its uses!");
 #endif
-        DEBUG(dbgs() << "Use to update " << UseIt->getOperandNo() << ":");
-        DEBUG((*UseIt)->print(dbgs()));
+        DEBUG(dbgs() << "Use to update " << Use.getOperandNo() << ":");
+        DEBUG(Use->print(dbgs()));
         DEBUG(dbgs() << '\n');
-        (*UseIt)->setOperand(UseIt->getOperandNo(), LoadedCst);
+        Use->setOperand(Use.getOperandNo(), LoadedCst);
         ++NumPromotedUses;
       }
     }
@@ -558,23 +554,22 @@ bool ARM64PromoteConstant::promoteConstant(Constant *Cst) {
 }
 
 bool ARM64PromoteConstant::runOnFunction(Function &F) {
-  // Look for instructions using constant vector
-  // Promote that constant to a global variable.
-  // Create as few load of this variable as possible and update the uses
-  // accordingly
+  // Look for instructions using constant vector. Promote that constant to a
+  // global variable. Create as few loads of this variable as possible and
+  // update the uses accordingly.
   bool LocalChange = false;
   SmallSet<Constant *, 8> AlreadyChecked;
 
   for (auto &MBB : F) {
     for (auto &MI : MBB) {
-      // Traverse the operand, looking for constant vectors
-      // Replace them by a load of a global variable of type constant vector
+      // Traverse the operand, looking for constant vectors. Replace them by a
+      // load of a global variable of constant vector type.
       for (unsigned OpIdx = 0, EndOpIdx = MI.getNumOperands();
            OpIdx != EndOpIdx; ++OpIdx) {
         Constant *Cst = dyn_cast<Constant>(MI.getOperand(OpIdx));
-        // There is no point is promoting global value, they are already global.
-        // Do not promote constant expression, as they may require some code
-        // expansion.
+        // There is no point in promoting global values as they are already
+        // global. Do not promote constant expressions either, as they may
+        // require some code expansion.
         if (Cst && !isa<GlobalValue>(Cst) && !isa<ConstantExpr>(Cst) &&
             AlreadyChecked.insert(Cst))
           LocalChange |= promoteConstant(Cst);