Skip to content

Commit eb0371e

Browse files
committed
[VPlan] Unify value/recipe printing after VPDef transition.
This patch unifies the way recipes and VPValues are printed after the transition to VPDef. VPSlotTracker has been updated to iterate over all recipes and all their defined values to number those. There is no need to number values in Value2VPValue. It also updates a few places that only used slot numbers for VPInstruction. All recipes now can produce numbered VPValues.
1 parent c163aae commit eb0371e

File tree

6 files changed

+97
-52
lines changed

6 files changed

+97
-52
lines changed

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,24 @@ VPValue::~VPValue() {
7171
}
7272

7373
void VPValue::print(raw_ostream &OS, VPSlotTracker &SlotTracker) const {
74-
if (const VPInstruction *Instr = dyn_cast<VPInstruction>(this))
75-
Instr->print(OS, SlotTracker);
74+
if (const VPRecipeBase *R = dyn_cast_or_null<VPRecipeBase>(Def))
75+
R->print(OS, "", SlotTracker);
7676
else
7777
printAsOperand(OS, SlotTracker);
7878
}
7979

8080
void VPValue::dump() const {
81-
const VPInstruction *Instr = dyn_cast<VPInstruction>(this);
81+
const VPRecipeBase *Instr = dyn_cast_or_null<VPRecipeBase>(this->Def);
8282
VPSlotTracker SlotTracker(
8383
(Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
8484
print(dbgs(), SlotTracker);
8585
dbgs() << "\n";
8686
}
8787

88-
void VPRecipeBase::dump() const {
89-
VPSlotTracker SlotTracker(nullptr);
88+
void VPDef::dump() const {
89+
const VPRecipeBase *Instr = dyn_cast_or_null<VPRecipeBase>(this);
90+
VPSlotTracker SlotTracker(
91+
(Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
9092
print(dbgs(), "", SlotTracker);
9193
dbgs() << "\n";
9294
}
@@ -500,18 +502,15 @@ void VPInstruction::execute(VPTransformState &State) {
500502
generateInstruction(State, Part);
501503
}
502504

505+
void VPInstruction::dump() const {
506+
VPSlotTracker SlotTracker(getParent()->getPlan());
507+
print(dbgs(), "", SlotTracker);
508+
}
509+
503510
void VPInstruction::print(raw_ostream &O, const Twine &Indent,
504511
VPSlotTracker &SlotTracker) const {
505512
O << "EMIT ";
506-
print(O, SlotTracker);
507-
}
508513

509-
void VPInstruction::print(raw_ostream &O) const {
510-
VPSlotTracker SlotTracker(getParent()->getPlan());
511-
print(O, SlotTracker);
512-
}
513-
514-
void VPInstruction::print(raw_ostream &O, VPSlotTracker &SlotTracker) const {
515514
if (hasResult()) {
516515
printAsOperand(O, SlotTracker);
517516
O << " = ";
@@ -1087,13 +1086,6 @@ VPInterleavedAccessInfo::VPInterleavedAccessInfo(VPlan &Plan,
10871086

10881087
void VPSlotTracker::assignSlot(const VPValue *V) {
10891088
assert(Slots.find(V) == Slots.end() && "VPValue already has a slot!");
1090-
const Value *UV = V->getUnderlyingValue();
1091-
if (UV)
1092-
return;
1093-
const auto *VPI = dyn_cast<VPInstruction>(V);
1094-
if (VPI && !VPI->hasResult())
1095-
return;
1096-
10971089
Slots[V] = NextSlot++;
10981090
}
10991091

@@ -1112,10 +1104,8 @@ void VPSlotTracker::assignSlots(const VPRegionBlock *Region) {
11121104

11131105
void VPSlotTracker::assignSlots(const VPBasicBlock *VPBB) {
11141106
for (const VPRecipeBase &Recipe : *VPBB) {
1115-
if (const auto *VPI = dyn_cast<VPInstruction>(&Recipe))
1116-
assignSlot(VPI);
1117-
else if (const auto *VPIV = dyn_cast<VPWidenCanonicalIVRecipe>(&Recipe))
1118-
assignSlot(VPIV->getVPValue());
1107+
for (VPValue *Def : Recipe.definedValues())
1108+
assignSlot(Def);
11191109
}
11201110
}
11211111

@@ -1124,10 +1114,6 @@ void VPSlotTracker::assignSlots(const VPlan &Plan) {
11241114
for (const VPValue *V : Plan.VPExternalDefs)
11251115
assignSlot(V);
11261116

1127-
for (auto &E : Plan.Value2VPValue)
1128-
if (!isa<VPInstruction>(E.second))
1129-
assignSlot(E.second);
1130-
11311117
for (const VPValue *V : Plan.VPCBVs)
11321118
assignSlot(V);
11331119

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -645,13 +645,6 @@ class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
645645
/// this VPRecipe, thereby "executing" the VPlan.
646646
virtual void execute(struct VPTransformState &State) = 0;
647647

648-
/// Each recipe prints itself.
649-
virtual void print(raw_ostream &O, const Twine &Indent,
650-
VPSlotTracker &SlotTracker) const = 0;
651-
652-
/// Dump the recipe to stderr (for debugging).
653-
void dump() const;
654-
655648
/// Insert an unlinked recipe into a basic block immediately before
656649
/// the specified recipe.
657650
void insertBefore(VPRecipeBase *InsertPos);
@@ -777,13 +770,12 @@ class VPInstruction : public VPRecipeBase, public VPUser, public VPValue {
777770
/// provided.
778771
void execute(VPTransformState &State) override;
779772

780-
/// Print the Recipe.
773+
/// Print the VPInstruction to \p O.
781774
void print(raw_ostream &O, const Twine &Indent,
782775
VPSlotTracker &SlotTracker) const override;
783776

784-
/// Print the VPInstruction.
785-
void print(raw_ostream &O) const;
786-
void print(raw_ostream &O, VPSlotTracker &SlotTracker) const;
777+
/// Print the VPInstruction to dbgs() (for debugging).
778+
void dump() const;
787779

788780
/// Return true if this instruction may modify memory.
789781
bool mayWriteToMemory() const {
@@ -1244,7 +1236,7 @@ class VPBranchOnMaskRecipe : public VPRecipeBase, public VPUser {
12441236
VPSlotTracker &SlotTracker) const override {
12451237
O << " +\n" << Indent << "\"BRANCH-ON-MASK ";
12461238
if (VPValue *Mask = getMask())
1247-
Mask->print(O, SlotTracker);
1239+
Mask->printAsOperand(O, SlotTracker);
12481240
else
12491241
O << " All-One";
12501242
O << "\\l\"";

llvm/lib/Transforms/Vectorize/VPlanSLP.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,8 @@ VPInstruction *VPlanSlp::buildGraph(ArrayRef<VPValue *> Values) {
466466
auto *VPI = new VPInstruction(Opcode, CombinedOperands);
467467
VPI->setUnderlyingInstr(cast<VPInstruction>(Values[0])->getUnderlyingInstr());
468468

469-
LLVM_DEBUG(dbgs() << "Create VPInstruction "; VPI->print(dbgs());
470-
cast<VPInstruction>(Values[0])->print(dbgs()); dbgs() << "\n");
469+
LLVM_DEBUG(dbgs() << "Create VPInstruction " << *VPI << " "
470+
<< *cast<VPInstruction>(Values[0]) << "\n");
471471
addCombined(Values, VPI);
472472
return VPI;
473473
}

llvm/lib/Transforms/Vectorize/VPlanValue.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ class VPDef {
327327

328328
/// Returns an ArrayRef of the values defined by the VPDef.
329329
ArrayRef<VPValue *> definedValues() { return DefinedValues; }
330+
/// Returns an ArrayRef of the values defined by the VPDef.
331+
ArrayRef<VPValue *> definedValues() const { return DefinedValues; }
330332

331333
/// Returns the number of values defined by the VPDef.
332334
unsigned getNumDefinedValues() const { return DefinedValues.size(); }
@@ -335,6 +337,13 @@ class VPDef {
335337
/// This is used to implement the classof checks. This should not be used
336338
/// for any other purpose, as the values may change as LLVM evolves.
337339
unsigned getVPDefID() const { return SubclassID; }
340+
341+
/// Dump the VPDef to stderr (for debugging).
342+
void dump() const;
343+
344+
/// Each concrete VPDef prints itself.
345+
virtual void print(raw_ostream &O, const Twine &Indent,
346+
VPSlotTracker &SlotTracker) const = 0;
338347
};
339348

340349
class VPlan;
@@ -356,7 +365,7 @@ class VPSlotTracker {
356365
void assignSlots(const VPlan &Plan);
357366

358367
public:
359-
VPSlotTracker(const VPlan *Plan) {
368+
VPSlotTracker(const VPlan *Plan = nullptr) {
360369
if (Plan)
361370
assignSlots(*Plan);
362371
}

llvm/test/Transforms/LoopVectorize/vplan-printing.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ define void @print_replicate_predicated_phi(i64 %n, i64* %x) {
123123
;
124124
; CHECK: N7 [label =
125125
; CHECK-NEXT: "for.inc:\n" +
126-
; CHECK-NEXT: "EMIT vp<%0> = not ir<%cmp>\l" +
127-
; CHECK-NEXT: "BLEND %d = ir<0>/vp<%0> ir<%tmp4>/ir<%cmp>\l" +
126+
; CHECK-NEXT: "EMIT vp<%4> = not ir<%cmp>\l" +
127+
; CHECK-NEXT: "BLEND %d = ir<0>/vp<%4> ir<%tmp4>/ir<%cmp>\l" +
128128
; CHECK-NEXT: "CLONE ir<%idx> = getelementptr ir<%x>, ir<%i>\l" +
129129
; CHECK-NEXT: "WIDEN store ir<%idx>, ir<%d>\l"
130130
; CHECK-NEXT: ]

llvm/unittests/Transforms/Vectorize/VPlanTest.cpp

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,10 @@ TEST(VPBasicBlockTest, print) {
346346
{
347347
std::string I3Dump;
348348
raw_string_ostream OS(I3Dump);
349-
I3->print(OS);
349+
VPSlotTracker SlotTracker;
350+
I3->print(OS, "", SlotTracker);
350351
OS.flush();
351-
EXPECT_EQ("br <badref> <badref>", I3Dump);
352+
EXPECT_EQ("EMIT br <badref> <badref>", I3Dump);
352353
}
353354

354355
VPlan Plan;
@@ -370,8 +371,8 @@ compound=true
370371
N0 -> N1 [ label=""]
371372
N1 [label =
372373
":\n" +
373-
"EMIT vp<%2> = mul vp<%1> vp<%0>\l" +
374-
"EMIT ret vp<%2>\l"
374+
"EMIT vp<%3> = mul vp<%1> vp<%0>\l" +
375+
"EMIT ret vp<%3>\l"
375376
]
376377
}
377378
)";
@@ -380,17 +381,18 @@ compound=true
380381
{
381382
std::string I3Dump;
382383
raw_string_ostream OS(I3Dump);
383-
I3->print(OS);
384+
VPSlotTracker SlotTracker(&Plan);
385+
I3->print(OS, "", SlotTracker);
384386
OS.flush();
385-
EXPECT_EQ("br vp<%0> vp<%1>", I3Dump);
387+
EXPECT_EQ("EMIT br vp<%0> vp<%1>", I3Dump);
386388
}
387389

388390
{
389391
std::string I4Dump;
390392
raw_string_ostream OS(I4Dump);
391393
OS << *I4;
392394
OS.flush();
393-
EXPECT_EQ("vp<%2> = mul vp<%1> vp<%0>", I4Dump);
395+
EXPECT_EQ("EMIT vp<%3> = mul vp<%1> vp<%0>", I4Dump);
394396
}
395397
}
396398

@@ -579,6 +581,62 @@ TEST(VPRecipeTest, CastVPWidenMemoryInstructionRecipeToVPUserAndVPDef) {
579581
delete Load;
580582
}
581583

584+
TEST(VPRecipeTest, dump) {
585+
VPlan Plan;
586+
VPBasicBlock *VPBB1 = new VPBasicBlock();
587+
Plan.setEntry(VPBB1);
588+
589+
LLVMContext C;
590+
591+
IntegerType *Int32 = IntegerType::get(C, 32);
592+
auto *AI =
593+
BinaryOperator::CreateAdd(UndefValue::get(Int32), UndefValue::get(Int32));
594+
AI->setName("a");
595+
SmallVector<VPValue *, 2> Args;
596+
VPValue *ExtVPV1 = new VPValue();
597+
VPValue *ExtVPV2 = new VPValue();
598+
Plan.addExternalDef(ExtVPV1);
599+
Plan.addExternalDef(ExtVPV2);
600+
Args.push_back(ExtVPV1);
601+
Args.push_back(ExtVPV2);
602+
VPWidenRecipe *WidenR =
603+
new VPWidenRecipe(*AI, make_range(Args.begin(), Args.end()));
604+
VPBB1->appendRecipe(WidenR);
605+
606+
{
607+
// Use EXPECT_EXIT to capture stderr and compare against expected output.
608+
//
609+
// Test VPValue::dump().
610+
VPValue *VPV = WidenR;
611+
EXPECT_EXIT(
612+
{
613+
VPV->dump();
614+
exit(0);
615+
},
616+
testing::ExitedWithCode(0), "WIDEN ir<%a> = add vp<%0>, vp<%1>");
617+
618+
// Test VPRecipeBase::dump().
619+
VPRecipeBase *R = WidenR;
620+
EXPECT_EXIT(
621+
{
622+
R->dump();
623+
exit(0);
624+
},
625+
testing::ExitedWithCode(0), "WIDEN ir<%a> = add vp<%0>, vp<%1>");
626+
627+
// Test VPDef::dump().
628+
VPDef *D = WidenR;
629+
EXPECT_EXIT(
630+
{
631+
D->dump();
632+
exit(0);
633+
},
634+
testing::ExitedWithCode(0), "WIDEN ir<%a> = add vp<%0>, vp<%1>");
635+
}
636+
637+
delete AI;
638+
}
639+
582640
TEST(VPRecipeTest, CastVPReductionRecipeToVPUser) {
583641
LLVMContext C;
584642

0 commit comments

Comments
 (0)