1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 12:12:47 +01:00

[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.
This commit is contained in:
Florian Hahn 2020-11-23 15:44:50 +00:00
parent 24cba9188e
commit 7ccaba4adc
6 changed files with 97 additions and 52 deletions

View File

@ -71,22 +71,24 @@ VPValue::~VPValue() {
}
void VPValue::print(raw_ostream &OS, VPSlotTracker &SlotTracker) const {
if (const VPInstruction *Instr = dyn_cast<VPInstruction>(this))
Instr->print(OS, SlotTracker);
if (const VPRecipeBase *R = dyn_cast_or_null<VPRecipeBase>(Def))
R->print(OS, "", SlotTracker);
else
printAsOperand(OS, SlotTracker);
}
void VPValue::dump() const {
const VPInstruction *Instr = dyn_cast<VPInstruction>(this);
const VPRecipeBase *Instr = dyn_cast_or_null<VPRecipeBase>(this->Def);
VPSlotTracker SlotTracker(
(Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
print(dbgs(), SlotTracker);
dbgs() << "\n";
}
void VPRecipeBase::dump() const {
VPSlotTracker SlotTracker(nullptr);
void VPDef::dump() const {
const VPRecipeBase *Instr = dyn_cast_or_null<VPRecipeBase>(this);
VPSlotTracker SlotTracker(
(Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
print(dbgs(), "", SlotTracker);
dbgs() << "\n";
}
@ -500,18 +502,15 @@ void VPInstruction::execute(VPTransformState &State) {
generateInstruction(State, Part);
}
void VPInstruction::dump() const {
VPSlotTracker SlotTracker(getParent()->getPlan());
print(dbgs(), "", SlotTracker);
}
void VPInstruction::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
O << "EMIT ";
print(O, SlotTracker);
}
void VPInstruction::print(raw_ostream &O) const {
VPSlotTracker SlotTracker(getParent()->getPlan());
print(O, SlotTracker);
}
void VPInstruction::print(raw_ostream &O, VPSlotTracker &SlotTracker) const {
if (hasResult()) {
printAsOperand(O, SlotTracker);
O << " = ";
@ -1087,13 +1086,6 @@ VPInterleavedAccessInfo::VPInterleavedAccessInfo(VPlan &Plan,
void VPSlotTracker::assignSlot(const VPValue *V) {
assert(Slots.find(V) == Slots.end() && "VPValue already has a slot!");
const Value *UV = V->getUnderlyingValue();
if (UV)
return;
const auto *VPI = dyn_cast<VPInstruction>(V);
if (VPI && !VPI->hasResult())
return;
Slots[V] = NextSlot++;
}
@ -1112,10 +1104,8 @@ void VPSlotTracker::assignSlots(const VPRegionBlock *Region) {
void VPSlotTracker::assignSlots(const VPBasicBlock *VPBB) {
for (const VPRecipeBase &Recipe : *VPBB) {
if (const auto *VPI = dyn_cast<VPInstruction>(&Recipe))
assignSlot(VPI);
else if (const auto *VPIV = dyn_cast<VPWidenCanonicalIVRecipe>(&Recipe))
assignSlot(VPIV->getVPValue());
for (VPValue *Def : Recipe.definedValues())
assignSlot(Def);
}
}
@ -1124,10 +1114,6 @@ void VPSlotTracker::assignSlots(const VPlan &Plan) {
for (const VPValue *V : Plan.VPExternalDefs)
assignSlot(V);
for (auto &E : Plan.Value2VPValue)
if (!isa<VPInstruction>(E.second))
assignSlot(E.second);
for (const VPValue *V : Plan.VPCBVs)
assignSlot(V);

View File

@ -645,13 +645,6 @@ public:
/// this VPRecipe, thereby "executing" the VPlan.
virtual void execute(struct VPTransformState &State) = 0;
/// Each recipe prints itself.
virtual void print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const = 0;
/// Dump the recipe to stderr (for debugging).
void dump() const;
/// Insert an unlinked recipe into a basic block immediately before
/// the specified recipe.
void insertBefore(VPRecipeBase *InsertPos);
@ -777,13 +770,12 @@ public:
/// provided.
void execute(VPTransformState &State) override;
/// Print the Recipe.
/// Print the VPInstruction to \p O.
void print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const override;
/// Print the VPInstruction.
void print(raw_ostream &O) const;
void print(raw_ostream &O, VPSlotTracker &SlotTracker) const;
/// Print the VPInstruction to dbgs() (for debugging).
void dump() const;
/// Return true if this instruction may modify memory.
bool mayWriteToMemory() const {
@ -1244,7 +1236,7 @@ public:
VPSlotTracker &SlotTracker) const override {
O << " +\n" << Indent << "\"BRANCH-ON-MASK ";
if (VPValue *Mask = getMask())
Mask->print(O, SlotTracker);
Mask->printAsOperand(O, SlotTracker);
else
O << " All-One";
O << "\\l\"";

View File

@ -466,8 +466,8 @@ VPInstruction *VPlanSlp::buildGraph(ArrayRef<VPValue *> Values) {
auto *VPI = new VPInstruction(Opcode, CombinedOperands);
VPI->setUnderlyingInstr(cast<VPInstruction>(Values[0])->getUnderlyingInstr());
LLVM_DEBUG(dbgs() << "Create VPInstruction "; VPI->print(dbgs());
cast<VPInstruction>(Values[0])->print(dbgs()); dbgs() << "\n");
LLVM_DEBUG(dbgs() << "Create VPInstruction " << *VPI << " "
<< *cast<VPInstruction>(Values[0]) << "\n");
addCombined(Values, VPI);
return VPI;
}

View File

@ -327,6 +327,8 @@ public:
/// Returns an ArrayRef of the values defined by the VPDef.
ArrayRef<VPValue *> definedValues() { return DefinedValues; }
/// Returns an ArrayRef of the values defined by the VPDef.
ArrayRef<VPValue *> definedValues() const { return DefinedValues; }
/// Returns the number of values defined by the VPDef.
unsigned getNumDefinedValues() const { return DefinedValues.size(); }
@ -335,6 +337,13 @@ public:
/// This is used to implement the classof checks. This should not be used
/// for any other purpose, as the values may change as LLVM evolves.
unsigned getVPDefID() const { return SubclassID; }
/// Dump the VPDef to stderr (for debugging).
void dump() const;
/// Each concrete VPDef prints itself.
virtual void print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const = 0;
};
class VPlan;
@ -356,7 +365,7 @@ class VPSlotTracker {
void assignSlots(const VPlan &Plan);
public:
VPSlotTracker(const VPlan *Plan) {
VPSlotTracker(const VPlan *Plan = nullptr) {
if (Plan)
assignSlots(*Plan);
}

View File

@ -123,8 +123,8 @@ define void @print_replicate_predicated_phi(i64 %n, i64* %x) {
;
; CHECK: N7 [label =
; CHECK-NEXT: "for.inc:\n" +
; CHECK-NEXT: "EMIT vp<%0> = not ir<%cmp>\l" +
; CHECK-NEXT: "BLEND %d = ir<0>/vp<%0> ir<%tmp4>/ir<%cmp>\l" +
; CHECK-NEXT: "EMIT vp<%4> = not ir<%cmp>\l" +
; CHECK-NEXT: "BLEND %d = ir<0>/vp<%4> ir<%tmp4>/ir<%cmp>\l" +
; CHECK-NEXT: "CLONE ir<%idx> = getelementptr ir<%x>, ir<%i>\l" +
; CHECK-NEXT: "WIDEN store ir<%idx>, ir<%d>\l"
; CHECK-NEXT: ]

View File

@ -346,9 +346,10 @@ TEST(VPBasicBlockTest, print) {
{
std::string I3Dump;
raw_string_ostream OS(I3Dump);
I3->print(OS);
VPSlotTracker SlotTracker;
I3->print(OS, "", SlotTracker);
OS.flush();
EXPECT_EQ("br <badref> <badref>", I3Dump);
EXPECT_EQ("EMIT br <badref> <badref>", I3Dump);
}
VPlan Plan;
@ -370,8 +371,8 @@ compound=true
N0 -> N1 [ label=""]
N1 [label =
":\n" +
"EMIT vp<%2> = mul vp<%1> vp<%0>\l" +
"EMIT ret vp<%2>\l"
"EMIT vp<%3> = mul vp<%1> vp<%0>\l" +
"EMIT ret vp<%3>\l"
]
}
)";
@ -380,9 +381,10 @@ compound=true
{
std::string I3Dump;
raw_string_ostream OS(I3Dump);
I3->print(OS);
VPSlotTracker SlotTracker(&Plan);
I3->print(OS, "", SlotTracker);
OS.flush();
EXPECT_EQ("br vp<%0> vp<%1>", I3Dump);
EXPECT_EQ("EMIT br vp<%0> vp<%1>", I3Dump);
}
{
@ -390,7 +392,7 @@ compound=true
raw_string_ostream OS(I4Dump);
OS << *I4;
OS.flush();
EXPECT_EQ("vp<%2> = mul vp<%1> vp<%0>", I4Dump);
EXPECT_EQ("EMIT vp<%3> = mul vp<%1> vp<%0>", I4Dump);
}
}
@ -579,6 +581,62 @@ TEST(VPRecipeTest, CastVPWidenMemoryInstructionRecipeToVPUserAndVPDef) {
delete Load;
}
TEST(VPRecipeTest, dump) {
VPlan Plan;
VPBasicBlock *VPBB1 = new VPBasicBlock();
Plan.setEntry(VPBB1);
LLVMContext C;
IntegerType *Int32 = IntegerType::get(C, 32);
auto *AI =
BinaryOperator::CreateAdd(UndefValue::get(Int32), UndefValue::get(Int32));
AI->setName("a");
SmallVector<VPValue *, 2> Args;
VPValue *ExtVPV1 = new VPValue();
VPValue *ExtVPV2 = new VPValue();
Plan.addExternalDef(ExtVPV1);
Plan.addExternalDef(ExtVPV2);
Args.push_back(ExtVPV1);
Args.push_back(ExtVPV2);
VPWidenRecipe *WidenR =
new VPWidenRecipe(*AI, make_range(Args.begin(), Args.end()));
VPBB1->appendRecipe(WidenR);
{
// Use EXPECT_EXIT to capture stderr and compare against expected output.
//
// Test VPValue::dump().
VPValue *VPV = WidenR;
EXPECT_EXIT(
{
VPV->dump();
exit(0);
},
testing::ExitedWithCode(0), "WIDEN ir<%a> = add vp<%0>, vp<%1>");
// Test VPRecipeBase::dump().
VPRecipeBase *R = WidenR;
EXPECT_EXIT(
{
R->dump();
exit(0);
},
testing::ExitedWithCode(0), "WIDEN ir<%a> = add vp<%0>, vp<%1>");
// Test VPDef::dump().
VPDef *D = WidenR;
EXPECT_EXIT(
{
D->dump();
exit(0);
},
testing::ExitedWithCode(0), "WIDEN ir<%a> = add vp<%0>, vp<%1>");
}
delete AI;
}
TEST(VPRecipeTest, CastVPReductionRecipeToVPUser) {
LLVMContext C;