OLD | NEW |
(Empty) | |
| 1 //===- ExpandShuffleVector.cpp - shufflevector to {insert/extract}element -===// |
| 2 // |
| 3 // The LLVM Compiler Infrastructure |
| 4 // |
| 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 8 //===----------------------------------------------------------------------===// |
| 9 // |
| 10 // Replace all shufflevector instructions by insertelement / extractelement. |
| 11 // BackendCanonicalize is able to reconstruct the shufflevector. |
| 12 // |
| 13 //===----------------------------------------------------------------------===// |
| 14 |
| 15 #include "llvm/IR/BasicBlock.h" |
| 16 #include "llvm/IR/Constants.h" |
| 17 #include "llvm/IR/Instruction.h" |
| 18 #include "llvm/IR/Instructions.h" |
| 19 #include "llvm/IR/Module.h" |
| 20 #include "llvm/IR/Type.h" |
| 21 #include "llvm/Pass.h" |
| 22 #include "llvm/Transforms/NaCl.h" |
| 23 |
| 24 using namespace llvm; |
| 25 |
| 26 namespace { |
| 27 class ExpandShuffleVector : public BasicBlockPass { |
| 28 public: |
| 29 static char ID; // Pass identification, replacement for typeid |
| 30 ExpandShuffleVector() : BasicBlockPass(ID), M(0) { |
| 31 initializeExpandShuffleVectorPass(*PassRegistry::getPassRegistry()); |
| 32 } |
| 33 using BasicBlockPass::doInitialization; |
| 34 bool doInitialization(Module &Mod) override { |
| 35 M = &Mod; |
| 36 return false; // Unchanged. |
| 37 } |
| 38 bool runOnBasicBlock(BasicBlock &BB) override; |
| 39 |
| 40 private: |
| 41 const Module *M; |
| 42 void Expand(ShuffleVectorInst *Shuf, Type *Int32); |
| 43 }; |
| 44 } |
| 45 |
| 46 char ExpandShuffleVector::ID = 0; |
| 47 INITIALIZE_PASS( |
| 48 ExpandShuffleVector, "expand-shufflevector", |
| 49 "Expand shufflevector instructions into insertelement and extractelement", |
| 50 false, false) |
| 51 |
| 52 void ExpandShuffleVector::Expand(ShuffleVectorInst *Shuf, Type *Int32) { |
| 53 Value *L = Shuf->getOperand(0); |
| 54 Value *R = Shuf->getOperand(1); |
| 55 assert(L->getType() == R->getType()); |
| 56 VectorType *SrcVecTy = cast<VectorType>(L->getType()); |
| 57 VectorType *DstVecTy = Shuf->getType(); |
| 58 Type *ElemTy = DstVecTy->getElementType(); |
| 59 SmallVector<int, 16> Mask = Shuf->getShuffleMask(); |
| 60 unsigned NumSrcElems = SrcVecTy->getNumElements(); |
| 61 unsigned NumDstElems = Mask.size(); |
| 62 |
| 63 // Start with an undefined vector, extract each element from either L |
| 64 // or R according to the Mask, and insert it into contiguous element |
| 65 // locations in the result vector. |
| 66 // |
| 67 // The sources for shufflevector must have the same type but the |
| 68 // destination could be a narrower or wider vector with the same |
| 69 // element type. |
| 70 Instruction *ExtractLoc = Shuf; |
| 71 Value *Res = UndefValue::get(DstVecTy); |
| 72 for (unsigned Elem = 0; Elem != NumDstElems; ++Elem) { |
| 73 bool IsUndef = |
| 74 0 > Mask[Elem] || static_cast<unsigned>(Mask[Elem]) >= NumSrcElems * 2; |
| 75 bool IsL = static_cast<unsigned>(Mask[Elem]) < NumSrcElems; |
| 76 Value *From = IsL ? L : R; |
| 77 int Adjustment = IsL ? 0 : NumSrcElems; |
| 78 Constant *ExtractIdx = ConstantInt::get(Int32, Mask[Elem] - Adjustment); |
| 79 Constant *InsertIdx = ConstantInt::get(Int32, Elem); |
| 80 Value *ElemToInsert = IsUndef ? UndefValue::get(ElemTy) |
| 81 : (Value *)ExtractElementInst::Create( |
| 82 From, ExtractIdx, "", ExtractLoc); |
| 83 Res = InsertElementInst::Create(Res, ElemToInsert, InsertIdx, "", Shuf); |
| 84 if (ExtractLoc == Shuf) |
| 85 // All the extracts should be added just before the first insert we added. |
| 86 ExtractLoc = cast<Instruction>(Res); |
| 87 } |
| 88 |
| 89 Shuf->replaceAllUsesWith(Res); |
| 90 Shuf->eraseFromParent(); |
| 91 } |
| 92 |
| 93 bool ExpandShuffleVector::runOnBasicBlock(BasicBlock &BB) { |
| 94 Type *Int32 = Type::getInt32Ty(M->getContext()); |
| 95 typedef SmallVector<ShuffleVectorInst *, 8> Instructions; |
| 96 Instructions Shufs; |
| 97 |
| 98 for (BasicBlock::iterator BBI = BB.begin(); BBI != BB.end(); ++BBI) |
| 99 if (ShuffleVectorInst *S = dyn_cast<ShuffleVectorInst>(&*BBI)) |
| 100 Shufs.push_back(S); |
| 101 |
| 102 for (Instructions::iterator S = Shufs.begin(), E = Shufs.end(); S != E; ++S) |
| 103 Expand(*S, Int32); |
| 104 |
| 105 return !Shufs.empty(); |
| 106 } |
| 107 |
| 108 BasicBlockPass *llvm::createExpandShuffleVectorPass() { |
| 109 return new ExpandShuffleVector(); |
| 110 } |
OLD | NEW |