[mips] Compact branch policy control for MIPSR6

This patch adds the commandline option -mips-compact-branches={never,optimal,always),
which controls how LLVM generates compact branches for MIPS targets. By
default, the compact branch policy is 'optimal' where LLVM will (hopefully)
pick the optimal branch for any situation. The 'never' policy will disable
the generation of compact branches and 'always' will generate compact branches
wherever possible.

Reviewers: dsanders

Differential Review: http://reviews.llvm.org/D20167


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269753 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Simon Dardis 2016-05-17 10:21:43 +00:00
parent 6bb068f15c
commit e7441472ae
2 changed files with 62 additions and 8 deletions

View File

@ -62,6 +62,28 @@ static cl::opt<bool> DisableBackwardSearch(
cl::desc("Disallow MIPS delay filler to search backward."),
cl::Hidden);
enum CompactBranchPolicy {
CB_Never, ///< The policy 'never' may in some circumstances or for some
///< ISAs not be absolutely adhered to.
CB_Optimal, ///< Optimal is the default and will produce compact branches
///< when delay slots cannot be filled.
CB_Always ///< 'always' may in some circumstances may not be
///< absolutely adhered to there may not be a corresponding
///< compact form of a branch.
};
static cl::opt<CompactBranchPolicy> MipsCompactBranchPolicy(
"mips-compact-branches",cl::Optional,
cl::init(CB_Optimal),
cl::desc("MIPS Specific: Compact branch policy."),
cl::values(
clEnumValN(CB_Never, "never", "Do not use compact branches if possible."),
clEnumValN(CB_Optimal, "optimal", "Use compact branches where appropiate (default)."),
clEnumValN(CB_Always, "always", "Always use compact branches if possible."),
clEnumValEnd
)
);
namespace {
typedef MachineBasicBlock::iterator Iter;
typedef MachineBasicBlock::reverse_iterator ReverseIter;
@ -563,14 +585,17 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None)) {
bool Filled = false;
if (searchBackward(MBB, I)) {
Filled = true;
} else if (I->isTerminator()) {
if (searchSuccBBs(MBB, I)) {
if (MipsCompactBranchPolicy.getValue() != CB_Always ||
!TII->getEquivalentCompactForm(I)) {
if (searchBackward(MBB, I)) {
Filled = true;
} else if (I->isTerminator()) {
if (searchSuccBBs(MBB, I)) {
Filled = true;
}
} else if (searchForward(MBB, I)) {
Filled = true;
}
} else if (searchForward(MBB, I)) {
Filled = true;
}
if (Filled) {
@ -596,8 +621,9 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
// For MIPSR6 attempt to produce the corresponding compact (no delay slot)
// form of the CTI. For indirect jumps this will not require inserting a
// NOP and for branches will hopefully avoid requiring a NOP.
if ((InMicroMipsMode || STI.hasMips32r6()) &&
TII->getEquivalentCompactForm(I)) {
if ((InMicroMipsMode ||
(STI.hasMips32r6() && MipsCompactBranchPolicy != CB_Never)) &&
TII->getEquivalentCompactForm(I)) {
I = replaceWithCompactBranch(MBB, I, I->getDebugLoc());
continue;
}

View File

@ -0,0 +1,28 @@
; Check that -mips-compact-branches={never,optimal,always} is accepted and honoured.
; RUN: llc -march=mips -mcpu=mips32r6 -mips-compact-branches=never < %s | FileCheck %s -check-prefix=NEVER
; RUN: llc -march=mips -mcpu=mips32r6 -mips-compact-branches=optimal < %s | FileCheck %s -check-prefix=OPTIMAL
; RUN: llc -march=mips -mcpu=mips32r6 -mips-compact-branches=always < %s | FileCheck %s -check-prefix=ALWAYS
define i32 @l(i32 signext %a, i32 signext %b) {
entry:
%add = add nsw i32 %b, %a
%cmp = icmp slt i32 %add, 100
; NEVER: beq
; OPTIMAL: beq
; ALWAYS: beqzc
; This nop is required for correct as having (j|b)al as the instruction
; immediately following beqzc would cause a forbidden slot hazard.
; ALWAYS: nop
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
%call = tail call i32 @k()
br label %if.end
if.end: ; preds = %entry, %if.then
%call.pn = phi i32 [ %call, %if.then ], [ -1, %entry ]
%c.0 = add nsw i32 %call.pn, %add
ret i32 %c.0
}
declare i32 @k() #1