From 62657090de3a5731bf644437701ccd78c247119f Mon Sep 17 00:00:00 2001 From: Nadav Rotem Date: Mon, 22 Jul 2013 22:18:07 +0000 Subject: When we vectorize across multiple basic blocks we may vectorize PHINodes that create a cycle. We already break the cycle on phi-nodes, but arithmetic operations are still uplicated. This patch adds code that checks if the operation that we are vectorizing was vectorized during the visit of the operands and uses this value if it can. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186883 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Vectorize/SLPVectorizer.cpp | 34 +++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'lib/Transforms/Vectorize/SLPVectorizer.cpp') diff --git a/lib/Transforms/Vectorize/SLPVectorizer.cpp b/lib/Transforms/Vectorize/SLPVectorizer.cpp index 3502222..25f7a78 100644 --- a/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -264,12 +264,16 @@ private: /// This is the recursive part of buildTree. void buildTree_rec(ArrayRef Roots, unsigned Depth); - /// Vectorizer a single entry in the tree. + /// Vectorize a single entry in the tree. Value *vectorizeTree(TreeEntry *E); - /// Vectorizer a single entry in the tree, starting in \p VL. + /// Vectorize a single entry in the tree, starting in \p VL. Value *vectorizeTree(ArrayRef VL); + /// \returns the pointer to the vectorized value if \p VL is already + /// vectorized, or NULL. They may happen in cycles. + Value *alreadyVectorized(ArrayRef VL); + /// \brief Take the pointer operand from the Load/Store instruction. /// \returns NULL if this is not a valid Load/Store instruction. static Value *getPointerOperand(Value *I); @@ -1117,6 +1121,16 @@ Value *BoUpSLP::Gather(ArrayRef VL, VectorType *Ty) { return Vec; } +Value *BoUpSLP::alreadyVectorized(ArrayRef VL) { + if (ScalarToTreeEntry.count(VL[0])) { + int Idx = ScalarToTreeEntry[VL[0]]; + TreeEntry *En = &VectorizableTree[Idx]; + if (En->isSame(VL) && En->VectorizedValue) + return En->VectorizedValue; + } + return 0; +} + Value *BoUpSLP::vectorizeTree(ArrayRef VL) { if (ScalarToTreeEntry.count(VL[0])) { int Idx = ScalarToTreeEntry[VL[0]]; @@ -1206,6 +1220,10 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) { Builder.SetInsertPoint(getLastInstruction(E->Scalars)); Value *InVec = vectorizeTree(INVL); + + if (Value *V = alreadyVectorized(E->Scalars)) + return V; + CastInst *CI = dyn_cast(VL0); Value *V = Builder.CreateCast(CI->getOpcode(), InVec, VecTy); E->VectorizedValue = V; @@ -1222,9 +1240,12 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) { Builder.SetInsertPoint(getLastInstruction(E->Scalars)); Value *L = vectorizeTree(LHSV); Value *R = vectorizeTree(RHSV); - Value *V; + + if (Value *V = alreadyVectorized(E->Scalars)) + return V; CmpInst::Predicate P0 = dyn_cast(VL0)->getPredicate(); + Value *V; if (Opcode == Instruction::FCmp) V = Builder.CreateFCmp(P0, L, R); else @@ -1245,6 +1266,10 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) { Value *Cond = vectorizeTree(CondVec); Value *True = vectorizeTree(TrueVec); Value *False = vectorizeTree(FalseVec); + + if (Value *V = alreadyVectorized(E->Scalars)) + return V; + Value *V = Builder.CreateSelect(Cond, True, False); E->VectorizedValue = V; return V; @@ -1281,6 +1306,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) { assert((VL0->getOperand(0) == VL0->getOperand(1)) && "Invalid order"); } + if (Value *V = alreadyVectorized(E->Scalars)) + return V; + BinaryOperator *BinOp = cast(VL0); Value *V = Builder.CreateBinOp(BinOp->getOpcode(), LHS, RHS); E->VectorizedValue = V; -- cgit v1.1