diff options
Diffstat (limited to 'llvm/lib/Transforms/Vectorize/VPlan.h')
| -rw-r--r-- | llvm/lib/Transforms/Vectorize/VPlan.h | 76 |
1 files changed, 62 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index bdf09d15c27f..00ee31007cb7 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1312,7 +1312,7 @@ public: // The first operand is the address, followed by the stored values, followed // by an optional mask. return ArrayRef<VPValue *>(op_begin(), getNumOperands()) - .slice(1, getNumOperands() - (HasMask ? 2 : 1)); + .slice(1, getNumStoreOperands()); } /// Generate the wide load or store, and shuffles. @@ -1325,6 +1325,12 @@ public: #endif const InterleaveGroup<Instruction> *getInterleaveGroup() { return IG; } + + /// Returns the number of stored operands of this interleave group. Returns 0 + /// for load interleave groups. + unsigned getNumStoreOperands() const { + return getNumOperands() - (HasMask ? 2 : 1); + } }; /// A recipe to represent inloop reduction operations, performing a reduction on @@ -1508,6 +1514,12 @@ public: class VPWidenMemoryInstructionRecipe : public VPRecipeBase { Instruction &Ingredient; + // Whether the loaded-from / stored-to addresses are consecutive. + bool Consecutive; + + // Whether the consecutive loaded/stored addresses are in reverse order. + bool Reverse; + void setMask(VPValue *Mask) { if (!Mask) return; @@ -1519,16 +1531,21 @@ class VPWidenMemoryInstructionRecipe : public VPRecipeBase { } public: - VPWidenMemoryInstructionRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask) - : VPRecipeBase(VPWidenMemoryInstructionSC, {Addr}), Ingredient(Load) { + VPWidenMemoryInstructionRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask, + bool Consecutive, bool Reverse) + : VPRecipeBase(VPWidenMemoryInstructionSC, {Addr}), Ingredient(Load), + Consecutive(Consecutive), Reverse(Reverse) { + assert((Consecutive || !Reverse) && "Reverse implies consecutive"); new VPValue(VPValue::VPVMemoryInstructionSC, &Load, this); setMask(Mask); } VPWidenMemoryInstructionRecipe(StoreInst &Store, VPValue *Addr, - VPValue *StoredValue, VPValue *Mask) + VPValue *StoredValue, VPValue *Mask, + bool Consecutive, bool Reverse) : VPRecipeBase(VPWidenMemoryInstructionSC, {Addr, StoredValue}), - Ingredient(Store) { + Ingredient(Store), Consecutive(Consecutive), Reverse(Reverse) { + assert((Consecutive || !Reverse) && "Reverse implies consecutive"); setMask(Mask); } @@ -1558,6 +1575,13 @@ public: return getOperand(1); // Stored value is the 2nd, mandatory operand. } + // Return whether the loaded-from / stored-to addresses are consecutive. + bool isConsecutive() const { return Consecutive; } + + // Return whether the consecutive loaded/stored addresses are in reverse + // order. + bool isReverse() const { return Reverse; } + /// Generate the wide load/store. void execute(VPTransformState &State) override; @@ -1569,11 +1593,11 @@ public: }; /// A Recipe for widening the canonical induction variable of the vector loop. -class VPWidenCanonicalIVRecipe : public VPRecipeBase { +class VPWidenCanonicalIVRecipe : public VPRecipeBase, public VPValue { public: - VPWidenCanonicalIVRecipe() : VPRecipeBase(VPWidenCanonicalIVSC, {}) { - new VPValue(nullptr, this); - } + VPWidenCanonicalIVRecipe() + : VPRecipeBase(VPWidenCanonicalIVSC, {}), + VPValue(VPValue::VPVWidenCanonicalIVSC, nullptr, this) {} ~VPWidenCanonicalIVRecipe() override = default; @@ -2094,6 +2118,10 @@ class VPlan { /// Holds the VPLoopInfo analysis for this VPlan. VPLoopInfo VPLInfo; + /// Indicates whether it is safe use the Value2VPValue mapping or if the + /// mapping cannot be used any longer, because it is stale. + bool Value2VPValueEnabled = true; + public: VPlan(VPBlockBase *Entry = nullptr) : Entry(Entry) { if (Entry) @@ -2135,6 +2163,10 @@ public: return BackedgeTakenCount; } + /// Mark the plan to indicate that using Value2VPValue is not safe any + /// longer, because it may be stale. + void disableValue2VPValue() { Value2VPValueEnabled = false; } + void addVF(ElementCount VF) { VFs.insert(VF); } bool hasVF(ElementCount VF) { return VFs.count(VF); } @@ -2148,6 +2180,8 @@ public: void addExternalDef(VPValue *VPVal) { VPExternalDefs.insert(VPVal); } void addVPValue(Value *V) { + assert(Value2VPValueEnabled && + "IR value to VPValue mapping may be out of date!"); assert(V && "Trying to add a null Value to VPlan"); assert(!Value2VPValue.count(V) && "Value already exists in VPlan"); VPValue *VPV = new VPValue(V); @@ -2156,25 +2190,39 @@ public: } void addVPValue(Value *V, VPValue *VPV) { + assert(Value2VPValueEnabled && "Value2VPValue mapping may be out of date!"); assert(V && "Trying to add a null Value to VPlan"); assert(!Value2VPValue.count(V) && "Value already exists in VPlan"); Value2VPValue[V] = VPV; } - VPValue *getVPValue(Value *V) { + /// Returns the VPValue for \p V. \p OverrideAllowed can be used to disable + /// checking whether it is safe to query VPValues using IR Values. + VPValue *getVPValue(Value *V, bool OverrideAllowed = false) { + assert((OverrideAllowed || isa<Constant>(V) || Value2VPValueEnabled) && + "Value2VPValue mapping may be out of date!"); assert(V && "Trying to get the VPValue of a null Value"); assert(Value2VPValue.count(V) && "Value does not exist in VPlan"); return Value2VPValue[V]; } - VPValue *getOrAddVPValue(Value *V) { + /// Gets the VPValue or adds a new one (if none exists yet) for \p V. \p + /// OverrideAllowed can be used to disable checking whether it is safe to + /// query VPValues using IR Values. + VPValue *getOrAddVPValue(Value *V, bool OverrideAllowed = false) { + assert((OverrideAllowed || isa<Constant>(V) || Value2VPValueEnabled) && + "Value2VPValue mapping may be out of date!"); assert(V && "Trying to get or add the VPValue of a null Value"); if (!Value2VPValue.count(V)) addVPValue(V); return getVPValue(V); } - void removeVPValueFor(Value *V) { Value2VPValue.erase(V); } + void removeVPValueFor(Value *V) { + assert(Value2VPValueEnabled && + "IR value to VPValue mapping may be out of date!"); + Value2VPValue.erase(V); + } /// Return the VPLoopInfo analysis for this VPlan. VPLoopInfo &getVPLoopInfo() { return VPLInfo; } @@ -2244,9 +2292,9 @@ class VPlanPrinter { return BlockID.count(Block) ? BlockID[Block] : BlockID[Block] = BID++; } - const Twine getOrCreateName(const VPBlockBase *Block); + Twine getOrCreateName(const VPBlockBase *Block); - const Twine getUID(const VPBlockBase *Block); + Twine getUID(const VPBlockBase *Block); /// Print the information related to a CFG edge between two VPBlockBases. void drawEdge(const VPBlockBase *From, const VPBlockBase *To, bool Hidden, |
