summaryrefslogtreecommitdiff
path: root/lib/Target/Mips/MipsLongBranch.cpp
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 /lib/Target/Mips/MipsLongBranch.cpp
parent41087d99df6ed87405639a6ee1a4bc7b825d4b65 (diff)
downloadllvm-95ce098219b204612be7595a94a382d5cab6eea4.tar.gz
llvm-95ce098219b204612be7595a94a382d5cab6eea4.tar.bz2
llvm-95ce098219b204612be7595a94a382d5cab6eea4.tar.xz
[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
Diffstat (limited to 'lib/Target/Mips/MipsLongBranch.cpp')
-rw-r--r--lib/Target/Mips/MipsLongBranch.cpp36
1 files changed, 18 insertions, 18 deletions
diff --git a/lib/Target/Mips/MipsLongBranch.cpp b/lib/Target/Mips/MipsLongBranch.cpp
index a8fd39176e..acfe76e35c 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);