-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[VPlan] Support isa/dyn_cast from VPRecipeBase to VPIRMetadata (NFC). #166245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Implement CastInfo from VPRecipeBase to VPIRMetadata to support isa/dyn_Cast. This is similar to CastInfoVPPhiAccessors, supporting dyn_cast by down-casting to the concrete recipe types inheriting from VPIRMetadata. Can be used for more generalized VPIRMetadata printing following llvm#165825.
|
@llvm/pr-subscribers-vectorizers @llvm/pr-subscribers-llvm-transforms Author: Florian Hahn (fhahn) ChangesImplement CastInfo from VPRecipeBase to VPIRMetadata to support isa/dyn_Cast. This is similar to CastInfoVPPhiAccessors, supporting dyn_cast by down-casting to the concrete recipe types inheriting from VPIRMetadata. Can be used for more generalized VPIRMetadata printing following #165825. Full diff: https://github.com/llvm/llvm-project/pull/166245.diff 1 Files Affected:
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index cfe1f1e9d7528..2c47aa3f35e02 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -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);
+ }
+};
+
+/// 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 * {
+ 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 *>
+ : 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.
|
| struct CastInfo<VPIRMetadata, VPRecipeBase *> | ||
| : CastInfoVPIRMetadata<VPRecipeBase *> {}; | ||
| template <> | ||
| struct CastInfo<VPIRMetadata, const VPRecipeBase *> |
There was a problem hiding this comment.
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?
|
|
||
| /// doCast is used by cast<>. | ||
| static inline VPIRMetadata *doCast(SrcTy R) { | ||
| return const_cast<VPIRMetadata *>([R]() -> const VPIRMetadata * { |
There was a problem hiding this comment.
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 * {
...
?
Implement CastInfo from VPRecipeBase to VPIRMetadata to support isa/dyn_Cast. This is similar to CastInfoVPPhiAccessors, supporting dyn_cast by down-casting to the concrete recipe types inheriting from VPIRMetadata.
Can be used for more generalized VPIRMetadata printing following #165825.