diff options
| author | Chandler Carruth <chandlerc@gmail.com> | 2012-12-17 04:07:35 +0000 | 
|---|---|---|
| committer | Chandler Carruth <chandlerc@gmail.com> | 2012-12-17 04:07:35 +0000 | 
| commit | eae65a56294eddee7296fe2f9ef64de5066c52dc (patch) | |
| tree | 0ee6b9af10a7cd688bf61bd524436aa56768b389 /llvm/lib/Transforms | |
| parent | 514f34f9c4b0960bf6bff83ad8d407d29fa71624 (diff) | |
| download | bcm5719-llvm-eae65a56294eddee7296fe2f9ef64de5066c52dc.tar.gz bcm5719-llvm-eae65a56294eddee7296fe2f9ef64de5066c52dc.zip | |
Extract the logic for inserting a subvector into a vector alloca.
No functionality changed. Another step of refactoring toward solving
PR14487.
llvm-svn: 170300
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/SROA.cpp | 88 | 
1 files changed, 50 insertions, 38 deletions
| diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index f4120c93cfa..5b11579f66b 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -2506,6 +2506,52 @@ private:      return !LI.isVolatile() && !IsPtrAdjusted;    } +  Value *insertVector(IRBuilder<> &IRB, Value *V, +                      unsigned BeginIndex, unsigned EndIndex) { +    assert(VecTy && "Can only insert a vector into a vector alloca"); +    unsigned NumElements = EndIndex - BeginIndex; +    assert(NumElements <= VecTy->getNumElements() && "Too many elements!"); + +    if (NumElements == VecTy->getNumElements()) +      return convertValue(TD, IRB, V, VecTy); + +    LoadInst *LI = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), +                                         getName(".load")); +    if (NumElements == 1) { +      V = IRB.CreateInsertElement(LI, V, IRB.getInt32(BeginIndex), +                                  getName(".insert")); +      DEBUG(dbgs() <<  "     insert: " << *V << "\n"); +      return V; +    } + +    // When inserting a smaller vector into the larger to store, we first +    // use a shuffle vector to widen it with undef elements, and then +    // a second shuffle vector to select between the loaded vector and the +    // incoming vector. +    SmallVector<Constant*, 8> Mask; +    Mask.reserve(VecTy->getNumElements()); +    for (unsigned i = 0; i != VecTy->getNumElements(); ++i) +      if (i >= BeginIndex && i < EndIndex) +        Mask.push_back(IRB.getInt32(i - BeginIndex)); +      else +        Mask.push_back(UndefValue::get(IRB.getInt32Ty())); +    V = IRB.CreateShuffleVector(V, UndefValue::get(V->getType()), +                                ConstantVector::get(Mask), +                                getName(".expand")); +    DEBUG(dbgs() << "    shuffle1: " << *V << "\n"); + +    Mask.clear(); +    for (unsigned i = 0; i != VecTy->getNumElements(); ++i) +      if (i >= BeginIndex && i < EndIndex) +        Mask.push_back(IRB.getInt32(i)); +      else +        Mask.push_back(IRB.getInt32(i + VecTy->getNumElements())); +    V = IRB.CreateShuffleVector(V, LI, ConstantVector::get(Mask), +                                getName("insert")); +    DEBUG(dbgs() << "    shuffle2: " << *V << "\n"); +    return V; +  } +    bool rewriteVectorizedStoreInst(IRBuilder<> &IRB, Value *V,                                    StoreInst &SI, Value *OldOp) {      unsigned BeginIndex = getIndex(BeginOffset); @@ -2518,44 +2564,10 @@ private:                             : VectorType::get(ElementTy, NumElements);      if (V->getType() != PartitionTy)        V = convertValue(TD, IRB, V, PartitionTy); -    if (NumElements < VecTy->getNumElements()) { -      // We need to mix in the existing elements. -      LoadInst *LI = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), -                                           getName(".load")); -      if (NumElements == 1) { -        V = IRB.CreateInsertElement(LI, V, IRB.getInt32(BeginIndex), -                                    getName(".insert")); -        DEBUG(dbgs() <<  "     insert: " << *V << "\n"); -      } else { -        // When inserting a smaller vector into the larger to store, we first -        // use a shuffle vector to widen it with undef elements, and then -        // a second shuffle vector to select between the loaded vector and the -        // incoming vector. -        SmallVector<Constant*, 8> Mask; -        Mask.reserve(VecTy->getNumElements()); -        for (unsigned i = 0; i != VecTy->getNumElements(); ++i) -          if (i >= BeginIndex && i < EndIndex) -            Mask.push_back(IRB.getInt32(i - BeginIndex)); -          else -            Mask.push_back(UndefValue::get(IRB.getInt32Ty())); -        V = IRB.CreateShuffleVector(V, UndefValue::get(V->getType()), -                                    ConstantVector::get(Mask), -                                    getName(".expand")); -        DEBUG(dbgs() << "    shuffle1: " << *V << "\n"); - -        Mask.clear(); -        for (unsigned i = 0; i != VecTy->getNumElements(); ++i) -          if (i >= BeginIndex && i < EndIndex) -            Mask.push_back(IRB.getInt32(i)); -          else -            Mask.push_back(IRB.getInt32(i + VecTy->getNumElements())); -        V = IRB.CreateShuffleVector(V, LI, ConstantVector::get(Mask), -                                    getName("insert")); -        DEBUG(dbgs() << "    shuffle2: " << *V << "\n"); -      } -    } else { -      V = convertValue(TD, IRB, V, VecTy); -    } + +    // Mix in the existing elements. +    V = insertVector(IRB, V, BeginIndex, EndIndex); +      StoreInst *Store = IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlignment());      Pass.DeadInsts.insert(&SI); | 

