LLParser: Handle BlockAddresses on-the-fly
[oota-llvm.git] / lib / Transforms / Scalar / Scalarizer.cpp
index 36a01bd81dfe4586b68c3453880b352a33ed3d90..813041ab2551b954acf9cc7bb0e2b925309ed099 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "scalarizer"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/IR/IRBuilder.h"
-#include "llvm/InstVisitor.h"
+#include "llvm/IR/InstVisitor.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Transforms/Scalar.h"
@@ -25,6 +24,8 @@
 
 using namespace llvm;
 
+#define DEBUG_TYPE "scalarizer"
+
 namespace {
 // Used to store the scattered form of a vector.
 typedef SmallVector<Value *, 8> ValueVector;
@@ -42,11 +43,13 @@ typedef SmallVector<std::pair<Instruction *, ValueVector *>, 16> GatherList;
 // component of a scattered vector or vector pointer.
 class Scatterer {
 public:
+  Scatterer() {}
+
   // Scatter V into Size components.  If new instructions are needed,
   // insert them before BBI in BB.  If Cache is nonnull, use it to cache
   // the results.
   Scatterer(BasicBlock *bb, BasicBlock::iterator bbi, Value *v,
-            ValueVector *cachePtr = 0);
+            ValueVector *cachePtr = nullptr);
 
   // Return component I, creating a new Value for it if necessary.
   Value *operator[](unsigned I);
@@ -97,19 +100,9 @@ struct BinarySplitter {
   BinaryOperator &BO;
 };
 
-// GEPSpliiter()(Builder, X, Y, Name) uses Builder to create
-// a single GEP called Name with operands X and Y.
-struct GEPSplitter {
-  GEPSplitter() {}
-  Value *operator()(IRBuilder<> &Builder, Value *Op0, Value *Op1,
-                    const Twine &Name) const {
-    return Builder.CreateGEP(Op0, Op1, Name);
-  }
-};
-
 // Information about a load or store that we're scalarizing.
 struct VectorLayout {
-  VectorLayout() : VecTy(0), ElemTy(0), VecAlign(0), ElemSize(0) {}
+  VectorLayout() : VecTy(nullptr), ElemTy(nullptr), VecAlign(0), ElemSize(0) {}
 
   // Return the alignment of element I.
   uint64_t getElemAlign(unsigned I) {
@@ -139,8 +132,8 @@ public:
     initializeScalarizerPass(*PassRegistry::getPassRegistry());
   }
 
-  virtual bool doInitialization(Module &M);
-  virtual bool runOnFunction(Function &F);
+  bool doInitialization(Module &M) override;
+  bool runOnFunction(Function &F) override;
 
   // InstVisitor methods.  They return true if the instruction was scalarized,
   // false if nothing changed.
@@ -170,7 +163,7 @@ private:
   ScatterMap Scattered;
   GatherList Gathered;
   unsigned ParallelLoopAccessMDKind;
-  const DataLayout *TDL;
+  const DataLayout *DL;
 };
 
 char Scalarizer::ID = 0;
@@ -194,9 +187,9 @@ Scatterer::Scatterer(BasicBlock *bb, BasicBlock::iterator bbi, Value *v,
     Ty = PtrTy->getElementType();
   Size = Ty->getVectorNumElements();
   if (!CachePtr)
-    Tmp.resize(Size, 0);
+    Tmp.resize(Size, nullptr);
   else if (CachePtr->empty())
-    CachePtr->resize(Size, 0);
+    CachePtr->resize(Size, nullptr);
   else
     assert(Size == CachePtr->size() && "Inconsistent vector sizes");
 }
@@ -248,7 +241,8 @@ bool Scalarizer::doInitialization(Module &M) {
 }
 
 bool Scalarizer::runOnFunction(Function &F) {
-  TDL = getAnalysisIfAvailable<DataLayout>();
+  DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
+  DL = DLP ? &DLP->getDataLayout() : nullptr;
   for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) {
     BasicBlock *BB = BBI;
     for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE;) {
@@ -276,7 +270,7 @@ Scatterer Scalarizer::scatter(Instruction *Point, Value *V) {
     // Put the scattered form of an instruction directly after the
     // instruction.
     BasicBlock *BB = VOp->getParent();
-    return Scatterer(BB, llvm::next(BasicBlock::iterator(VOp)),
+    return Scatterer(BB, std::next(BasicBlock::iterator(VOp)),
                      V, &Scattered[V]);
   }
   // In the fallback case, just put the scattered before Point and
@@ -318,6 +312,8 @@ bool Scalarizer::canTransferMetadata(unsigned Tag) {
           || Tag == LLVMContext::MD_fpmath
           || Tag == LLVMContext::MD_tbaa_struct
           || Tag == LLVMContext::MD_invariant_load
+          || Tag == LLVMContext::MD_alias_scope
+          || Tag == LLVMContext::MD_noalias
           || Tag == ParallelLoopAccessMDKind);
 }
 
@@ -341,7 +337,7 @@ void Scalarizer::transferMetadata(Instruction *Op, const ValueVector &CV) {
 // the alignment of the vector, or 0 if the ABI default should be used.
 bool Scalarizer::getVectorLayout(Type *Ty, unsigned Alignment,
                                  VectorLayout &Layout) {
-  if (!TDL)
+  if (!DL)
     return false;
 
   // Make sure we're dealing with a vector.
@@ -351,15 +347,15 @@ bool Scalarizer::getVectorLayout(Type *Ty, unsigned Alignment,
 
   // Check that we're dealing with full-byte elements.
   Layout.ElemTy = Layout.VecTy->getElementType();
-  if (TDL->getTypeSizeInBits(Layout.ElemTy) !=
-      TDL->getTypeStoreSizeInBits(Layout.ElemTy))
+  if (DL->getTypeSizeInBits(Layout.ElemTy) !=
+      DL->getTypeStoreSizeInBits(Layout.ElemTy))
     return false;
 
   if (Alignment)
     Layout.VecAlign = Alignment;
   else
-    Layout.VecAlign = TDL->getABITypeAlignment(Layout.VecTy);
-  Layout.ElemSize = TDL->getTypeStoreSize(Layout.ElemTy);
+    Layout.VecAlign = DL->getABITypeAlignment(Layout.VecTy);
+  Layout.ElemSize = DL->getTypeStoreSize(Layout.ElemTy);
   return true;
 }
 
@@ -429,7 +425,36 @@ bool Scalarizer::visitBinaryOperator(BinaryOperator &BO) {
 }
 
 bool Scalarizer::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
-  return splitBinary(GEPI, GEPSplitter());
+  VectorType *VT = dyn_cast<VectorType>(GEPI.getType());
+  if (!VT)
+    return false;
+
+  IRBuilder<> Builder(GEPI.getParent(), &GEPI);
+  unsigned NumElems = VT->getNumElements();
+  unsigned NumIndices = GEPI.getNumIndices();
+
+  Scatterer Base = scatter(&GEPI, GEPI.getOperand(0));
+
+  SmallVector<Scatterer, 8> Ops;
+  Ops.resize(NumIndices);
+  for (unsigned I = 0; I < NumIndices; ++I)
+    Ops[I] = scatter(&GEPI, GEPI.getOperand(I + 1));
+
+  ValueVector Res;
+  Res.resize(NumElems);
+  for (unsigned I = 0; I < NumElems; ++I) {
+    SmallVector<Value *, 8> Indices;
+    Indices.resize(NumIndices);
+    for (unsigned J = 0; J < NumIndices; ++J)
+      Indices[J] = Ops[J][I];
+    Res[I] = Builder.CreateGEP(Base[I], Indices,
+                               GEPI.getName() + ".i" + Twine(I));
+    if (GEPI.isInBounds())
+      if (GetElementPtrInst *NewGEPI = dyn_cast<GetElementPtrInst>(Res[I]))
+        NewGEPI->setIsInBounds();
+  }
+  gather(&GEPI, Res);
+  return true;
 }
 
 bool Scalarizer::visitCastInst(CastInst &CI) {
@@ -617,8 +642,11 @@ bool Scalarizer::finish() {
       // InsertElements.
       Type *Ty = Op->getType();
       Value *Res = UndefValue::get(Ty);
+      BasicBlock *BB = Op->getParent();
       unsigned Count = Ty->getVectorNumElements();
-      IRBuilder<> Builder(Op->getParent(), Op);
+      IRBuilder<> Builder(BB, Op);
+      if (isa<PHINode>(Op))
+        Builder.SetInsertPoint(BB, BB->getFirstInsertionPt());
       for (unsigned I = 0; I < Count; ++I)
         Res = Builder.CreateInsertElement(Res, CV[I], Builder.getInt32(I),
                                           Op->getName() + ".upto" + Twine(I));