[llvm] r372425 - Revert "[MachinePipeliner] Improve the TargetInstrInfo API analyzeLoop/reduceLoopCount"
Mitch Phillips via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 20 13:25:16 PDT 2019
Author: hctim
Date: Fri Sep 20 13:25:16 2019
New Revision: 372425
URL: http://llvm.org/viewvc/llvm-project?rev=372425&view=rev
Log:
Revert "[MachinePipeliner] Improve the TargetInstrInfo API analyzeLoop/reduceLoopCount"
This commit broke the ASan buildbot. See comments in rL372376 for more
information.
This reverts commit 15e27b0b6d9d51362fad85dbe95ac5b3fadf0a06.
Modified:
llvm/trunk/include/llvm/CodeGen/ModuloSchedule.h
llvm/trunk/include/llvm/CodeGen/TargetInstrInfo.h
llvm/trunk/lib/CodeGen/MachinePipeliner.cpp
llvm/trunk/lib/CodeGen/ModuloSchedule.cpp
llvm/trunk/lib/CodeGen/TargetInstrInfo.cpp
llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp
llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.h
llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h
llvm/trunk/test/CodeGen/Hexagon/swp-epilog-phi7.ll
Modified: llvm/trunk/include/llvm/CodeGen/ModuloSchedule.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ModuloSchedule.h?rev=372425&r1=372424&r2=372425&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ModuloSchedule.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ModuloSchedule.h Fri Sep 20 13:25:16 2019
@@ -62,7 +62,6 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include <vector>
@@ -169,7 +168,6 @@ private:
MachineBasicBlock *BB;
MachineBasicBlock *Preheader;
MachineBasicBlock *NewKernel = nullptr;
- std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopInfo;
/// Map for each register and the max difference between its uses and def.
/// The first element in the pair is the max difference in stages. The
Modified: llvm/trunk/include/llvm/CodeGen/TargetInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetInstrInfo.h?rev=372425&r1=372424&r2=372425&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/TargetInstrInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/TargetInstrInfo.h Fri Sep 20 13:25:16 2019
@@ -662,50 +662,6 @@ public:
BytesAdded);
}
- /// Object returned by analyzeLoopForPipelining. Allows software pipelining
- /// implementations to query attributes of the loop being pipelined and to
- /// apply target-specific updates to the loop once pipelining is complete.
- class PipelinerLoopInfo {
- public:
- virtual ~PipelinerLoopInfo();
- /// Return true if the given instruction should not be pipelined and should
- /// be ignored. An example could be a loop comparison, or induction variable
- /// update with no users being pipelined.
- virtual bool shouldIgnoreForPipelining(const MachineInstr *MI) const = 0;
-
- /// Create a condition to determine if the trip count of the loop is greater
- /// than TC.
- ///
- /// If the trip count is statically known to be greater than TC, return
- /// true. If the trip count is statically known to be not greater than TC,
- /// return false. Otherwise return nullopt and fill out Cond with the test
- /// condition.
- virtual Optional<bool>
- createTripCountGreaterCondition(int TC, MachineBasicBlock &MBB,
- SmallVectorImpl<MachineOperand> &Cond) = 0;
-
- /// Modify the loop such that the trip count is
- /// OriginalTC + TripCountAdjust.
- virtual void adjustTripCount(int TripCountAdjust) = 0;
-
- /// Called when the loop's preheader has been modified to NewPreheader.
- virtual void setPreheader(MachineBasicBlock *NewPreheader) = 0;
-
- /// Called when the loop is being removed. Any instructions in the preheader
- /// should be removed.
- ///
- /// Once this function is called, no other functions on this object are
- /// valid; the loop has been removed.
- virtual void disposed() = 0;
- };
-
- /// Analyze loop L, which must be a single-basic-block loop, and if the
- /// conditions can be understood enough produce a PipelinerLoopInfo object.
- virtual std::unique_ptr<PipelinerLoopInfo>
- analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const {
- return nullptr;
- }
-
/// Analyze the loop code, return true if it cannot be understoo. Upon
/// success, this function returns false and returns information about the
/// induction variable and compare instruction used at the end.
Modified: llvm/trunk/lib/CodeGen/MachinePipeliner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachinePipeliner.cpp?rev=372425&r1=372424&r2=372425&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachinePipeliner.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachinePipeliner.cpp Fri Sep 20 13:25:16 2019
@@ -326,7 +326,7 @@ bool MachinePipeliner::canPipelineLoop(M
LI.LoopInductionVar = nullptr;
LI.LoopCompare = nullptr;
- if (!TII->analyzeLoopForPipelining(L.getTopBlock())) {
+ if (TII->analyzeLoop(L, LI.LoopInductionVar, LI.LoopCompare)) {
LLVM_DEBUG(
dbgs() << "Unable to analyzeLoop, can NOT pipeline current Loop\n");
NumFailLoop++;
Modified: llvm/trunk/lib/CodeGen/ModuloSchedule.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ModuloSchedule.cpp?rev=372425&r1=372424&r2=372425&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ModuloSchedule.cpp (original)
+++ llvm/trunk/lib/CodeGen/ModuloSchedule.cpp Fri Sep 20 13:25:16 2019
@@ -105,9 +105,6 @@ void ModuloScheduleExpander::expand() {
}
void ModuloScheduleExpander::generatePipelinedLoop() {
- LoopInfo = TII->analyzeLoopForPipelining(BB);
- assert(LoopInfo && "Must be able to analyze loop!");
-
// Create a new basic block for the kernel and add it to the CFG.
MachineBasicBlock *KernelBB = MF.CreateMachineBasicBlock(BB->getBasicBlock());
@@ -850,6 +847,10 @@ void ModuloScheduleExpander::addBranches
MBBVectorTy &EpilogBBs,
ValueMapTy *VRMap) {
assert(PrologBBs.size() == EpilogBBs.size() && "Prolog/Epilog mismatch");
+ MachineInstr *IndVar;
+ MachineInstr *Cmp;
+ if (TII->analyzeLoop(*Schedule.getLoop(), IndVar, Cmp))
+ llvm_unreachable("Must be able to analyze loop!");
MachineBasicBlock *LastPro = KernelBB;
MachineBasicBlock *LastEpi = KernelBB;
@@ -857,20 +858,32 @@ void ModuloScheduleExpander::addBranches
// to the first prolog and the last epilog blocks.
SmallVector<MachineInstr *, 4> PrevInsts;
unsigned MaxIter = PrologBBs.size() - 1;
+ unsigned LC = UINT_MAX;
+ unsigned LCMin = UINT_MAX;
for (unsigned i = 0, j = MaxIter; i <= MaxIter; ++i, --j) {
// Add branches to the prolog that go to the corresponding
// epilog, and the fall-thru prolog/kernel block.
MachineBasicBlock *Prolog = PrologBBs[j];
MachineBasicBlock *Epilog = EpilogBBs[i];
-
+ // We've executed one iteration, so decrement the loop count and check for
+ // the loop end.
SmallVector<MachineOperand, 4> Cond;
- Optional<bool> StaticallyGreater =
- LoopInfo->createTripCountGreaterCondition(j + 1, *Prolog, Cond);
+ // Check if the LOOP0 has already been removed. If so, then there is no need
+ // to reduce the trip count.
+ if (LC != 0)
+ LC = TII->reduceLoopCount(*Prolog, PreheaderBB, IndVar, *Cmp, Cond,
+ PrevInsts, j, MaxIter);
+
+ // Record the value of the first trip count, which is used to determine if
+ // branches and blocks can be removed for constant trip counts.
+ if (LCMin == UINT_MAX)
+ LCMin = LC;
+
unsigned numAdded = 0;
- if (!StaticallyGreater.hasValue()) {
+ if (Register::isVirtualRegister(LC)) {
Prolog->addSuccessor(Epilog);
numAdded = TII->insertBranch(*Prolog, Epilog, LastPro, Cond, DebugLoc());
- } else if (*StaticallyGreater == false) {
+ } else if (j >= LCMin) {
Prolog->addSuccessor(Epilog);
Prolog->removeSuccessor(LastPro);
LastEpi->removeSuccessor(Epilog);
@@ -881,12 +894,10 @@ void ModuloScheduleExpander::addBranches
LastEpi->clear();
LastEpi->eraseFromParent();
}
- if (LastPro == KernelBB) {
- LoopInfo->disposed();
- NewKernel = nullptr;
- }
LastPro->clear();
LastPro->eraseFromParent();
+ if (LastPro == KernelBB)
+ NewKernel = nullptr;
} else {
numAdded = TII->insertBranch(*Prolog, LastPro, nullptr, Cond, DebugLoc());
removePhis(Epilog, Prolog);
@@ -898,11 +909,6 @@ void ModuloScheduleExpander::addBranches
I != E && numAdded > 0; ++I, --numAdded)
updateInstruction(&*I, false, j, 0, VRMap);
}
-
- if (NewKernel) {
- LoopInfo->setPreheader(PrologBBs[MaxIter]);
- LoopInfo->adjustTripCount(-(MaxIter + 1));
- }
}
/// Return true if we can compute the amount the instruction changes
Modified: llvm/trunk/lib/CodeGen/TargetInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetInstrInfo.cpp?rev=372425&r1=372424&r2=372425&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetInstrInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetInstrInfo.cpp Fri Sep 20 13:25:16 2019
@@ -1257,5 +1257,3 @@ bool TargetInstrInfo::getInsertSubregInp
InsertedReg.SubIdx = (unsigned)MOSubIdx.getImm();
return true;
}
-
-TargetInstrInfo::PipelinerLoopInfo::~PipelinerLoopInfo() {}
Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp?rev=372425&r1=372424&r2=372425&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp Fri Sep 20 13:25:16 2019
@@ -674,84 +674,86 @@ unsigned HexagonInstrInfo::insertBranch(
return 2;
}
-class HexagonPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
- MachineInstr *Loop, *EndLoop;
- MachineFunction *MF;
- const HexagonInstrInfo *TII;
+/// Analyze the loop code to find the loop induction variable and compare used
+/// to compute the number of iterations. Currently, we analyze loop that are
+/// controlled using hardware loops. In this case, the induction variable
+/// instruction is null. For all other cases, this function returns true, which
+/// means we're unable to analyze it.
+bool HexagonInstrInfo::analyzeLoop(MachineLoop &L,
+ MachineInstr *&IndVarInst,
+ MachineInstr *&CmpInst) const {
-public:
- HexagonPipelinerLoopInfo(MachineInstr *Loop, MachineInstr *EndLoop)
- : Loop(Loop), EndLoop(EndLoop), MF(Loop->getParent()->getParent()),
- TII(MF->getSubtarget<HexagonSubtarget>().getInstrInfo()) {}
-
- bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
- // Only ignore the terminator.
- return MI == EndLoop;
- }
-
- Optional<bool>
- createTripCountGreaterCondition(int TC, MachineBasicBlock &MBB,
- SmallVectorImpl<MachineOperand> &Cond) override {
- if (Loop->getOpcode() == Hexagon::J2_loop0r) {
- Register LoopCount = Loop->getOperand(1).getReg();
- // Check if we're done with the loop.
- unsigned Done = TII->createVR(MF, MVT::i1);
- MachineInstr *NewCmp = BuildMI(&MBB, Loop->getDebugLoc(),
- TII->get(Hexagon::C2_cmpgtui), Done)
- .addReg(LoopCount)
- .addImm(TC);
- Cond.push_back(MachineOperand::CreateImm(Hexagon::J2_jumpf));
- Cond.push_back(NewCmp->getOperand(0));
- return {};
- }
-
- int64_t TripCount = Loop->getOperand(1).getImm();
- return TripCount > TC;
- }
-
- void setPreheader(MachineBasicBlock *NewPreheader) override {
- NewPreheader->splice(NewPreheader->getFirstTerminator(), Loop->getParent(),
- Loop);
- }
-
- void adjustTripCount(int TripCountAdjust) override {
- // If the loop trip count is a compile-time value, then just change the
- // value.
- if (Loop->getOpcode() == Hexagon::J2_loop0i ||
- Loop->getOpcode() == Hexagon::J2_loop1i) {
- int64_t TripCount = Loop->getOperand(1).getImm() + TripCountAdjust;
- assert(TripCount > 0 && "Can't create an empty or negative loop!");
- Loop->getOperand(1).setImm(TripCount);
- return;
- }
-
- // The loop trip count is a run-time value. We generate code to subtract
- // one from the trip count, and update the loop instruction.
- Register LoopCount = Loop->getOperand(1).getReg();
- Register NewLoopCount = TII->createVR(MF, MVT::i32);
- BuildMI(*Loop->getParent(), Loop, Loop->getDebugLoc(),
- TII->get(Hexagon::A2_addi), NewLoopCount)
- .addReg(LoopCount)
- .addImm(TripCountAdjust);
- Loop->getOperand(1).setReg(NewLoopCount);
- }
-
- void disposed() override { Loop->eraseFromParent(); }
-};
-
-std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
-HexagonInstrInfo::analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const {
+ MachineBasicBlock *LoopEnd = L.getBottomBlock();
+ MachineBasicBlock::iterator I = LoopEnd->getFirstTerminator();
// We really "analyze" only hardware loops right now.
- MachineBasicBlock::iterator I = LoopBB->getFirstTerminator();
+ if (I != LoopEnd->end() && isEndLoopN(I->getOpcode())) {
+ IndVarInst = nullptr;
+ CmpInst = &*I;
+ return false;
+ }
+ return true;
+}
- if (I != LoopBB->end() && isEndLoopN(I->getOpcode())) {
- SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
- MachineInstr *LoopInst = findLoopInstr(
- LoopBB, I->getOpcode(), I->getOperand(0).getMBB(), VisitedBBs);
- if (LoopInst)
- return std::make_unique<HexagonPipelinerLoopInfo>(LoopInst, &*I);
+/// Generate code to reduce the loop iteration by one and check if the loop is
+/// finished. Return the value/register of the new loop count. this function
+/// assumes the nth iteration is peeled first.
+unsigned HexagonInstrInfo::reduceLoopCount(
+ MachineBasicBlock &MBB, MachineBasicBlock &PreHeader, MachineInstr *IndVar,
+ MachineInstr &Cmp, SmallVectorImpl<MachineOperand> &Cond,
+ SmallVectorImpl<MachineInstr *> &PrevInsts, unsigned Iter,
+ unsigned MaxIter) const {
+ // We expect a hardware loop currently. This means that IndVar is set
+ // to null, and the compare is the ENDLOOP instruction.
+ assert((!IndVar) && isEndLoopN(Cmp.getOpcode())
+ && "Expecting a hardware loop");
+ MachineFunction *MF = MBB.getParent();
+ DebugLoc DL = Cmp.getDebugLoc();
+ SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
+ MachineInstr *Loop = findLoopInstr(&MBB, Cmp.getOpcode(),
+ Cmp.getOperand(0).getMBB(), VisitedBBs);
+ if (!Loop)
+ return 0;
+ // If the loop trip count is a compile-time value, then just change the
+ // value.
+ if (Loop->getOpcode() == Hexagon::J2_loop0i ||
+ Loop->getOpcode() == Hexagon::J2_loop1i) {
+ int64_t Offset = Loop->getOperand(1).getImm();
+ if (Offset <= 1)
+ Loop->eraseFromParent();
+ else
+ Loop->getOperand(1).setImm(Offset - 1);
+ return Offset - 1;
}
- return nullptr;
+ // The loop trip count is a run-time value. We generate code to subtract
+ // one from the trip count, and update the loop instruction.
+ assert(Loop->getOpcode() == Hexagon::J2_loop0r && "Unexpected instruction");
+ Register LoopCount = Loop->getOperand(1).getReg();
+ // Check if we're done with the loop.
+ unsigned LoopEnd = createVR(MF, MVT::i1);
+ MachineInstr *NewCmp = BuildMI(&MBB, DL, get(Hexagon::C2_cmpgtui), LoopEnd).
+ addReg(LoopCount).addImm(1);
+ unsigned NewLoopCount = createVR(MF, MVT::i32);
+ MachineInstr *NewAdd = BuildMI(&MBB, DL, get(Hexagon::A2_addi), NewLoopCount).
+ addReg(LoopCount).addImm(-1);
+ const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
+ // Update the previously generated instructions with the new loop counter.
+ for (SmallVectorImpl<MachineInstr *>::iterator I = PrevInsts.begin(),
+ E = PrevInsts.end(); I != E; ++I)
+ (*I)->substituteRegister(LoopCount, NewLoopCount, 0, HRI);
+ PrevInsts.clear();
+ PrevInsts.push_back(NewCmp);
+ PrevInsts.push_back(NewAdd);
+ // Insert the new loop instruction if this is the last time the loop is
+ // decremented.
+ if (Iter == MaxIter)
+ BuildMI(&MBB, DL, get(Hexagon::J2_loop0r)).
+ addMBB(Loop->getOperand(0).getMBB()).addReg(NewLoopCount);
+ // Delete the old loop instruction.
+ if (Iter == 0)
+ Loop->eraseFromParent();
+ Cond.push_back(MachineOperand::CreateImm(Hexagon::J2_jumpf));
+ Cond.push_back(NewCmp->getOperand(0));
+ return NewLoopCount;
}
bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.h?rev=372425&r1=372424&r2=372425&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.h (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.h Fri Sep 20 13:25:16 2019
@@ -129,10 +129,21 @@ public:
const DebugLoc &DL,
int *BytesAdded = nullptr) const override;
- /// Analyze loop L, which must be a single-basic-block loop, and if the
- /// conditions can be understood enough produce a PipelinerLoopInfo object.
- std::unique_ptr<PipelinerLoopInfo>
- analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override;
+ /// Analyze the loop code, return true if it cannot be understood. Upon
+ /// success, this function returns false and returns information about the
+ /// induction variable and compare instruction used at the end.
+ bool analyzeLoop(MachineLoop &L, MachineInstr *&IndVarInst,
+ MachineInstr *&CmpInst) const override;
+
+ /// Generate code to reduce the loop iteration by one and check if the loop
+ /// is finished. Return the value/register of the new loop count. We need
+ /// this function when peeling off one or more iterations of a loop. This
+ /// function assumes the nth iteration is peeled first.
+ unsigned reduceLoopCount(MachineBasicBlock &MBB, MachineBasicBlock &PreHeader,
+ MachineInstr *IndVar, MachineInstr &Cmp,
+ SmallVectorImpl<MachineOperand> &Cond,
+ SmallVectorImpl<MachineInstr *> &PrevInsts,
+ unsigned Iter, unsigned MaxIter) const override;
/// Return true if it's profitable to predicate
/// instructions with accumulated instruction latency of "NumCycles"
Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=372425&r1=372424&r2=372425&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Fri Sep 20 13:25:16 2019
@@ -3930,92 +3930,21 @@ bool PPCInstrInfo::isBDNZ(unsigned Opcod
return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));
}
-class PPCPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
- MachineInstr *Loop, *EndLoop, *LoopCount;
- MachineFunction *MF;
- const TargetInstrInfo *TII;
-
-public:
- PPCPipelinerLoopInfo(MachineInstr *Loop, MachineInstr *EndLoop,
- MachineInstr *LoopCount)
- : Loop(Loop), EndLoop(EndLoop), LoopCount(LoopCount),
- MF(Loop->getParent()->getParent()),
- TII(MF->getSubtarget().getInstrInfo()) {}
-
- bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
- // Only ignore the terminator.
- return MI == EndLoop;
+bool PPCInstrInfo::analyzeLoop(MachineLoop &L, MachineInstr *&IndVarInst,
+ MachineInstr *&CmpInst) const {
+ MachineBasicBlock *LoopEnd = L.getBottomBlock();
+ MachineBasicBlock::iterator I = LoopEnd->getFirstTerminator();
+ // We really "analyze" only CTR loops right now.
+ if (I != LoopEnd->end() && isBDNZ(I->getOpcode())) {
+ IndVarInst = nullptr;
+ CmpInst = &*I;
+ return false;
}
-
- Optional<bool>
- createTripCountGreaterCondition(int TC, MachineBasicBlock &MBB,
- SmallVectorImpl<MachineOperand> &Cond) override {
- bool IsConstantTripCount =
- LoopCount->getOpcode() == PPC::LI8 || LoopCount->getOpcode() == PPC::LI;
- if (!IsConstantTripCount) {
- // Since BDZ/BDZ8 that we will insert will also decrease the ctr by 1,
- // so we don't need to generate any thing here.
- Cond.push_back(MachineOperand::CreateImm(0));
- Cond.push_back(MachineOperand::CreateReg(
- MF->getSubtarget<PPCSubtarget>().isPPC64() ? PPC::CTR8 : PPC::CTR,
- true));
- return {};
- }
-
- int64_t TripCount = LoopCount->getOperand(1).getImm();
- return TripCount > TC;
- }
-
- void setPreheader(MachineBasicBlock *NewPreheader) override {
- // Do nothing. We want the LOOP setup instruction to stay in the *old*
- // preheader, so we can use BDZ in the prologs to adapt the loop trip count.
- }
-
- void adjustTripCount(int TripCountAdjust) override {
- // If the loop trip count is a compile-time value, then just change the
- // value.
- if (LoopCount->getOpcode() == PPC::LI8 ||
- LoopCount->getOpcode() == PPC::LI) {
- int64_t TripCount = LoopCount->getOperand(1).getImm() + TripCountAdjust;
- LoopCount->getOperand(1).setImm(TripCount);
- return;
- }
-
- // Since BDZ/BDZ8 that we will insert will also decrease the ctr by 1,
- // so we don't need to generate any thing here.
- }
-
- void disposed() override {
- Loop->eraseFromParent();
- // Ensure the loop setup instruction is deleted too.
- LoopCount->eraseFromParent();
- }
-};
-
-std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
-PPCInstrInfo::analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const {
- // We really "analyze" only hardware loops right now.
- MachineBasicBlock::iterator I = LoopBB->getFirstTerminator();
- MachineBasicBlock *Preheader = *LoopBB->pred_begin();
- if (Preheader == LoopBB)
- Preheader = *std::next(LoopBB->pred_begin());
- MachineFunction *MF = Preheader->getParent();
-
- if (I != LoopBB->end() && isBDNZ(I->getOpcode())) {
- SmallPtrSet<MachineBasicBlock *, 8> Visited;
- if (MachineInstr *LoopInst = findLoopInstr(*Preheader, Visited)) {
- Register LoopCountReg = LoopInst->getOperand(0).getReg();
- MachineRegisterInfo &MRI = MF->getRegInfo();
- MachineInstr *LoopCount = MRI.getUniqueVRegDef(LoopCountReg);
- return std::make_unique<PPCPipelinerLoopInfo>(LoopInst, &*I, LoopCount);
- }
- }
- return nullptr;
+ return true;
}
-MachineInstr *PPCInstrInfo::findLoopInstr(
- MachineBasicBlock &PreHeader,
- SmallPtrSet<MachineBasicBlock *, 8> &Visited) const {
+MachineInstr *
+PPCInstrInfo::findLoopInstr(MachineBasicBlock &PreHeader) const {
unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);
@@ -4026,6 +3955,50 @@ MachineInstr *PPCInstrInfo::findLoopInst
return nullptr;
}
+unsigned PPCInstrInfo::reduceLoopCount(
+ MachineBasicBlock &MBB, MachineBasicBlock &PreHeader, MachineInstr *IndVar,
+ MachineInstr &Cmp, SmallVectorImpl<MachineOperand> &Cond,
+ SmallVectorImpl<MachineInstr *> &PrevInsts, unsigned Iter,
+ unsigned MaxIter) const {
+ // We expect a hardware loop currently. This means that IndVar is set
+ // to null, and the compare is the ENDLOOP instruction.
+ assert((!IndVar) && isBDNZ(Cmp.getOpcode()) && "Expecting a CTR loop");
+ MachineFunction *MF = MBB.getParent();
+ DebugLoc DL = Cmp.getDebugLoc();
+ MachineInstr *Loop = findLoopInstr(PreHeader);
+ if (!Loop)
+ return 0;
+ Register LoopCountReg = Loop->getOperand(0).getReg();
+ MachineRegisterInfo &MRI = MF->getRegInfo();
+ MachineInstr *LoopCount = MRI.getUniqueVRegDef(LoopCountReg);
+
+ if (!LoopCount)
+ return 0;
+ // If the loop trip count is a compile-time value, then just change the
+ // value.
+ if (LoopCount->getOpcode() == PPC::LI8 || LoopCount->getOpcode() == PPC::LI) {
+ int64_t Offset = LoopCount->getOperand(1).getImm();
+ if (Offset <= 1) {
+ LoopCount->eraseFromParent();
+ Loop->eraseFromParent();
+ return 0;
+ }
+ LoopCount->getOperand(1).setImm(Offset - 1);
+ return Offset - 1;
+ }
+
+ // The loop trip count is a run-time value.
+ // We need to subtract one from the trip count,
+ // and insert branch later to check if we're done with the loop.
+
+ // Since BDZ/BDZ8 that we will insert will also decrease the ctr by 1,
+ // so we don't need to generate any thing here.
+ Cond.push_back(MachineOperand::CreateImm(0));
+ Cond.push_back(MachineOperand::CreateReg(
+ Subtarget.isPPC64() ? PPC::CTR8 : PPC::CTR, true));
+ return LoopCountReg;
+}
+
// Return true if get the base operand, byte offset of an instruction and the
// memory width. Width is the size of memory that is being loaded/stored.
bool PPCInstrInfo::getMemOperandWithOffsetWidth(
Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h?rev=372425&r1=372424&r2=372425&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h Fri Sep 20 13:25:16 2019
@@ -486,14 +486,26 @@ public:
/// On PPC, we have two instructions used to set-up the hardware loop
/// (MTCTRloop, MTCTR8loop) with corresponding endloop (BDNZ, BDNZ8)
/// instructions to indicate the end of a loop.
- MachineInstr *
- findLoopInstr(MachineBasicBlock &PreHeader,
- SmallPtrSet<MachineBasicBlock *, 8> &Visited) const;
+ MachineInstr *findLoopInstr(MachineBasicBlock &PreHeader) const;
- /// Analyze loop L, which must be a single-basic-block loop, and if the
- /// conditions can be understood enough produce a PipelinerLoopInfo object.
- std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
- analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override;
+ /// Analyze the loop code to find the loop induction variable and compare used
+ /// to compute the number of iterations. Currently, we analyze loop that are
+ /// controlled using hardware loops. In this case, the induction variable
+ /// instruction is null. For all other cases, this function returns true,
+ /// which means we're unable to analyze it. \p IndVarInst and \p CmpInst will
+ /// return new values when we can analyze the readonly loop \p L, otherwise,
+ /// nothing got changed
+ bool analyzeLoop(MachineLoop &L, MachineInstr *&IndVarInst,
+ MachineInstr *&CmpInst) const override;
+ /// Generate code to reduce the loop iteration by one and check if the loop
+ /// is finished. Return the value/register of the new loop count. We need
+ /// this function when peeling off one or more iterations of a loop. This
+ /// function assumes the last iteration is peeled first.
+ unsigned reduceLoopCount(MachineBasicBlock &MBB, MachineBasicBlock &PreHeader,
+ MachineInstr *IndVar, MachineInstr &Cmp,
+ SmallVectorImpl<MachineOperand> &Cond,
+ SmallVectorImpl<MachineInstr *> &PrevInsts,
+ unsigned Iter, unsigned MaxIter) const override;
};
}
Modified: llvm/trunk/test/CodeGen/Hexagon/swp-epilog-phi7.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/swp-epilog-phi7.ll?rev=372425&r1=372424&r2=372425&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/swp-epilog-phi7.ll (original)
+++ llvm/trunk/test/CodeGen/Hexagon/swp-epilog-phi7.ll Fri Sep 20 13:25:16 2019
@@ -7,8 +7,8 @@
; CHECK: if ({{.*}}) jump
; CHECK: [[VREG:v([0-9]+)]]{{.*}} = {{.*}}vmem(r{{[0-9]+}}++#1)
-; CHECK: if ({{.*}}) {{jump|jump:nt|jump:t}} [[EPLOG1:(.*)]]
-; CHECK: if ({{.*}}) {{jump|jump:nt|jump:t}} [[EPLOG:(.*)]]
+; CHECK: if ({{.*}}) {{jump|jump:nt}} [[EPLOG1:(.*)]]
+; CHECK: if ({{.*}}) {{jump|jump:nt}} [[EPLOG:(.*)]]
; CHECK: [[EPLOG]]:
; CHECK: [[VREG1:v([0-9]+)]] = [[VREG]]
; CHECK: [[VREG]] = v{{[0-9]+}}
More information about the llvm-commits
mailing list