mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-27 07:12:06 +00:00
[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:
parent
6bb068f15c
commit
e7441472ae
@ -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;
|
||||
}
|
||||
|
28
test/CodeGen/Mips/compactbranches/compact-branch-policy.ll
Normal file
28
test/CodeGen/Mips/compactbranches/compact-branch-policy.ll
Normal 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
|
Loading…
x
Reference in New Issue
Block a user