summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/Scalarizer.cpp
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-12-23 14:45:00 +0000
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-12-23 14:45:00 +0000
commit3548cbb98044c569e6fef10d6b9a1b6c68c8bbf7 (patch)
tree9970d5e556e164816339169230f1589475a3f402 /llvm/lib/Transforms/Scalar/Scalarizer.cpp
parent530e207d8a1eb487f0912e467bac98a83528d766 (diff)
downloadbcm5719-llvm-3548cbb98044c569e6fef10d6b9a1b6c68c8bbf7.tar.gz
bcm5719-llvm-3548cbb98044c569e6fef10d6b9a1b6c68c8bbf7.zip
Fix Scalarizer handling of vector GEPs with multiple index operands
The old code only worked for one index operand. Also handle "inbounds". llvm-svn: 197908
Diffstat (limited to 'llvm/lib/Transforms/Scalar/Scalarizer.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/Scalarizer.cpp43
1 files changed, 32 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/Scalar/Scalarizer.cpp b/llvm/lib/Transforms/Scalar/Scalarizer.cpp
index 36a01bd81df..33ccb7350d8 100644
--- a/llvm/lib/Transforms/Scalar/Scalarizer.cpp
+++ b/llvm/lib/Transforms/Scalar/Scalarizer.cpp
@@ -42,6 +42,8 @@ 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.
@@ -97,16 +99,6 @@ 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) {}
@@ -429,7 +421,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) {
OpenPOWER on IntegriCloud