[PATCH] Optimize long branch for MIPS64 by removing calculation of %higher and %highest

Sasa Stankovic Sasa.Stankovic at imgtec.com
Thu Apr 3 13:49:52 PDT 2014


Hi mseaborn,

[mips] Optimize long branch for MIPS64.  Since %higher and %highest can have non-zero values only for offsets greater than 4GB (which is highly unlikely, if not impossible when compiling a single function), replace them with the instruction that just initializes register to zero.  This makes long branch for MIPS64 2 instructions smaller.

http://llvm-reviews.chandlerc.com/D3281

Files:
  lib/Target/Mips/MipsLongBranch.cpp
  test/CodeGen/Mips/longbranch.ll

Index: lib/Target/Mips/MipsLongBranch.cpp
===================================================================
--- lib/Target/Mips/MipsLongBranch.cpp
+++ lib/Target/Mips/MipsLongBranch.cpp
@@ -64,7 +64,7 @@
       : 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 ? 11 : 9)) {}
 
     virtual const char *getPassName() const {
       return "Mips Long Branch";
@@ -324,9 +324,7 @@
       // $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, $zero, 0
       //  daddiu $at, $at, %hi($tgt - $baltgt)
       //  bal $baltgt
       //  dsll $at, $at, 16
@@ -339,23 +337,40 @@
       // $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.
+      // Note that we optimized offset calculation by using
+      //
+      //   daddiu $at, $zero, 0
+      //
+      // instead of
+      //
+      //   lui64 $at, %highest($tgt - $baltgt)
+      //   daddiu $at, $at, %higher($tgt - $baltgt)
+      //   dsll $at, $at, 16
+      //
+      // It's safe to do this because %highest and %higher can have non-zero
+      // values only when the offset is greater than 4GB, which is highly
+      // unlikely, if not impossible when compiling a single function.
+      //
+      // 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();
 
       BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
         .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::DADDiu), Mips::AT_64)
+        .addReg(Mips::ZERO_64).addImm(0);
       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);
 
Index: test/CodeGen/Mips/longbranch.ll
===================================================================
--- test/CodeGen/Mips/longbranch.ll
+++ test/CodeGen/Mips/longbranch.ll
@@ -76,10 +76,8 @@
 
 ; N64:        daddiu  $sp, $sp, -16
 ; N64:        sd      $ra, 0($sp)
-; N64:        lui     $1, %highest(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]]))
-; N64:        daddiu  $1, $1, %higher(($[[BB2]])-($[[BB1]]))
-; N64:        dsll    $1, $1, 16
-; N64:        daddiu  $1, $1, %hi(($[[BB2]])-($[[BB1]]))
+; N64:        daddiu  $1, $zero, 0
+; N64:        daddiu  $1, $1, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]]))
 ; N64:        bal     $[[BB1]]
 ; N64:        dsll    $1, $1, 16
 ; N64:   $[[BB1]]:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3281.1.patch
Type: text/x-patch
Size: 3989 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140403/07341c7b/attachment.bin>


More information about the llvm-commits mailing list