-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[VPlan] Implement printing VPIRMetadata. #168385
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
|
@llvm/pr-subscribers-vectorizers @llvm/pr-subscribers-llvm-transforms Author: Florian Hahn (fhahn) Changesmplement printing for VPIRMetadata, using generic dyn_cast to VPIRMetadata. Depends on #166245 (included in the PR) Full diff: https://github.com/llvm/llvm-project/pull/168385.diff 5 Files Affected:
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 13131a2b61722..e1fbce731c31c 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -983,6 +983,11 @@ class VPIRMetadata {
/// Intersect this VPIRMetada object with \p MD, keeping only metadata
/// nodes that are common to both.
void intersect(const VPIRMetadata &MD);
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ /// Print metadata with node IDs.
+ void print(raw_ostream &O, const Module &M) const;
+#endif
};
/// This is a concrete Recipe that models a single VPlan-level instruction.
@@ -3869,6 +3874,77 @@ 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.
+namespace detail {
+/// Returns const VPIRMetadata* if input is const, and VPIRMetadata* otherwise.
+template <typename RecipeBasePtrTy>
+static inline auto castToVPIRMetadata(RecipeBasePtrTy R) -> std::conditional_t<
+ std::is_const_v<std::remove_pointer_t<RecipeBasePtrTy>>,
+ const VPIRMetadata *, 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");
+ }
+}
+} // namespace detail
+
+/// 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> {
+ static inline bool isPossible(SrcTy R) {
+ return isa<VPInstruction, VPWidenRecipe, VPWidenCastRecipe,
+ VPWidenIntrinsicRecipe, VPWidenCallRecipe, VPWidenSelectRecipe,
+ VPReplicateRecipe, VPInterleaveRecipe, VPInterleaveEVLRecipe,
+ VPWidenLoadRecipe, VPWidenLoadEVLRecipe, VPWidenStoreRecipe,
+ VPWidenStoreEVLRecipe>(R);
+ }
+
+ using Self = CastInfo<VPIRMetadata, SrcTy>;
+ using RetTy = decltype(detail::castToVPIRMetadata(std::declval<SrcTy>()));
+
+ static inline RetTy doCast(SrcTy R) { return detail::castToVPIRMetadata(R); }
+
+ static inline RetTy doCastIfPossible(SrcTy R) {
+ if (!Self::isPossible(R))
+ return nullptr;
+ return doCast(R);
+ }
+};
+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.
@@ -4333,6 +4409,11 @@ class VPlan {
/// Return the VPIRBasicBlock wrapping the header of the scalar loop.
VPIRBasicBlock *getScalarHeader() const { return ScalarHeader; }
+ /// Return the Module from the scalar header.
+ const Module &getModule() const {
+ return *ScalarHeader->getIRBasicBlock()->getModule();
+ }
+
/// Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of
/// the original scalar loop.
ArrayRef<VPIRBasicBlock *> getExitBlocks() const { return ExitBlocks; }
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index cf95b4eac9d75..246292b9d9d61 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -489,6 +489,9 @@ void VPSingleDefRecipe::dump() const { VPDef::dump(); }
void VPRecipeBase::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
printRecipe(O, Indent, SlotTracker);
+
+ if (auto *Metadata = dyn_cast<VPIRMetadata>(this))
+ Metadata->print(O, getParent()->getPlan()->getModule());
}
#endif
@@ -1703,6 +1706,27 @@ void VPIRMetadata::intersect(const VPIRMetadata &Other) {
Metadata = std::move(MetadataIntersection);
}
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+void VPIRMetadata::print(raw_ostream &O, const Module &M) const {
+ if (Metadata.empty())
+ return;
+
+ SmallVector<StringRef, 8> MDNames;
+ M.getContext().getMDKindNames(MDNames);
+
+ O << " (";
+ interleaveComma(Metadata, O, [&](const auto &KindNodePair) {
+ auto [Kind, Node] = KindNodePair;
+ assert(Kind != 0 && "Debug metadata should not be managed by VPIRMetadata");
+ assert(Kind < MDNames.size() && !MDNames[Kind].empty() &&
+ "Unexpected unnamed metadata kind");
+ O << "!" << MDNames[Kind] << " ";
+ Node->printAsOperand(O, &M);
+ });
+ O << ")";
+}
+#endif
+
void VPWidenCallRecipe::execute(VPTransformState &State) {
assert(State.VF.isVector() && "not widening");
assert(Variant != nullptr && "Can't create vector function.");
diff --git a/llvm/test/Transforms/LoopVectorize/vplan-printing-metadata.ll b/llvm/test/Transforms/LoopVectorize/vplan-printing-metadata.ll
index 857b9131a0b8c..fb49e94ee67bc 100644
--- a/llvm/test/Transforms/LoopVectorize/vplan-printing-metadata.ll
+++ b/llvm/test/Transforms/LoopVectorize/vplan-printing-metadata.ll
@@ -7,11 +7,11 @@ define void @test_widen_metadata(ptr noalias %A, ptr noalias %B, i32 %n) {
; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
; CHECK: <x1> vector loop: {
; CHECK: vector.body:
-; CHECK: WIDEN ir<%lv> = load vp<{{.*}}>
-; CHECK: WIDEN-CAST ir<%conv> = sitofp ir<%lv> to float
-; CHECK: WIDEN ir<%mul> = fmul ir<%conv>, ir<2.000000e+00>
+; CHECK: WIDEN ir<%lv> = load vp<{{.*}}> (!tbaa !{{[0-9]+}})
+; CHECK: WIDEN-CAST ir<%conv> = sitofp ir<%lv> to float (!fpmath !{{[0-9]+}})
+; CHECK: WIDEN ir<%mul> = fmul ir<%conv>, ir<2.000000e+00> (!fpmath !{{[0-9]+}})
; CHECK: WIDEN-CAST ir<%conv.back> = fptosi ir<%mul> to i32
-; CHECK: WIDEN store vp<{{.*}}>, ir<%conv.back>
+; CHECK: WIDEN store vp<{{.*}}>, ir<%conv.back> (!tbaa !{{[0-9]+}})
;
entry:
br label %loop
@@ -40,9 +40,9 @@ define void @test_intrinsic_with_metadata(ptr noalias %A, ptr noalias %B, i32 %n
; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
; CHECK: <x1> vector loop: {
; CHECK: vector.body:
-; CHECK: WIDEN ir<%lv> = load vp<{{.*}}>
-; CHECK: WIDEN-INTRINSIC ir<%sqrt> = call llvm.sqrt(ir<%lv>)
-; CHECK: WIDEN store vp<{{.*}}>, ir<%sqrt>
+; CHECK: WIDEN ir<%lv> = load vp<{{.*}}> (!tbaa !{{[0-9]+}})
+; CHECK: WIDEN-INTRINSIC ir<%sqrt> = call llvm.sqrt(ir<%lv>) (!fpmath !{{[0-9]+}})
+; CHECK: WIDEN store vp<{{.*}}>, ir<%sqrt> (!tbaa !{{[0-9]+}})
;
entry:
br label %loop
@@ -67,11 +67,11 @@ define void @test_widen_with_multiple_metadata(ptr noalias %A, ptr noalias %B, i
; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
; CHECK: <x1> vector loop: {
; CHECK: vector.body:
-; CHECK: WIDEN ir<%lv> = load vp<{{.*}}>
+; CHECK: WIDEN ir<%lv> = load vp<{{.*}}> (!tbaa !{{[0-9]+}})
; CHECK: WIDEN-CAST ir<%conv> = sitofp ir<%lv> to float
; CHECK: WIDEN ir<%mul> = fmul ir<%conv>, ir<2.000000e+00>
; CHECK: WIDEN-CAST ir<%conv.back> = fptosi ir<%mul> to i32
-; CHECK: WIDEN store vp<{{.*}}>, ir<%conv.back>
+; CHECK: WIDEN store vp<{{.*}}>, ir<%conv.back> (!tbaa !{{[0-9]+}})
;
entry:
br label %loop
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index ee7fa175ca918..7cea64625fe5f 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -743,8 +743,10 @@ TEST_F(VPBasicBlockTest, print) {
VPBB2->setName("bb2");
VPBlockUtils::connectBlocks(VPBB1, VPBB2);
+ VPBlockUtils::connectBlocks(VPBB2, Plan.getScalarHeader());
+ VPBlockUtils::connectBlocks(VPBB0, VPBB1);
- // Check printing an instruction without associated VPlan.
+ // Check printing an instruction with associated VPlan.
{
std::string I3Dump;
raw_string_ostream OS(I3Dump);
@@ -753,8 +755,6 @@ TEST_F(VPBasicBlockTest, print) {
EXPECT_EQ("EMIT store <badref>, <badref>", I3Dump);
}
- VPBlockUtils::connectBlocks(VPBB2, Plan.getScalarHeader());
- VPBlockUtils::connectBlocks(VPBB0, VPBB1);
std::string FullDump;
raw_string_ostream OS(FullDump);
Plan.printDOT(OS);
@@ -996,7 +996,7 @@ TEST_F(VPRecipeTest, CastVPInstructionToVPUser) {
VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
VPInstruction Recipe(Instruction::Add, {Op1, Op2});
- checkVPRecipeCastImpl<VPInstruction, VPUser>(&Recipe);
+ checkVPRecipeCastImpl<VPInstruction, VPUser, VPIRMetadata>(&Recipe);
}
TEST_F(VPRecipeTest, CastVPWidenRecipeToVPUser) {
@@ -1011,7 +1011,7 @@ TEST_F(VPRecipeTest, CastVPWidenRecipeToVPUser) {
Args.push_back(Op2);
VPWidenRecipe WidenR(*AI, make_range(Args.begin(), Args.end()));
- checkVPRecipeCastImpl<VPWidenRecipe, VPUser>(&WidenR);
+ checkVPRecipeCastImpl<VPWidenRecipe, VPUser, VPIRMetadata>(&WidenR);
delete AI;
}
@@ -1030,7 +1030,7 @@ TEST_F(VPRecipeTest, CastVPWidenCallRecipeToVPUserAndVPDef) {
Args.push_back(CalledFn);
VPWidenCallRecipe Recipe(Call, Fn, Args);
- checkVPRecipeCastImpl<VPWidenCallRecipe, VPUser>(&Recipe);
+ checkVPRecipeCastImpl<VPWidenCallRecipe, VPUser, VPIRMetadata>(&Recipe);
VPValue *VPV = &Recipe;
EXPECT_TRUE(VPV->getDefiningRecipe());
@@ -1056,7 +1056,8 @@ TEST_F(VPRecipeTest, CastVPWidenSelectRecipeToVPUserAndVPDef) {
VPWidenSelectRecipe WidenSelectR(*SelectI,
make_range(Args.begin(), Args.end()));
- checkVPRecipeCastImpl<VPWidenSelectRecipe, VPUser>(&WidenSelectR);
+ checkVPRecipeCastImpl<VPWidenSelectRecipe, VPUser, VPIRMetadata>(
+ &WidenSelectR);
VPValue *VPV = &WidenSelectR;
EXPECT_EQ(&WidenSelectR, VPV->getDefiningRecipe());
@@ -1094,7 +1095,7 @@ TEST_F(VPRecipeTest, CastVPWidenCastRecipeToVPUser) {
VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
VPWidenCastRecipe Recipe(Instruction::ZExt, Op1, Int64, *Cast);
- checkVPRecipeCastImpl<VPWidenCastRecipe, VPUser>(&Recipe);
+ checkVPRecipeCastImpl<VPWidenCastRecipe, VPUser, VPIRMetadata>(&Recipe);
delete Cast;
}
@@ -1105,7 +1106,7 @@ TEST_F(VPRecipeTest, CastVPWidenIntrinsicRecipeToVPUser) {
VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
VPWidenIntrinsicRecipe Recipe(Intrinsic::smax, {Op1, Op2}, Int32);
- checkVPRecipeCastImpl<VPWidenIntrinsicRecipe, VPUser>(&Recipe);
+ checkVPRecipeCastImpl<VPWidenIntrinsicRecipe, VPUser, VPIRMetadata>(&Recipe);
}
TEST_F(VPRecipeTest, CastVPBlendRecipeToVPUser) {
@@ -1135,7 +1136,7 @@ TEST_F(VPRecipeTest, CastVPInterleaveRecipeToVPUser) {
InterleaveGroup<Instruction> IG(4, false, Align(4));
VPInterleaveRecipe Recipe(&IG, Addr, {}, Mask, false, {}, DebugLoc());
- checkVPRecipeCastImpl<VPInterleaveRecipe, VPUser>(&Recipe);
+ checkVPRecipeCastImpl<VPInterleaveRecipe, VPUser, VPIRMetadata>(&Recipe);
}
TEST_F(VPRecipeTest, CastVPReplicateRecipeToVPUser) {
@@ -1151,7 +1152,7 @@ TEST_F(VPRecipeTest, CastVPReplicateRecipeToVPUser) {
auto *Call = CallInst::Create(FTy, PoisonValue::get(FTy));
VPReplicateRecipe Recipe(Call, make_range(Args.begin(), Args.end()), true);
- checkVPRecipeCastImpl<VPReplicateRecipe, VPUser>(&Recipe);
+ checkVPRecipeCastImpl<VPReplicateRecipe, VPUser, VPIRMetadata>(&Recipe);
delete Call;
}
@@ -1175,7 +1176,7 @@ TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) {
VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
VPWidenLoadRecipe Recipe(*Load, Addr, Mask, true, false, {}, {});
- checkVPRecipeCastImpl<VPWidenLoadRecipe, VPUser>(&Recipe);
+ checkVPRecipeCastImpl<VPWidenLoadRecipe, VPUser, VPIRMetadata>(&Recipe);
VPValue *VPV = Recipe.getVPSingleValue();
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe()));
@@ -1194,7 +1195,7 @@ TEST_F(VPRecipeTest, CastVPInterleaveEVLRecipeToVPUser) {
VPInterleaveRecipe BaseRecipe(&IG, Addr, {}, Mask, false, {}, DebugLoc());
VPInterleaveEVLRecipe Recipe(BaseRecipe, *EVL, Mask);
- checkVPRecipeCastImpl<VPInterleaveEVLRecipe, VPUser>(&Recipe);
+ checkVPRecipeCastImpl<VPInterleaveEVLRecipe, VPUser, VPIRMetadata>(&Recipe);
}
TEST_F(VPRecipeTest, CastVPWidenLoadEVLRecipeToVPUser) {
@@ -1209,7 +1210,7 @@ TEST_F(VPRecipeTest, CastVPWidenLoadEVLRecipeToVPUser) {
VPWidenLoadRecipe BaseLoad(*Load, Addr, Mask, true, false, {}, {});
VPWidenLoadEVLRecipe Recipe(BaseLoad, Addr, *EVL, Mask);
- checkVPRecipeCastImpl<VPWidenLoadEVLRecipe, VPUser>(&Recipe);
+ checkVPRecipeCastImpl<VPWidenLoadEVLRecipe, VPUser, VPIRMetadata>(&Recipe);
delete Load;
}
@@ -1225,7 +1226,7 @@ TEST_F(VPRecipeTest, CastVPWidenStoreRecipeToVPUser) {
VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
VPWidenStoreRecipe Recipe(*Store, Addr, StoredVal, Mask, true, false, {}, {});
- checkVPRecipeCastImpl<VPWidenStoreRecipe, VPUser>(&Recipe);
+ checkVPRecipeCastImpl<VPWidenStoreRecipe, VPUser, VPIRMetadata>(&Recipe);
delete Store;
}
@@ -1244,7 +1245,7 @@ TEST_F(VPRecipeTest, CastVPWidenStoreEVLRecipeToVPUser) {
{});
VPWidenStoreEVLRecipe Recipe(BaseStore, Addr, *EVL, Mask);
- checkVPRecipeCastImpl<VPWidenStoreEVLRecipe, VPUser>(&Recipe);
+ checkVPRecipeCastImpl<VPWidenStoreEVLRecipe, VPUser, VPIRMetadata>(&Recipe);
delete Store;
}
@@ -1611,12 +1612,18 @@ TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesNotInPlanOrBlock) {
auto *AI = BinaryOperator::CreateAdd(PoisonValue::get(Int32),
PoisonValue::get(Int32));
AI->setName("a");
- VPValue *ExtVPV1 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1));
- VPValue *ExtVPV2 = getPlan().getOrAddLiveIn(AI);
+ VPlan &Plan = getPlan();
+ VPValue *ExtVPV1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
+ VPValue *ExtVPV2 = Plan.getOrAddLiveIn(AI);
VPInstruction *I1 = new VPInstruction(Instruction::Add, {ExtVPV1, ExtVPV2});
VPInstruction *I2 = new VPInstruction(Instruction::Mul, {I1, I1});
+ // Add instructions to a block in the plan so they have access to Module
+ VPBasicBlock *VPBB = Plan.getEntry();
+ VPBB->appendRecipe(I1);
+ VPBB->appendRecipe(I2);
+
// Check printing I1.
{
// Use EXPECT_EXIT to capture stderr and compare against expected output.
@@ -1628,7 +1635,7 @@ TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesNotInPlanOrBlock) {
VPV->dump();
exit(0);
},
- testing::ExitedWithCode(0), "EMIT <badref> = add ir<1>, ir<%a>");
+ testing::ExitedWithCode(0), "EMIT vp<%1> = add ir<1>, ir<%a>");
// Test VPRecipeBase::dump().
VPRecipeBase *R = I1;
@@ -1637,7 +1644,7 @@ TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesNotInPlanOrBlock) {
R->dump();
exit(0);
},
- testing::ExitedWithCode(0), "EMIT <badref> = add ir<1>, ir<%a>");
+ testing::ExitedWithCode(0), "EMIT vp<%1> = add ir<1>, ir<%a>");
// Test VPDef::dump().
VPDef *D = I1;
@@ -1646,7 +1653,7 @@ TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesNotInPlanOrBlock) {
D->dump();
exit(0);
},
- testing::ExitedWithCode(0), "EMIT <badref> = add ir<1>, ir<%a>");
+ testing::ExitedWithCode(0), "EMIT vp<%1> = add ir<1>, ir<%a>");
}
// Check printing I2.
{
@@ -1659,7 +1666,7 @@ TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesNotInPlanOrBlock) {
VPV->dump();
exit(0);
},
- testing::ExitedWithCode(0), "EMIT <badref> = mul <badref>, <badref>");
+ testing::ExitedWithCode(0), "EMIT vp<%2> = mul vp<%1>, vp<%1>");
// Test VPRecipeBase::dump().
VPRecipeBase *R = I2;
@@ -1668,7 +1675,7 @@ TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesNotInPlanOrBlock) {
R->dump();
exit(0);
},
- testing::ExitedWithCode(0), "EMIT <badref> = mul <badref>, <badref>");
+ testing::ExitedWithCode(0), "EMIT vp<%2> = mul vp<%1>, vp<%1>");
// Test VPDef::dump().
VPDef *D = I2;
@@ -1677,11 +1684,9 @@ TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesNotInPlanOrBlock) {
D->dump();
exit(0);
},
- testing::ExitedWithCode(0), "EMIT <badref> = mul <badref>, <badref>");
+ testing::ExitedWithCode(0), "EMIT vp<%2> = mul vp<%1>, vp<%1>");
}
- delete I2;
- delete I1;
delete AI;
}
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h b/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
index 21090c0716d46..84bf3b60b0296 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
@@ -86,11 +86,18 @@ class VPlanTestIRBase : public testing::Test {
class VPlanTestBase : public testing::Test {
protected:
LLVMContext C;
- std::unique_ptr<BasicBlock> ScalarHeader;
+ std::unique_ptr<Module> M;
+ Function *F;
+ BasicBlock *ScalarHeader;
SmallVector<std::unique_ptr<VPlan>> Plans;
- VPlanTestBase() : ScalarHeader(BasicBlock::Create(C, "scalar.header")) {
- BranchInst::Create(&*ScalarHeader, &*ScalarHeader);
+ VPlanTestBase() {
+ M = std::make_unique<Module>("VPlanTest", C);
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), false);
+ F = Function::Create(FTy, GlobalValue::ExternalLinkage, "test_function",
+ M.get());
+ ScalarHeader = BasicBlock::Create(C, "scalar.header", F);
+ BranchInst::Create(ScalarHeader, ScalarHeader);
}
VPlan &getPlan() {
|
beae906 to
96de4eb
Compare
🐧 Linux x64 Test Results
|
96de4eb to
6c155f6
Compare
Implement and use debug printing for VPIRMetadata.
6c155f6 to
279213b
Compare
| ; CHECK: WIDEN ir<%lv> = load vp<{{.*}}> | ||
| ; CHECK: WIDEN-CAST ir<%conv> = sitofp ir<%lv> to float | ||
| ; CHECK: WIDEN ir<%mul> = fmul ir<%conv>, ir<2.000000e+00> | ||
| ; CHECK: WIDEN ir<%lv> = load vp<{{.*}}> (!tbaa !{{[0-9]+}}) |
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.
Is it worth also changing the RUN line to generate CHECK lines for the attributes so that we can verify they are as expected?
|
|
||
| #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||
| void VPIRMetadata::print(raw_ostream &O, const VPlan *Plan) const { | ||
| if (Metadata.empty() || !Plan) |
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.
Can we ever be in a situation where Plan is nullptr? It looks like the only place we call this is when the parent VPBasicBlock is non-null, so that must mean the Plan is non-null too I think?
| VPIRBasicBlock *getScalarHeader() const { return ScalarHeader; } | ||
|
|
||
| /// Return the Module from the scalar header. | ||
| const Module &getModule() const { |
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.
Given this is only used in one place is it worth adding this function? Not sure if it would be used elsewhere though.
|
|
||
| const Module &M = Plan->getModule(); | ||
| SmallVector<StringRef, 8> MDNames; | ||
| M.getContext().getMDKindNames(MDNames); |
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.
Isn't this quite an expensive operation? Would be great if there was a way to only do this once, although I realise that might be tricky.
| interleaveComma(Metadata, O, [&](const auto &KindNodePair) { | ||
| auto [Kind, Node] = KindNodePair; | ||
| assert(Kind != 0 && "Debug metadata should not be managed by VPIRMetadata"); | ||
| assert(Kind < MDNames.size() && !MDNames[Kind].empty() && |
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.
I wonder if these checks should actually live somewhere in the vplan verifier, rather than only checking when someone is dumping the recipe?
mplement printing for VPIRMetadata, using generic dyn_cast to VPIRMetadata.
Depends on #166245 (included in the PR)