@@ -282,6 +282,10 @@ struct VPTransformState {
282
282
// delegates the call to ILV below.
283
283
if (Data.PerPartOutput .count (Def)) {
284
284
auto *VecPart = Data.PerPartOutput [Def][Instance.Part ];
285
+ if (!VecPart->getType ()->isVectorTy ()) {
286
+ assert (Instance.Lane == 0 && " cannot get lane > 0 for scalar" );
287
+ return VecPart;
288
+ }
285
289
// TODO: Cache created scalar values.
286
290
return Builder.CreateExtractElement (VecPart,
287
291
Builder.getInt32 (Instance.Lane ));
@@ -298,6 +302,7 @@ struct VPTransformState {
298
302
}
299
303
Data.PerPartOutput [Def][Part] = V;
300
304
}
305
+ void set (VPValue *Def, Value *IRDef, Value *V, unsigned Part);
301
306
302
307
// / Hold state information used when constructing the CFG of the output IR,
303
308
// / traversing the VPBasicBlocks and generating corresponding IR BasicBlocks.
@@ -684,6 +689,20 @@ class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock> {
684
689
// / Returns a pointer to a VPValue, if the recipe inherits from VPValue or
685
690
// / nullptr otherwise.
686
691
VPValue *toVPValue ();
692
+ const VPValue *toVPValue () const ;
693
+
694
+ // / Returns the underlying instruction, if the recipe is a VPValue or nullptr
695
+ // / otherwise.
696
+ Instruction *getUnderlyingInstr () {
697
+ if (auto *VPV = toVPValue ())
698
+ return cast_or_null<Instruction>(VPV->getUnderlyingValue ());
699
+ return nullptr ;
700
+ }
701
+ const Instruction *getUnderlyingInstr () const {
702
+ if (auto *VPV = toVPValue ())
703
+ return cast_or_null<Instruction>(VPV->getUnderlyingValue ());
704
+ return nullptr ;
705
+ }
687
706
};
688
707
689
708
inline bool VPUser::classof (const VPRecipeBase *Recipe) {
@@ -725,10 +744,6 @@ class VPInstruction : public VPUser, public VPValue, public VPRecipeBase {
725
744
void generateInstruction (VPTransformState &State, unsigned Part);
726
745
727
746
protected:
728
- Instruction *getUnderlyingInstr () {
729
- return cast_or_null<Instruction>(getUnderlyingValue ());
730
- }
731
-
732
747
void setUnderlyingInstr (Instruction *I) { setUnderlyingValue (I); }
733
748
734
749
public:
@@ -1207,8 +1222,9 @@ class VPPredInstPHIRecipe : public VPRecipeBase {
1207
1222
// / - For store: Address, stored value, optional mask
1208
1223
// / TODO: We currently execute only per-part unless a specific instance is
1209
1224
// / provided.
1210
- class VPWidenMemoryInstructionRecipe : public VPRecipeBase , public VPUser {
1211
- Instruction &Instr;
1225
+ class VPWidenMemoryInstructionRecipe : public VPRecipeBase ,
1226
+ public VPValue,
1227
+ public VPUser {
1212
1228
1213
1229
void setMask (VPValue *Mask) {
1214
1230
if (!Mask)
@@ -1217,20 +1233,22 @@ class VPWidenMemoryInstructionRecipe : public VPRecipeBase, public VPUser {
1217
1233
}
1218
1234
1219
1235
bool isMasked () const {
1220
- return (isa<LoadInst>(Instr ) && getNumOperands () == 2 ) ||
1221
- (isa<StoreInst>(Instr ) && getNumOperands () == 3 );
1236
+ return (isa<LoadInst>(getUnderlyingInstr () ) && getNumOperands () == 2 ) ||
1237
+ (isa<StoreInst>(getUnderlyingInstr () ) && getNumOperands () == 3 );
1222
1238
}
1223
1239
1224
1240
public:
1225
1241
VPWidenMemoryInstructionRecipe (LoadInst &Load, VPValue *Addr, VPValue *Mask)
1226
- : VPRecipeBase(VPWidenMemoryInstructionSC), VPUser({Addr}), Instr(Load) {
1242
+ : VPRecipeBase(VPWidenMemoryInstructionSC),
1243
+ VPValue (VPValue::VPMemoryInstructionSC, &Load), VPUser({Addr}) {
1227
1244
setMask (Mask);
1228
1245
}
1229
1246
1230
1247
VPWidenMemoryInstructionRecipe (StoreInst &Store, VPValue *Addr,
1231
1248
VPValue *StoredValue, VPValue *Mask)
1232
- : VPRecipeBase(VPWidenMemoryInstructionSC), VPUser({Addr, StoredValue}),
1233
- Instr (Store) {
1249
+ : VPRecipeBase(VPWidenMemoryInstructionSC),
1250
+ VPValue(VPValue::VPMemoryInstructionSC, &Store),
1251
+ VPUser({Addr, StoredValue}) {
1234
1252
setMask (Mask);
1235
1253
}
1236
1254
@@ -1253,7 +1271,7 @@ class VPWidenMemoryInstructionRecipe : public VPRecipeBase, public VPUser {
1253
1271
1254
1272
// / Return the address accessed by this recipe.
1255
1273
VPValue *getStoredValue () const {
1256
- assert (isa<StoreInst>(Instr ) &&
1274
+ assert (isa<StoreInst>(getUnderlyingInstr () ) &&
1257
1275
" Stored value only available for store instructions" );
1258
1276
return getOperand (1 ); // Stored value is the 2nd, mandatory operand.
1259
1277
}
@@ -1619,6 +1637,10 @@ class VPlan {
1619
1637
// / VPlan.
1620
1638
Value2VPValueTy Value2VPValue;
1621
1639
1640
+ // / Contains all VPValues that been allocated by addVPValue directly and need
1641
+ // / to be free when the plan's destructor is called.
1642
+ SmallVector<VPValue *, 16 > VPValuesToFree;
1643
+
1622
1644
// / Holds the VPLoopInfo analysis for this VPlan.
1623
1645
VPLoopInfo VPLInfo;
1624
1646
@@ -1634,8 +1656,8 @@ class VPlan {
1634
1656
~VPlan () {
1635
1657
if (Entry)
1636
1658
VPBlockBase::deleteCFG (Entry);
1637
- for (auto &MapEntry : Value2VPValue )
1638
- delete MapEntry. second ;
1659
+ for (VPValue *VPV : VPValuesToFree )
1660
+ delete VPV ;
1639
1661
if (BackedgeTakenCount)
1640
1662
delete BackedgeTakenCount;
1641
1663
for (VPValue *Def : VPExternalDefs)
@@ -1685,7 +1707,24 @@ class VPlan {
1685
1707
void addVPValue (Value *V) {
1686
1708
assert (V && " Trying to add a null Value to VPlan" );
1687
1709
assert (!Value2VPValue.count (V) && " Value already exists in VPlan" );
1688
- Value2VPValue[V] = new VPValue (V);
1710
+ VPValue *VPV = new VPValue (V);
1711
+ Value2VPValue[V] = VPV;
1712
+ VPValuesToFree.push_back (VPV);
1713
+ }
1714
+
1715
+ void addVPValue (Value *V, VPValue *VPV) {
1716
+ assert (V && " Trying to add a null Value to VPlan" );
1717
+ assert (!Value2VPValue.count (V) && " Value already exists in VPlan" );
1718
+ Value2VPValue[V] = VPV;
1719
+ }
1720
+
1721
+ void addOrReplaceVPValue (Value *V, VPValue *VPV) {
1722
+ assert (V && " Trying to add a null Value to VPlan" );
1723
+ auto I = Value2VPValue.find (V);
1724
+ if (I == Value2VPValue.end ())
1725
+ Value2VPValue[V] = VPV;
1726
+ else
1727
+ I->second = VPV;
1689
1728
}
1690
1729
1691
1730
VPValue *getVPValue (Value *V) {
@@ -1701,6 +1740,8 @@ class VPlan {
1701
1740
return getVPValue (V);
1702
1741
}
1703
1742
1743
+ void removeVPValueFor (Value *V) { Value2VPValue.erase (V); }
1744
+
1704
1745
// / Return the VPLoopInfo analysis for this VPlan.
1705
1746
VPLoopInfo &getVPLoopInfo () { return VPLInfo; }
1706
1747
const VPLoopInfo &getVPLoopInfo () const { return VPLInfo; }
@@ -1782,9 +1823,9 @@ class VPlanPrinter {
1782
1823
};
1783
1824
1784
1825
struct VPlanIngredient {
1785
- Value *V;
1826
+ const Value *V;
1786
1827
1787
- VPlanIngredient (Value *V) : V(V) {}
1828
+ VPlanIngredient (const Value *V) : V(V) {}
1788
1829
};
1789
1830
1790
1831
inline raw_ostream &operator <<(raw_ostream &OS, const VPlanIngredient &I) {
0 commit comments