summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon
diff options
context:
space:
mode:
authorMitch Phillips <mitchphillips@outlook.com>2019-09-20 20:25:16 +0000
committerMitch Phillips <mitchphillips@outlook.com>2019-09-20 20:25:16 +0000
commit72a3d8597da5cb50f3a21ba8a2f822117459af34 (patch)
treedf3e193898f34c22018d097e4b0f733bc7714a9d /llvm/lib/Target/Hexagon
parentce7cfbccc63ba318bed00aef65dab49adc6f43c8 (diff)
downloadbcm5719-llvm-72a3d8597da5cb50f3a21ba8a2f822117459af34.tar.gz
bcm5719-llvm-72a3d8597da5cb50f3a21ba8a2f822117459af34.zip
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. llvm-svn: 372425
Diffstat (limited to 'llvm/lib/Target/Hexagon')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp152
-rw-r--r--llvm/lib/Target/Hexagon/HexagonInstrInfo.h19
2 files changed, 92 insertions, 79 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index f9d464b0797..97318a8057b 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -674,84 +674,86 @@ unsigned HexagonInstrInfo::insertBranch(MachineBasicBlock &MBB,
return 2;
}
-class HexagonPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
- MachineInstr *Loop, *EndLoop;
- MachineFunction *MF;
- const HexagonInstrInfo *TII;
-
-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 {
+/// 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 {
+
+ 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,
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.h b/llvm/lib/Target/Hexagon/HexagonInstrInfo.h
index e863400480b..e0a999d0f4c 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.h
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.h
@@ -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"
OpenPOWER on IntegriCloud