Revert r240137 (Fixed/added namespace ending comments using clang-tidy. NFC)
[oota-llvm.git] / lib / Transforms / Utils / BypassSlowDivision.cpp
index 1c58bec925d920b5f4f2b97e7ad563c4850649b1..f2d5e074503520eb8f0bbc54bedaa93182b8bc51 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "bypass-slow-division"
-#include "llvm/Instructions.h"
-#include "llvm/Function.h"
-#include "llvm/IRBuilder.h"
-#include "llvm/ADT/DenseMap.h"
 #include "llvm/Transforms/Utils/BypassSlowDivision.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instructions.h"
 
 using namespace llvm;
 
-namespace llvm {
+#define DEBUG_TYPE "bypass-slow-division"
+
+namespace {
   struct DivOpInfo {
     bool SignedOp;
     Value *Dividend;
@@ -41,7 +42,9 @@ namespace llvm {
     DivPhiNodes(PHINode *InQuotient, PHINode *InRemainder)
       : Quotient(InQuotient), Remainder(InRemainder) {}
   };
+}
 
+namespace llvm {
   template<>
   struct DenseMapInfo<DivOpInfo> {
     static bool isEqual(const DivOpInfo &Val1, const DivOpInfo &Val2) {
@@ -51,17 +54,17 @@ namespace llvm {
     }
 
     static DivOpInfo getEmptyKey() {
-      return DivOpInfo(false, 0, 0);
+      return DivOpInfo(false, nullptr, nullptr);
     }
 
     static DivOpInfo getTombstoneKey() {
-      return DivOpInfo(true, 0, 0);
+      return DivOpInfo(true, nullptr, nullptr);
     }
 
     static unsigned getHashValue(const DivOpInfo &Val) {
       return (unsigned)(reinterpret_cast<uintptr_t>(Val.Dividend) ^
                         reinterpret_cast<uintptr_t>(Val.Divisor)) ^
-                       (unsigned)Val.SignedOp;
+                        (unsigned)Val.SignedOp;
     }
   };
 
@@ -71,31 +74,29 @@ namespace llvm {
 // insertFastDiv - Substitutes the div/rem instruction with code that checks the
 // value of the operands and uses a shorter-faster div/rem instruction when
 // possible and the longer-slower div/rem instruction otherwise.
-static void insertFastDiv(Function &F,
+static bool insertFastDiv(Function &F,
                           Function::iterator &I,
                           BasicBlock::iterator &J,
                           IntegerType *BypassType,
                           bool UseDivOp,
                           bool UseSignedOp,
-                          DivCacheTy &PerBBDivCache)
-{
+                          DivCacheTy &PerBBDivCache) {
   // Get instruction operands
   Instruction *Instr = J;
   Value *Dividend = Instr->getOperand(0);
   Value *Divisor = Instr->getOperand(1);
 
-  if (dyn_cast<ConstantInt>(Divisor) != 0 ||
-      (dyn_cast<ConstantInt>(Dividend) != 0 &&
-       dyn_cast<ConstantInt>(Divisor) != 0)) {
+  if (isa<ConstantInt>(Divisor) ||
+      (isa<ConstantInt>(Dividend) && isa<ConstantInt>(Divisor))) {
     // Operations with immediate values should have
     // been solved and replaced during compile time.
-    return;
+    return false;
   }
 
   // Basic Block is split before divide
   BasicBlock *MainBB = I;
   BasicBlock *SuccessorBB = I->splitBasicBlock(J);
-  I++; //advance iterator I to successorBB
+  ++I; //advance iterator I to successorBB
 
   // Add new basic block for slow divide operation
   BasicBlock *SlowBB = BasicBlock::Create(F.getContext(), "",
@@ -118,17 +119,19 @@ static void insertFastDiv(Function &F,
                                           MainBB->getParent(), SuccessorBB);
   FastBB->moveBefore(SlowBB);
   IRBuilder<> FastBuilder(FastBB, FastBB->begin());
-  Value *ShortDivisorV = FastBuilder.CreateCast(Instruction::Trunc, Divisor, BypassType);
-  Value *ShortDividendV = FastBuilder.CreateCast(Instruction::Trunc, Dividend, BypassType);
+  Value *ShortDivisorV = FastBuilder.CreateCast(Instruction::Trunc, Divisor,
+                                                BypassType);
+  Value *ShortDividendV = FastBuilder.CreateCast(Instruction::Trunc, Dividend,
+                                                 BypassType);
 
   // udiv/urem because optimization only handles positive numbers
   Value *ShortQuotientV = FastBuilder.CreateExactUDiv(ShortDividendV,
-                                                       ShortDivisorV);
+                                                      ShortDivisorV);
   Value *ShortRemainderV = FastBuilder.CreateURem(ShortDividendV,
                                                   ShortDivisorV);
   Value *FastQuotientV = FastBuilder.CreateCast(Instruction::ZExt,
-                                                 ShortQuotientV,
-                                                 Dividend->getType());
+                                                ShortQuotientV,
+                                                Dividend->getType());
   Value *FastRemainderV = FastBuilder.CreateCast(Instruction::ZExt,
                                                  ShortRemainderV,
                                                  Dividend->getType());
@@ -144,11 +147,10 @@ static void insertFastDiv(Function &F,
   RemPhi->addIncoming(FastRemainderV, FastBB);
 
   // Replace Instr with appropriate phi node
-  if (UseDivOp) {
+  if (UseDivOp)
     Instr->replaceAllUsesWith(QuoPhi);
-  } else {
+  else
     Instr->replaceAllUsesWith(RemPhi);
-  }
   Instr->eraseFromParent();
 
   // Combine operands into a single value with OR for value testing below
@@ -162,7 +164,7 @@ static void insertFastDiv(Function &F,
   Value *AndV = MainBuilder.CreateAnd(OrV, BitMask);
 
   // Compare operand values and branch
-  Value *ZeroV = MainBuilder.getInt32(0);
+  Value *ZeroV = ConstantInt::getSigned(Dividend->getType(), 0);
   Value *CmpV = MainBuilder.CreateICmpEQ(AndV, ZeroV);
   MainBuilder.CreateCondBr(CmpV, FastBB, SlowBB);
 
@@ -174,32 +176,32 @@ static void insertFastDiv(Function &F,
   DivOpInfo Key(UseSignedOp, Dividend, Divisor);
   DivPhiNodes Value(QuoPhi, RemPhi);
   PerBBDivCache.insert(std::pair<DivOpInfo, DivPhiNodes>(Key, Value));
+  return true;
 }
 
 // reuseOrInsertFastDiv - Reuses previously computed dividend or remainder if
 // operands and operation are identical. Otherwise call insertFastDiv to perform
 // the optimization and cache the resulting dividend and remainder.
-static void reuseOrInsertFastDiv(Function &F,
+static bool reuseOrInsertFastDiv(Function &F,
                                  Function::iterator &I,
                                  BasicBlock::iterator &J,
                                  IntegerType *BypassType,
                                  bool UseDivOp,
                                  bool UseSignedOp,
-                                 DivCacheTy &PerBBDivCache)
-{
+                                 DivCacheTy &PerBBDivCache) {
   // Get instruction operands
   Instruction *Instr = J;
   DivOpInfo Key(UseSignedOp, Instr->getOperand(0), Instr->getOperand(1));
-  DivCacheTy::const_iterator CacheI = PerBBDivCache.find(Key);
+  DivCacheTy::iterator CacheI = PerBBDivCache.find(Key);
 
   if (CacheI == PerBBDivCache.end()) {
     // If previous instance does not exist, insert fast div
-    insertFastDiv(F, I, J, BypassType, UseDivOp, UseSignedOp, PerBBDivCache);
-    return;
+    return insertFastDiv(F, I, J, BypassType, UseDivOp, UseSignedOp,
+                         PerBBDivCache);
   }
 
   // Replace operation value with previously generated phi node
-  DivPhiNodes Value = CacheI->second;
+  DivPhiNodes &Value = CacheI->second;
   if (UseDivOp) {
     // Replace all uses of div instruction with quotient phi node
     J->replaceAllUsesWith(Value.Quotient);
@@ -209,18 +211,18 @@ static void reuseOrInsertFastDiv(Function &F,
   }
 
   // Advance to next operation
-  J++;
+  ++J;
 
   // Remove redundant operation
   Instr->eraseFromParent();
+  return true;
 }
 
 // bypassSlowDivision - This optimization identifies DIV instructions that can
 // be profitably bypassed and carried out with a shorter, faster divide.
-bool bypassSlowDivision(Function &F,
-                        Function::iterator &I,
-                        const llvm::DenseMap<Type *, Type *> &BypassTypeMap)
-{
+bool llvm::bypassSlowDivision(Function &F,
+                              Function::iterator &I,
+                              const DenseMap<unsigned int, unsigned int> &BypassWidths) {
   DivCacheTy DivCache;
 
   bool MadeChange = false;
@@ -230,21 +232,31 @@ bool bypassSlowDivision(Function &F,
     unsigned Opcode = J->getOpcode();
     bool UseDivOp = Opcode == Instruction::SDiv || Opcode == Instruction::UDiv;
     bool UseRemOp = Opcode == Instruction::SRem || Opcode == Instruction::URem;
-    bool UseSignedOp = Opcode == Instruction::SDiv || Opcode == Instruction::SRem;
+    bool UseSignedOp = Opcode == Instruction::SDiv ||
+                       Opcode == Instruction::SRem;
 
     // Only optimize div or rem ops
-    if (!UseDivOp && !UseRemOp) {
+    if (!UseDivOp && !UseRemOp)
       continue;
-    }
-    // Continue if div/rem type is not bypassed
-    DenseMap<Type *, Type *>::const_iterator BT = BypassTypeMap.find(J->getType());
-    if (BT == BypassTypeMap.end()) {
+
+    // Skip division on vector types, only optimize integer instructions
+    if (!J->getType()->isIntegerTy())
       continue;
-    }
 
-    IntegerType *BypassType = (IntegerType *)BT->second;
-    reuseOrInsertFastDiv(F, I, J, BypassType, UseDivOp, UseSignedOp, DivCache);
-    MadeChange = true;
+    // Get bitwidth of div/rem instruction
+    IntegerType *T = cast<IntegerType>(J->getType());
+    unsigned int bitwidth = T->getBitWidth();
+
+    // Continue if bitwidth is not bypassed
+    DenseMap<unsigned int, unsigned int>::const_iterator BI = BypassWidths.find(bitwidth);
+    if (BI == BypassWidths.end())
+      continue;
+
+    // Get type for div/rem instruction with bypass bitwidth
+    IntegerType *BT = IntegerType::get(J->getContext(), BI->second);
+
+    MadeChange |= reuseOrInsertFastDiv(F, I, J, BT, UseDivOp,
+                                       UseSignedOp, DivCache);
   }
 
   return MadeChange;