1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[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
This commit is contained in:
Krzysztof Parzyszek 2016-05-26 19:44:28 +00:00
parent 6d0c828d28
commit 871650f3b5
7 changed files with 100 additions and 25 deletions

View File

@ -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())

View File

@ -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;

View File

@ -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; }

View File

@ -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)

View File

@ -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
}

View File

@ -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)

View File

@ -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]*}})