diff options
author | Cameron McInally <cameron.mcinally@nyu.edu> | 2019-06-04 23:01:36 +0000 |
---|---|---|
committer | Cameron McInally <cameron.mcinally@nyu.edu> | 2019-06-04 23:01:36 +0000 |
commit | 5c7245b830eabfe85113707187f1da9bac1e17e5 (patch) | |
tree | b959844a4a3580f0cec555f34e514ab10845abaf /llvm/lib/Transforms/Scalar/Scalarizer.cpp | |
parent | c93b99589f7ef45d2f85f459731d0cbc4a55b005 (diff) | |
download | bcm5719-llvm-5c7245b830eabfe85113707187f1da9bac1e17e5.tar.gz bcm5719-llvm-5c7245b830eabfe85113707187f1da9bac1e17e5.zip |
[Scalarizer] Add UnaryOperator visitor to scalarization pass
Differential Revision: https://reviews.llvm.org/D62858
llvm-svn: 362558
Diffstat (limited to 'llvm/lib/Transforms/Scalar/Scalarizer.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/Scalarizer.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/Scalarizer.cpp b/llvm/lib/Transforms/Scalar/Scalarizer.cpp index 0bd0fff1aa5..515a6482773 100644 --- a/llvm/lib/Transforms/Scalar/Scalarizer.cpp +++ b/llvm/lib/Transforms/Scalar/Scalarizer.cpp @@ -124,6 +124,18 @@ struct ICmpSplitter { ICmpInst &ICI; }; +// UnarySpliiter(UO)(Builder, X, Name) uses Builder to create +// a unary operator like UO called Name with operand X. +struct UnarySplitter { + UnarySplitter(UnaryOperator &uo) : UO(uo) {} + + Value *operator()(IRBuilder<> &Builder, Value *Op, const Twine &Name) const { + return Builder.CreateUnOp(UO.getOpcode(), Op, Name); + } + + UnaryOperator &UO; +}; + // BinarySpliiter(BO)(Builder, X, Y, Name) uses Builder to create // a binary operator like BO called Name with operands X and Y. struct BinarySplitter { @@ -173,6 +185,7 @@ public: bool visitSelectInst(SelectInst &SI); bool visitICmpInst(ICmpInst &ICI); bool visitFCmpInst(FCmpInst &FCI); + bool visitUnaryOperator(UnaryOperator &UO); bool visitBinaryOperator(BinaryOperator &BO); bool visitGetElementPtrInst(GetElementPtrInst &GEPI); bool visitCastInst(CastInst &CI); @@ -192,6 +205,7 @@ private: const DataLayout &DL); bool finish(); + template<typename T> bool splitUnary(Instruction &, const T &); template<typename T> bool splitBinary(Instruction &, const T &); bool splitCall(CallInst &CI); @@ -419,6 +433,26 @@ bool ScalarizerVisitor::getVectorLayout(Type *Ty, unsigned Alignment, return true; } +// Scalarize one-operand instruction I, using Split(Builder, X, Name) +// to create an instruction like I with operand X and name Name. +template<typename Splitter> +bool ScalarizerVisitor::splitUnary(Instruction &I, const Splitter &Split) { + VectorType *VT = dyn_cast<VectorType>(I.getType()); + if (!VT) + return false; + + unsigned NumElems = VT->getNumElements(); + IRBuilder<> Builder(&I); + Scatterer Op = scatter(&I, I.getOperand(0)); + assert(Op.size() == NumElems && "Mismatched unary operation"); + ValueVector Res; + Res.resize(NumElems); + for (unsigned Elem = 0; Elem < NumElems; ++Elem) + Res[Elem] = Split(Builder, Op[Elem], I.getName() + ".i" + Twine(Elem)); + gather(&I, Res); + return true; +} + // Scalarize two-operand instruction I, using Split(Builder, X, Y, Name) // to create an instruction like I with operands X and Y and name Name. template<typename Splitter> @@ -551,6 +585,10 @@ bool ScalarizerVisitor::visitFCmpInst(FCmpInst &FCI) { return splitBinary(FCI, FCmpSplitter(FCI)); } +bool ScalarizerVisitor::visitUnaryOperator(UnaryOperator &UO) { + return splitUnary(UO, UnarySplitter(UO)); +} + bool ScalarizerVisitor::visitBinaryOperator(BinaryOperator &BO) { return splitBinary(BO, BinarySplitter(BO)); } |