diff options
| author | Mitch Phillips <mitchphillips@outlook.com> | 2019-09-20 20:25:16 +0000 |
|---|---|---|
| committer | Mitch Phillips <mitchphillips@outlook.com> | 2019-09-20 20:25:16 +0000 |
| commit | 72a3d8597da5cb50f3a21ba8a2f822117459af34 (patch) | |
| tree | df3e193898f34c22018d097e4b0f733bc7714a9d /llvm/lib/Target/Hexagon | |
| parent | ce7cfbccc63ba318bed00aef65dab49adc6f43c8 (diff) | |
| download | bcm5719-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.cpp | 152 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfo.h | 19 |
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" |

