Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Unified Diff: lib/Transforms/NaCl/ExpandShuffleVector.cpp

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/Transforms/NaCl/ExpandLargeIntegers.cpp ('k') | lib/Transforms/NaCl/ExpandSmallArguments.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/Transforms/NaCl/ExpandShuffleVector.cpp
diff --git a/lib/Transforms/NaCl/ExpandShuffleVector.cpp b/lib/Transforms/NaCl/ExpandShuffleVector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7212668216bde673deb3f9605934f515822fdf35
--- /dev/null
+++ b/lib/Transforms/NaCl/ExpandShuffleVector.cpp
@@ -0,0 +1,110 @@
+//===- ExpandShuffleVector.cpp - shufflevector to {insert/extract}element -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Replace all shufflevector instructions by insertelement / extractelement.
+// BackendCanonicalize is able to reconstruct the shufflevector.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/NaCl.h"
+
+using namespace llvm;
+
+namespace {
+class ExpandShuffleVector : public BasicBlockPass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ ExpandShuffleVector() : BasicBlockPass(ID), M(0) {
+ initializeExpandShuffleVectorPass(*PassRegistry::getPassRegistry());
+ }
+ using BasicBlockPass::doInitialization;
+ bool doInitialization(Module &Mod) override {
+ M = &Mod;
+ return false; // Unchanged.
+ }
+ bool runOnBasicBlock(BasicBlock &BB) override;
+
+private:
+ const Module *M;
+ void Expand(ShuffleVectorInst *Shuf, Type *Int32);
+};
+}
+
+char ExpandShuffleVector::ID = 0;
+INITIALIZE_PASS(
+ ExpandShuffleVector, "expand-shufflevector",
+ "Expand shufflevector instructions into insertelement and extractelement",
+ false, false)
+
+void ExpandShuffleVector::Expand(ShuffleVectorInst *Shuf, Type *Int32) {
+ Value *L = Shuf->getOperand(0);
+ Value *R = Shuf->getOperand(1);
+ assert(L->getType() == R->getType());
+ VectorType *SrcVecTy = cast<VectorType>(L->getType());
+ VectorType *DstVecTy = Shuf->getType();
+ Type *ElemTy = DstVecTy->getElementType();
+ SmallVector<int, 16> Mask = Shuf->getShuffleMask();
+ unsigned NumSrcElems = SrcVecTy->getNumElements();
+ unsigned NumDstElems = Mask.size();
+
+ // Start with an undefined vector, extract each element from either L
+ // or R according to the Mask, and insert it into contiguous element
+ // locations in the result vector.
+ //
+ // The sources for shufflevector must have the same type but the
+ // destination could be a narrower or wider vector with the same
+ // element type.
+ Instruction *ExtractLoc = Shuf;
+ Value *Res = UndefValue::get(DstVecTy);
+ for (unsigned Elem = 0; Elem != NumDstElems; ++Elem) {
+ bool IsUndef =
+ 0 > Mask[Elem] || static_cast<unsigned>(Mask[Elem]) >= NumSrcElems * 2;
+ bool IsL = static_cast<unsigned>(Mask[Elem]) < NumSrcElems;
+ Value *From = IsL ? L : R;
+ int Adjustment = IsL ? 0 : NumSrcElems;
+ Constant *ExtractIdx = ConstantInt::get(Int32, Mask[Elem] - Adjustment);
+ Constant *InsertIdx = ConstantInt::get(Int32, Elem);
+ Value *ElemToInsert = IsUndef ? UndefValue::get(ElemTy)
+ : (Value *)ExtractElementInst::Create(
+ From, ExtractIdx, "", ExtractLoc);
+ Res = InsertElementInst::Create(Res, ElemToInsert, InsertIdx, "", Shuf);
+ if (ExtractLoc == Shuf)
+ // All the extracts should be added just before the first insert we added.
+ ExtractLoc = cast<Instruction>(Res);
+ }
+
+ Shuf->replaceAllUsesWith(Res);
+ Shuf->eraseFromParent();
+}
+
+bool ExpandShuffleVector::runOnBasicBlock(BasicBlock &BB) {
+ Type *Int32 = Type::getInt32Ty(M->getContext());
+ typedef SmallVector<ShuffleVectorInst *, 8> Instructions;
+ Instructions Shufs;
+
+ for (BasicBlock::iterator BBI = BB.begin(); BBI != BB.end(); ++BBI)
+ if (ShuffleVectorInst *S = dyn_cast<ShuffleVectorInst>(&*BBI))
+ Shufs.push_back(S);
+
+ for (Instructions::iterator S = Shufs.begin(), E = Shufs.end(); S != E; ++S)
+ Expand(*S, Int32);
+
+ return !Shufs.empty();
+}
+
+BasicBlockPass *llvm::createExpandShuffleVectorPass() {
+ return new ExpandShuffleVector();
+}
« no previous file with comments | « lib/Transforms/NaCl/ExpandLargeIntegers.cpp ('k') | lib/Transforms/NaCl/ExpandSmallArguments.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698