[mips] Optimize long branch for MIPS64 by removing %higher and %highest.
authorSasa Stankovic <Sasa.Stankovic@imgtec.com>
Tue, 27 May 2014 18:53:06 +0000 (18:53 +0000)
committerSasa Stankovic <Sasa.Stankovic@imgtec.com>
Tue, 27 May 2014 18:53:06 +0000 (18:53 +0000)
%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

lib/Target/Mips/Mips64InstrInfo.td
lib/Target/Mips/MipsAsmPrinter.cpp
lib/Target/Mips/MipsLongBranch.cpp
lib/Target/Mips/MipsMCInstLower.cpp
lib/Target/Mips/MipsMCInstLower.h
test/CodeGen/Mips/longbranch.ll

index 43103e65375e9eba6a6fc009d55bf1e85388c988..924b32529b2d6863202fc91a749e38fcbc8a5886 100644 (file)
@@ -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), []>;
index 626657e9dff2c4a56ad97edbf82b55cf0fabe151..6df90aa75a114dd715bf22ea1bec669efb5816c8 100644 (file)
@@ -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);
 }
 
index a8fd39176eb654ddc73887624421912cd1deb560..acfe76e35cf515bc0d14e3bce171671fd3f2db37 100644 (file)
@@ -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);
 
index 85f78674661105670d4cd47b1be1e9d0d3954e47..821392e1d45fb1bd5fbcc45e7d11fe83fea364e2 100644 (file)
@@ -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)
index 6971f49ff233db31da38d5585d84f022b3cdc3bd..269190ffc0659c55c8feb1c37018e24616fbc1a7 100644 (file)
@@ -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;
index f9980940643d9d93287bc745617cef82c7b8f465..c7fe6fd69dc1b77f1d1a99beeb76fd3f567c14dc 100644 (file)
@@ -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]]))