diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-05-26 19:44:28 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-05-26 19:44:28 +0000 |
commit | da0b9a959eaa5e1fc0e7879574eac214f95f00a5 (patch) | |
tree | 08c1a28c4f0b23297ccf2a5edaedf11b56c29a07 | |
parent | a86a83bb2e49aa51cea215ab7cefd6ee24e636ea (diff) | |
download | bcm5719-llvm-da0b9a959eaa5e1fc0e7879574eac214f95f00a5.tar.gz bcm5719-llvm-da0b9a959eaa5e1fc0e7879574eac214f95f00a5.zip |
[Hexagon] Enable the post-RA scheduler
The aggressive anti-dependency breaker can rename the restored callee-
saved registers. To prevent this, mark these registers are live on all
paths to the return/tail-call instructions, and add implicit use operands
for them to these instructions.
llvm-svn: 270898
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp | 95 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonFrameLowering.h | 2 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonSubtarget.h | 1 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/adde.ll | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/newvaluestore.ll | 21 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/sube.ll | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/v60Intrins.ll | 2 |
7 files changed, 100 insertions, 25 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index 4d6235a9fe5..df9fdceb5d5 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -292,6 +292,26 @@ namespace { return false; } + /// Returns the "return" instruction from this block, or nullptr if there + /// isn't any. + MachineInstr *getReturn(MachineBasicBlock &MBB) { + for (auto &I : MBB) + if (I.isReturn()) + return &I; + return nullptr; + } + + bool isRestoreCall(unsigned Opc) { + switch (Opc) { + case Hexagon::RESTORE_DEALLOC_RET_JMP_V4: + case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC: + case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4: + case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC: + return true; + } + return false; + } + inline bool isOptNone(const MachineFunction &MF) { return MF.getFunction()->hasFnAttribute(Attribute::OptimizeNone) || MF.getTarget().getOptLevel() == CodeGenOpt::None; @@ -445,6 +465,28 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF, for (auto &B : MF) if (B.isReturnBlock()) insertEpilogueInBlock(B); + + for (auto &B : MF) { + if (B.empty()) + continue; + MachineInstr *RetI = getReturn(B); + if (!RetI || isRestoreCall(RetI->getOpcode())) + continue; + for (auto &R : CSI) + RetI->addOperand(MachineOperand::CreateReg(R.getReg(), false, true)); + } + } + + if (EpilogB) { + // If there is an epilog block, it may not have a return instruction. + // In such case, we need to add the callee-saved registers as live-ins + // in all blocks on all paths from the epilog to any return block. + unsigned MaxBN = 0; + for (auto &B : MF) + if (B.getNumber() >= 0) + MaxBN = std::max(MaxBN, unsigned(B.getNumber())); + BitVector DoneT(MaxBN+1), DoneF(MaxBN+1), Path(MaxBN+1); + updateExitPaths(*EpilogB, EpilogB, DoneT, DoneF, Path); } } @@ -544,13 +586,7 @@ void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &MBB) const { auto &HRI = *HST.getRegisterInfo(); unsigned SP = HRI.getStackRegister(); - MachineInstr *RetI = nullptr; - for (auto &I : MBB) { - if (!I.isReturn()) - continue; - RetI = &I; - break; - } + MachineInstr *RetI = getReturn(MBB); unsigned RetOpc = RetI ? RetI->getOpcode() : 0; MachineBasicBlock::iterator InsertPt = MBB.getFirstTerminator(); @@ -614,6 +650,51 @@ void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &MBB) const { } +bool HexagonFrameLowering::updateExitPaths(MachineBasicBlock &MBB, + MachineBasicBlock *RestoreB, BitVector &DoneT, BitVector &DoneF, + BitVector &Path) const { + assert(MBB.getNumber() >= 0); + unsigned BN = MBB.getNumber(); + if (Path[BN] || DoneF[BN]) + return false; + if (DoneT[BN]) + return true; + + auto &CSI = MBB.getParent()->getFrameInfo()->getCalleeSavedInfo(); + + Path[BN] = true; + bool ReachedExit = false; + for (auto &SB : MBB.successors()) + ReachedExit |= updateExitPaths(*SB, RestoreB, DoneT, DoneF, Path); + + if (!MBB.empty() && MBB.back().isReturn()) { + // Add implicit uses of all callee-saved registers to the reached + // return instructions. This is to prevent the anti-dependency breaker + // from renaming these registers. + MachineInstr &RetI = MBB.back(); + if (!isRestoreCall(RetI.getOpcode())) + for (auto &R : CSI) + RetI.addOperand(MachineOperand::CreateReg(R.getReg(), false, true)); + ReachedExit = true; + } + + // We don't want to add unnecessary live-ins to the restore block: since + // the callee-saved registers are being defined in it, the entry of the + // restore block cannot be on the path from the definitions to any exit. + if (ReachedExit && &MBB != RestoreB) { + for (auto &R : CSI) + if (!MBB.isLiveIn(R.getReg())) + MBB.addLiveIn(R.getReg()); + DoneT[BN] = true; + } + if (!ReachedExit) + DoneF[BN] = true; + + Path[BN] = false; + return ReachedExit; +} + + namespace { bool IsAllocFrame(MachineBasicBlock::const_iterator It) { if (!It->isBundle()) diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h index 3c3f03915d9..3e76214559b 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h @@ -91,6 +91,8 @@ private: const HexagonRegisterInfo &HRI, bool &PrologueStubs) const; bool insertCSRRestoresInBlock(MachineBasicBlock &MBB, const CSIVect &CSI, const HexagonRegisterInfo &HRI) const; + bool updateExitPaths(MachineBasicBlock &MBB, MachineBasicBlock *RestoreB, + BitVector &DoneT, BitVector &DoneF, BitVector &Path) const; void insertCFIInstructionsAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator At) const; diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.h b/llvm/lib/Target/Hexagon/HexagonSubtarget.h index 9d5a4a81503..d3ff482b1d4 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.h +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.h @@ -106,6 +106,7 @@ public: bool enableMachineSchedDefaultSched() const override { return false; } AntiDepBreakMode getAntiDepBreakMode() const override { return ANTIDEP_ALL; } + bool enablePostRAScheduler() const override { return true; } const std::string &getCPUString () const { return CPUString; } diff --git a/llvm/test/CodeGen/Hexagon/adde.ll b/llvm/test/CodeGen/Hexagon/adde.ll index 4a88914dc6c..43ddb4307ef 100644 --- a/llvm/test/CodeGen/Hexagon/adde.ll +++ b/llvm/test/CodeGen/Hexagon/adde.ll @@ -1,4 +1,4 @@ -; RUN: llc -march=hexagon -disable-hsdr -hexagon-expand-condsets=0 -hexagon-bit=0 < %s | FileCheck %s +; RUN: llc -march=hexagon -disable-hsdr -hexagon-expand-condsets=0 -hexagon-bit=0 -disable-post-ra < %s | FileCheck %s ; CHECK: r{{[0-9]+:[0-9]+}} = combine(#0, #1) ; CHECK: r{{[0-9]+:[0-9]+}} = combine(#0, #0) diff --git a/llvm/test/CodeGen/Hexagon/newvaluestore.ll b/llvm/test/CodeGen/Hexagon/newvaluestore.ll index 13cbba2d08e..cc1ff00ecdc 100644 --- a/llvm/test/CodeGen/Hexagon/newvaluestore.ll +++ b/llvm/test/CodeGen/Hexagon/newvaluestore.ll @@ -1,22 +1,13 @@ -; RUN: llc -march=hexagon -mcpu=hexagonv4 -disable-hexagon-misched < %s | FileCheck %s -; Check that we generate new value store packet in V4 +; RUN: llc -march=hexagon < %s | FileCheck %s +; Check that we generate new value store. @i = global i32 0, align 4 -@j = global i32 10, align 4 -@k = global i32 100, align 4 -define i32 @main() nounwind { +define i32 @main(i32 %x, i32* %p) nounwind { entry: ; CHECK: memw(r{{[0-9]+}}+#{{[0-9]+}}) = r{{[0-9]+}}.new - %number1 = alloca i32, align 4 - %number2 = alloca i32, align 4 - %number3 = alloca i32, align 4 - %0 = load i32 , i32 * @i, align 4 - store i32 %0, i32* %number1, align 4 - %1 = load i32 , i32 * @j, align 4 - store i32 %1, i32* %number2, align 4 - %2 = load i32 , i32 * @k, align 4 - store i32 %2, i32* %number3, align 4 - ret i32 %0 + %t0 = load i32, i32* @i, align 4 + store i32 %t0, i32* %p, align 4 + ret i32 %x } diff --git a/llvm/test/CodeGen/Hexagon/sube.ll b/llvm/test/CodeGen/Hexagon/sube.ll index fab3dcaefa8..e1688984b61 100644 --- a/llvm/test/CodeGen/Hexagon/sube.ll +++ b/llvm/test/CodeGen/Hexagon/sube.ll @@ -1,4 +1,4 @@ -; RUN: llc -march=hexagon -disable-hsdr -hexagon-expand-condsets=0 -hexagon-bit=0 < %s | FileCheck %s +; RUN: llc -march=hexagon -disable-hsdr -hexagon-expand-condsets=0 -hexagon-bit=0 -disable-post-ra < %s | FileCheck %s ; CHECK: r{{[0-9]+:[0-9]+}} = combine(#0, #1) ; CHECK: r{{[0-9]+:[0-9]+}} = combine(#0, #0) diff --git a/llvm/test/CodeGen/Hexagon/v60Intrins.ll b/llvm/test/CodeGen/Hexagon/v60Intrins.ll index 5f4f294c405..d0064c50e71 100644 --- a/llvm/test/CodeGen/Hexagon/v60Intrins.ll +++ b/llvm/test/CodeGen/Hexagon/v60Intrins.ll @@ -1,4 +1,4 @@ -; RUN: llc -march=hexagon -mcpu=hexagonv60 -O2 < %s | FileCheck %s +; RUN: llc -march=hexagon -mcpu=hexagonv60 -O2 -disable-post-ra < %s | FileCheck %s ; CHECK: q{{[0-3]}} = vand(v{{[0-9]*}},r{{[0-9]*}}) ; CHECK: q{{[0-3]}} = vsetq(r{{[0-9]*}}) |