diff options
author | Nadav Rotem <nrotem@apple.com> | 2012-10-20 04:59:06 +0000 |
---|---|---|
committer | Nadav Rotem <nrotem@apple.com> | 2012-10-20 04:59:06 +0000 |
commit | e6748f91eaa69b91cc5c4081a45e013a251c2726 (patch) | |
tree | b04167d6d38951f195b1b73a0a045f470fda3bde /lib/Transforms/Vectorize/LoopVectorize.cpp | |
parent | 2dc1921e9b9cb379444f78d2998ef33495242a8d (diff) |
Vectorizer: refactor the memory checks to a new function. No functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166366 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Vectorize/LoopVectorize.cpp')
-rw-r--r-- | lib/Transforms/Vectorize/LoopVectorize.cpp | 84 |
1 files changed, 51 insertions, 33 deletions
diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index c0b709af8e..7866fcf04a 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -202,6 +202,12 @@ private: /// and we only need to check individual instructions. bool canVectorizeBlock(BasicBlock &BB); + /// When we vectorize loops we may change the order in which + /// we read and write from memory. This method checks if it is + /// legal to vectorize the code, considering only memory constrains. + /// Returns true if BB is vectorizable + bool canVectorizeMemory(BasicBlock &BB;) + // Check if a pointer value is known to be disjoint. // Example: Alloca, Global, NoAlias. bool isIdentifiedSafeObject(Value* Val); @@ -908,11 +914,7 @@ unsigned LoopVectorizationLegality::getLoopMaxVF() { } bool LoopVectorizationLegality::canVectorizeBlock(BasicBlock &BB) { - // Holds the read and write pointers that we find. - typedef SmallVector<Value*, 10> ValueVector; - ValueVector Reads; - ValueVector Writes; - + // Scan the instructions in the block and look for hazards. for (BasicBlock::iterator it = BB.begin(), e = BB.end(); it != e; ++it) { Instruction *I = it; @@ -960,34 +962,6 @@ bool LoopVectorizationLegality::canVectorizeBlock(BasicBlock &BB) { } }// end of PHI handling - // If this is a load, record its pointer. If it is not a load, abort. - // Notice that we don't handle function calls that read or write. - if (I->mayReadFromMemory()) { - LoadInst *Ld = dyn_cast<LoadInst>(I); - if (!Ld) return false; - if (!Ld->isSimple()) { - DEBUG(dbgs() << "LV: Found a non-simple load.\n"); - return false; - } - - Value* Ptr = Ld->getPointerOperand(); - GetUnderlyingObjects(Ptr, Reads, DL); - } - - // Record store pointers. Abort on all other instructions that write to - // memory. - if (I->mayWriteToMemory()) { - StoreInst *St = dyn_cast<StoreInst>(I); - if (!St) return false; - if (!St->isSimple()) { - DEBUG(dbgs() << "LV: Found a non-simple store.\n"); - return false; - } - - Value* Ptr = St->getPointerOperand(); - GetUnderlyingObjects(Ptr, Writes, DL); - } - // We still don't handle functions. CallInst *CI = dyn_cast<CallInst>(I); if (CI) { @@ -1024,6 +998,50 @@ bool LoopVectorizationLegality::canVectorizeBlock(BasicBlock &BB) { return false; } + // If the memory dependencies do not prevent us from + // vectorizing, then vectorize. + return canVectorizeMemory(BB); +} + +bool LoopVectorizationLegality::canVectorizeMemory(BasicBlock &BB) { + // Holds the read and write pointers that we find. + typedef SmallVector<Value*, 10> ValueVector; + ValueVector Reads; + ValueVector Writes; + + for (BasicBlock::iterator it = BB.begin(), e = BB.end(); it != e; ++it) { + Instruction *I = it; + + // If this is a load, record its pointer. If it is not a load, abort. + // Notice that we don't handle function calls that read or write. + if (I->mayReadFromMemory()) { + LoadInst *Ld = dyn_cast<LoadInst>(I); + if (!Ld) return false; + if (!Ld->isSimple()) { + DEBUG(dbgs() << "LV: Found a non-simple load.\n"); + return false; + } + + Value* Ptr = Ld->getPointerOperand(); + GetUnderlyingObjects(Ptr, Reads, DL); + } + + // Record store pointers. Abort on all other instructions that write to + // memory. + if (I->mayWriteToMemory()) { + StoreInst *St = dyn_cast<StoreInst>(I); + if (!St) return false; + if (!St->isSimple()) { + DEBUG(dbgs() << "LV: Found a non-simple store.\n"); + return false; + } + + Value* Ptr = St->getPointerOperand(); + GetUnderlyingObjects(Ptr, Writes, DL); + } + } // next instr. + + // Check that the underlying objects of the reads and writes are either // disjoint memory locations, or that they are no-alias arguments. ValueVector::iterator r, re, w, we; |