Skip to content
70 changes: 70 additions & 0 deletions llvm/lib/Transforms/Vectorize/VPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -3815,6 +3815,76 @@ template <>
struct CastInfo<VPPhiAccessors, const VPRecipeBase *>
: CastInfoVPPhiAccessors<const VPRecipeBase *> {};

/// Casting from VPRecipeBase -> VPIRMetadata is supported for all recipe types
/// implementing VPIRMetadata. Used by isa<> & co.
template <> struct CastIsPossible<VPIRMetadata, const VPRecipeBase *> {
static inline bool isPossible(const VPRecipeBase *R) {
return isa<VPInstruction, VPWidenRecipe, VPWidenCastRecipe,
VPWidenIntrinsicRecipe, VPWidenCallRecipe, VPWidenSelectRecipe,
VPReplicateRecipe, VPInterleaveRecipe, VPInterleaveEVLRecipe,
VPWidenLoadRecipe, VPWidenLoadEVLRecipe, VPWidenStoreRecipe,
VPWidenStoreEVLRecipe>(R);
Comment on lines +3920 to +3924
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to note at VPIRMetadata that any recipe inheriting from it should be listed here. Also for VPPhiAccessors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added thanks

}
};

/// Support casting from VPRecipeBase -> VPIRMetadata, by down-casting to the
/// recipe types implementing VPIRMetadata. Used by cast<>, dyn_cast<> & co.
template <typename SrcTy>
struct CastInfoVPIRMetadata : public CastIsPossible<VPIRMetadata, SrcTy> {

using Self = CastInfo<VPIRMetadata, SrcTy>;

/// doCast is used by cast<>.
static inline VPIRMetadata *doCast(SrcTy R) {
return const_cast<VPIRMetadata *>([R]() -> const VPIRMetadata * {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a bit odd. We potentially take a non-const SrcTy, cast it to a non-const VPInstruction, etc., then return const VPIRMetadata * from the lambda function, which then returns VPIRMetadata *. Why not just do

  return cast<VPIRMetadata *> ([R]() -> VPIRMetadata * {
    ...

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this was not 100% const-correct. I updated the patch to avoid this, by adding a templated castToVPIRMetadata, which can take care of both casting const * -> const *and non-const -> non-const.

Not sure if there's a nicer way to do that safely.

switch (R->getVPDefID()) {
case VPDef::VPInstructionSC:
return cast<VPInstruction>(R);
case VPDef::VPWidenSC:
return cast<VPWidenRecipe>(R);
case VPDef::VPWidenCastSC:
return cast<VPWidenCastRecipe>(R);
case VPDef::VPWidenIntrinsicSC:
return cast<VPWidenIntrinsicRecipe>(R);
case VPDef::VPWidenCallSC:
return cast<VPWidenCallRecipe>(R);
case VPDef::VPWidenSelectSC:
return cast<VPWidenSelectRecipe>(R);
case VPDef::VPReplicateSC:
return cast<VPReplicateRecipe>(R);
case VPDef::VPInterleaveSC:
return cast<VPInterleaveRecipe>(R);
case VPDef::VPInterleaveEVLSC:
return cast<VPInterleaveEVLRecipe>(R);
case VPDef::VPWidenLoadSC:
return cast<VPWidenLoadRecipe>(R);
case VPDef::VPWidenLoadEVLSC:
return cast<VPWidenLoadEVLRecipe>(R);
case VPDef::VPWidenStoreSC:
return cast<VPWidenStoreRecipe>(R);
case VPDef::VPWidenStoreEVLSC:
return cast<VPWidenStoreEVLRecipe>(R);
default:
llvm_unreachable("invalid recipe for VPIRMetadata cast");
}
}());
}

/// doCastIfPossible is used by dyn_cast<>.
static inline VPIRMetadata *doCastIfPossible(SrcTy f) {
if (!Self::isPossible(f))
return nullptr;
return doCast(f);
}
};

template <>
struct CastInfo<VPIRMetadata, VPRecipeBase *>
: CastInfoVPIRMetadata<VPRecipeBase *> {};
template <>
struct CastInfo<VPIRMetadata, const VPRecipeBase *>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't we casting from a const to a non-const pointer here - is this safe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(somehow my response seem to got lost, but that should be taken care of now)

: CastInfoVPIRMetadata<const VPRecipeBase *> {};

/// VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It
/// holds a sequence of zero or more VPRecipe's each representing a sequence of
/// output IR instructions. All PHI-like recipes must come before any non-PHI recipes.
Expand Down
Loading