diff options
author | Diego Caballero <diego.caballero@intel.com> | 2018-05-17 19:24:47 +0000 |
---|---|---|
committer | Diego Caballero <diego.caballero@intel.com> | 2018-05-17 19:24:47 +0000 |
commit | f58ad3129c874aeda40ce720a0aede59480e02d6 (patch) | |
tree | a2eb0b76b5f3549a7af3fe766e160b4a294602b9 /llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h | |
parent | bc471c39eed35e82d6c39ca28e6e7d78029ee59c (diff) | |
download | bcm5719-llvm-f58ad3129c874aeda40ce720a0aede59480e02d6.tar.gz bcm5719-llvm-f58ad3129c874aeda40ce720a0aede59480e02d6.zip |
[LV][VPlan] Build plain CFG with simple VPInstructions for outer loops.
Patch #3 from VPlan Outer Loop Vectorization Patch Series #1
(RFC: http://lists.llvm.org/pipermail/llvm-dev/2017-December/119523.html).
Expected to be NFC for the current inner loop vectorization path. It
introduces the basic algorithm to build the VPlan plain CFG (single-level
CFG, no hierarchical CFG (H-CFG), yet) in the VPlan-native vectorization
path using VPInstructions. It includes:
- VPlanHCFGBuilder: Main class to build the VPlan H-CFG (plain CFG without nested regions, for now).
- VPlanVerifier: Main class with utilities to check the consistency of a H-CFG.
- VPlanBlockUtils: Main class with utilities to manipulate VPBlockBases in VPlan.
Reviewers: rengolin, fhahn, mkuper, mssimpso, a.elovikov, hfinkel, aprantl.
Differential Revision: https://reviews.llvm.org/D44338
llvm-svn: 332654
Diffstat (limited to 'llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h')
-rw-r--r-- | llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h | 101 |
1 files changed, 96 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h index 304bc7ab57b..70629cb35d2 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h +++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h @@ -39,23 +39,94 @@ private: VPBasicBlock::iterator InsertPt = VPBasicBlock::iterator(); VPInstruction *createInstruction(unsigned Opcode, - std::initializer_list<VPValue *> Operands) { + ArrayRef<VPValue *> Operands) { VPInstruction *Instr = new VPInstruction(Opcode, Operands); - BB->insert(Instr, InsertPt); + if (BB) + BB->insert(Instr, InsertPt); return Instr; } + VPInstruction *createInstruction(unsigned Opcode, + std::initializer_list<VPValue *> Operands) { + return createInstruction(Opcode, ArrayRef<VPValue *>(Operands)); + } + public: VPBuilder() {} - /// This specifies that created VPInstructions should be appended to - /// the end of the specified block. + /// Clear the insertion point: created instructions will not be inserted into + /// a block. + void clearInsertionPoint() { + BB = nullptr; + InsertPt = VPBasicBlock::iterator(); + } + + VPBasicBlock *getInsertBlock() const { return BB; } + VPBasicBlock::iterator getInsertPoint() const { return InsertPt; } + + /// InsertPoint - A saved insertion point. + class VPInsertPoint { + VPBasicBlock *Block = nullptr; + VPBasicBlock::iterator Point; + + public: + /// Creates a new insertion point which doesn't point to anything. + VPInsertPoint() = default; + + /// Creates a new insertion point at the given location. + VPInsertPoint(VPBasicBlock *InsertBlock, VPBasicBlock::iterator InsertPoint) + : Block(InsertBlock), Point(InsertPoint) {} + + /// Returns true if this insert point is set. + bool isSet() const { return Block != nullptr; } + + VPBasicBlock *getBlock() const { return Block; } + VPBasicBlock::iterator getPoint() const { return Point; } + }; + + /// Sets the current insert point to a previously-saved location. + void restoreIP(VPInsertPoint IP) { + if (IP.isSet()) + setInsertPoint(IP.getBlock(), IP.getPoint()); + else + clearInsertionPoint(); + } + + /// This specifies that created VPInstructions should be appended to the end + /// of the specified block. void setInsertPoint(VPBasicBlock *TheBB) { assert(TheBB && "Attempting to set a null insert point"); BB = TheBB; InsertPt = BB->end(); } + /// This specifies that created instructions should be inserted at the + /// specified point. + void setInsertPoint(VPBasicBlock *TheBB, VPBasicBlock::iterator IP) { + BB = TheBB; + InsertPt = IP; + } + + /// Insert and return the specified instruction. + VPInstruction *insert(VPInstruction *I) const { + BB->insert(I, InsertPt); + return I; + } + + /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as + /// its underlying Instruction. + VPValue *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands, + Instruction *Inst = nullptr) { + VPInstruction *NewVPInst = createInstruction(Opcode, Operands); + NewVPInst->setUnderlyingValue(Inst); + return NewVPInst; + } + VPValue *createNaryOp(unsigned Opcode, + std::initializer_list<VPValue *> Operands, + Instruction *Inst = nullptr) { + return createNaryOp(Opcode, ArrayRef<VPValue *>(Operands), Inst); + } + VPValue *createNot(VPValue *Operand) { return createInstruction(VPInstruction::Not, {Operand}); } @@ -67,8 +138,28 @@ public: VPValue *createOr(VPValue *LHS, VPValue *RHS) { return createInstruction(Instruction::BinaryOps::Or, {LHS, RHS}); } -}; + //===--------------------------------------------------------------------===// + // RAII helpers. + //===--------------------------------------------------------------------===// + + /// RAII object that stores the current insertion point and restores it when + /// the object is destroyed. + class InsertPointGuard { + VPBuilder &Builder; + VPBasicBlock *Block; + VPBasicBlock::iterator Point; + + public: + InsertPointGuard(VPBuilder &B) + : Builder(B), Block(B.getInsertBlock()), Point(B.getInsertPoint()) {} + + InsertPointGuard(const InsertPointGuard &) = delete; + InsertPointGuard &operator=(const InsertPointGuard &) = delete; + + ~InsertPointGuard() { Builder.restoreIP(VPInsertPoint(Block, Point)); } + }; +}; /// TODO: The following VectorizationFactor was pulled out of /// LoopVectorizationCostModel class. LV also deals with |