summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSasa Stankovic <Sasa.Stankovic@imgtec.com>2014-05-27 18:53:06 +0000
committerSasa Stankovic <Sasa.Stankovic@imgtec.com>2014-05-27 18:53:06 +0000
commit95ce098219b204612be7595a94a382d5cab6eea4 (patch)
tree80ef49bd60749ac8336e6a7e900c20eb53485102
parent41087d99df6ed87405639a6ee1a4bc7b825d4b65 (diff)
[mips] Optimize long branch for MIPS64 by removing %higher and %highest.
%higher and %highest can have non-zero values only for offsets greater than 2GB, which is highly unlikely, if not impossible when compiling a single function. This makes long branch for MIPS64 3 instructions smaller. Differential Revision: http://llvm-reviews.chandlerc.com/D3281.diff git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209678 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/Mips/Mips64InstrInfo.td8
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp1
-rw-r--r--lib/Target/Mips/MipsLongBranch.cpp36
-rw-r--r--lib/Target/Mips/MipsMCInstLower.cpp23
-rw-r--r--lib/Target/Mips/MipsMCInstLower.h3
-rw-r--r--test/CodeGen/Mips/longbranch.ll5
6 files changed, 30 insertions, 46 deletions
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td
index 43103e65375..924b32529b2 100644
--- a/lib/Target/Mips/Mips64InstrInfo.td
+++ b/lib/Target/Mips/Mips64InstrInfo.td
@@ -245,16 +245,12 @@ let isCodeGenOnly = 1, rs = 0, shamt = 0 in {
"sll\t$rd, $rt, 0", [], II_SLL>;
}
-// We need the following two pseudo instructions to avoid offset calculation for
+// We need the following pseudo instruction to avoid offset calculation for
// long branches. See the comment in file MipsLongBranch.cpp for detailed
// explanation.
-// Expands to: lui $dst, %highest($tgt - $baltgt)
-def LONG_BRANCH_LUi64 : PseudoSE<(outs GPR64Opnd:$dst),
- (ins brtarget:$tgt, brtarget:$baltgt), []>;
-
// Expands to: daddiu $dst, $src, %PART($tgt - $baltgt)
-// where %PART may be %higher, %hi or %lo, depending on the relocation kind
+// where %PART may be %hi or %lo, depending on the relocation kind
// that $tgt is annotated with.
def LONG_BRANCH_DADDiu : PseudoSE<(outs GPR64Opnd:$dst),
(ins GPR64Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index 626657e9dff..6df90aa75a1 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -958,7 +958,6 @@ void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) {
bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
return (Opcode == Mips::LONG_BRANCH_LUi
|| Opcode == Mips::LONG_BRANCH_ADDiu
- || Opcode == Mips::LONG_BRANCH_LUi64
|| Opcode == Mips::LONG_BRANCH_DADDiu);
}
diff --git a/lib/Target/Mips/MipsLongBranch.cpp b/lib/Target/Mips/MipsLongBranch.cpp
index a8fd39176eb..acfe76e35cf 100644
--- a/lib/Target/Mips/MipsLongBranch.cpp
+++ b/lib/Target/Mips/MipsLongBranch.cpp
@@ -64,7 +64,7 @@ namespace {
: MachineFunctionPass(ID), TM(tm),
IsPIC(TM.getRelocationModel() == Reloc::PIC_),
ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()),
- LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : 9)) {}
+ LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 10 : 9)) {}
const char *getPassName() const override {
return "Mips Long Branch";
@@ -324,10 +324,7 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
// $longbr:
// daddiu $sp, $sp, -16
// sd $ra, 0($sp)
- // lui64 $at, %highest($tgt - $baltgt)
- // daddiu $at, $at, %higher($tgt - $baltgt)
- // dsll $at, $at, 16
- // daddiu $at, $at, %hi($tgt - $baltgt)
+ // daddiu $at, $zero, %hi($tgt - $baltgt)
// dsll $at, $at, 16
// bal $baltgt
// daddiu $at, $at, %lo($tgt - $baltgt)
@@ -339,10 +336,20 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
// $fallthrough:
//
- // TODO: %highest and %higher can have non-zero values only when the
- // offset is greater than 4GB, which is highly unlikely. Replace
- // them (and the following instructon that shifts $at by 16) with the
- // instruction that sets $at to zero.
+ // We assume the branch is within-function, and that offset is within
+ // +/- 2GB. High 32 bits will therefore always be zero.
+
+ // Note that this will work even if the offset is negative, because
+ // of the +1 modification that's added in that case. For example, if the
+ // offset is -1MB (0xFFFFFFFFFFF00000), the computation for %higher is
+ //
+ // 0xFFFFFFFFFFF00000 + 0x80008000 = 0x000000007FF08000
+ //
+ // and the bits [47:32] are zero. For %highest
+ //
+ // 0xFFFFFFFFFFF00000 + 0x800080008000 = 0x000080007FF08000
+ //
+ // and the bits [63:48] are zero.
Pos = LongBrMBB->begin();
@@ -350,16 +357,9 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
.addReg(Mips::SP_64).addImm(-16);
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64)
.addReg(Mips::SP_64).addImm(0);
- BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi64),
- Mips::AT_64).addMBB(TgtMBB).addMBB(BalTgtMBB);
- BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu),
- Mips::AT_64).addReg(Mips::AT_64).addMBB(TgtMBB, MipsII::MO_HIGHER)
- .addMBB(BalTgtMBB);
- BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
- .addReg(Mips::AT_64).addImm(16);
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu),
- Mips::AT_64).addReg(Mips::AT_64).addMBB(TgtMBB, MipsII::MO_ABS_HI)
- .addMBB(BalTgtMBB);
+ Mips::AT_64).addReg(Mips::ZERO_64)
+ .addMBB(TgtMBB, MipsII::MO_ABS_HI).addMBB(BalTgtMBB);
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
.addReg(Mips::AT_64).addImm(16);
diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp
index 85f78674661..821392e1d45 100644
--- a/lib/Target/Mips/MipsMCInstLower.cpp
+++ b/lib/Target/Mips/MipsMCInstLower.cpp
@@ -162,16 +162,16 @@ MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,
}
void MipsMCInstLower::
-lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI, int Opcode,
- MCSymbolRefExpr::VariantKind Kind) const {
- OutMI.setOpcode(Opcode);
+lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const {
+ OutMI.setOpcode(Mips::LUi);
// Lower register operand.
OutMI.addOperand(LowerOperand(MI->getOperand(0)));
- // Create %hi($tgt-$baltgt) or %highest($tgt-$baltgt).
+ // Create %hi($tgt-$baltgt).
OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),
- MI->getOperand(2).getMBB(), Kind));
+ MI->getOperand(2).getMBB(),
+ MCSymbolRefExpr::VK_Mips_ABS_HI));
}
void MipsMCInstLower::
@@ -185,7 +185,7 @@ lowerLongBranchADDiu(const MachineInstr *MI, MCInst &OutMI, int Opcode,
OutMI.addOperand(LowerOperand(MO));
}
- // Create %lo($tgt-$baltgt), %hi($tgt-$baltgt) or %higher($tgt-$baltgt).
+ // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),
MI->getOperand(3).getMBB(), Kind));
}
@@ -196,11 +196,7 @@ bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
default:
return false;
case Mips::LONG_BRANCH_LUi:
- lowerLongBranchLUi(MI, OutMI, Mips::LUi, MCSymbolRefExpr::VK_Mips_ABS_HI);
- return true;
- case Mips::LONG_BRANCH_LUi64:
- lowerLongBranchLUi(MI, OutMI, Mips::LUi64,
- MCSymbolRefExpr::VK_Mips_HIGHEST);
+ lowerLongBranchLUi(MI, OutMI);
return true;
case Mips::LONG_BRANCH_ADDiu:
lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu,
@@ -208,10 +204,7 @@ bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
return true;
case Mips::LONG_BRANCH_DADDiu:
unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
- if (TargetFlags == MipsII::MO_HIGHER)
- lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu,
- MCSymbolRefExpr::VK_Mips_HIGHER);
- else if (TargetFlags == MipsII::MO_ABS_HI)
+ if (TargetFlags == MipsII::MO_ABS_HI)
lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu,
MCSymbolRefExpr::VK_Mips_ABS_HI);
else if (TargetFlags == MipsII::MO_ABS_LO)
diff --git a/lib/Target/Mips/MipsMCInstLower.h b/lib/Target/Mips/MipsMCInstLower.h
index 6971f49ff23..269190ffc06 100644
--- a/lib/Target/Mips/MipsMCInstLower.h
+++ b/lib/Target/Mips/MipsMCInstLower.h
@@ -39,8 +39,7 @@ private:
MachineOperandType MOTy, unsigned Offset) const;
MCOperand createSub(MachineBasicBlock *BB1, MachineBasicBlock *BB2,
MCSymbolRefExpr::VariantKind Kind) const;
- void lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI,
- int Opcode, MCSymbolRefExpr::VariantKind Kind) const;
+ void lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const;
void lowerLongBranchADDiu(const MachineInstr *MI, MCInst &OutMI,
int Opcode,
MCSymbolRefExpr::VariantKind Kind) const;
diff --git a/test/CodeGen/Mips/longbranch.ll b/test/CodeGen/Mips/longbranch.ll
index f9980940643..c7fe6fd69dc 100644
--- a/test/CodeGen/Mips/longbranch.ll
+++ b/test/CodeGen/Mips/longbranch.ll
@@ -80,10 +80,7 @@ end:
; Check for long branch expansion:
; N64: daddiu $sp, $sp, -16
; N64-NEXT: sd $ra, 0($sp)
-; N64-NEXT: lui $1, %highest(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]]))
-; N64-NEXT: daddiu $1, $1, %higher(($[[BB2]])-($[[BB1]]))
-; N64-NEXT: dsll $1, $1, 16
-; N64-NEXT: daddiu $1, $1, %hi(($[[BB2]])-($[[BB1]]))
+; N64-NEXT: daddiu $1, $zero, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]]))
; N64-NEXT: dsll $1, $1, 16
; N64-NEXT: bal $[[BB1]]
; N64-NEXT: daddiu $1, $1, %lo(($[[BB2]])-($[[BB1]]))