[llvm-commits] [llvm] r160601 - in /llvm/trunk: lib/Target/Mips/MipsInstrInfo.td lib/Target/Mips/MipsLongBranch.cpp test/CodeGen/Mips/longbranch.ll

Akira Hatanaka ahatanaka at mips.com
Fri Jul 20 20:30:44 PDT 2012


Author: ahatanak
Date: Fri Jul 20 22:30:44 2012
New Revision: 160601

URL: http://llvm.org/viewvc/llvm-project?rev=160601&view=rev
Log:
Fix Mips long branch pass.

This pass no longer requires that the global pointer value be saved to the
stack or register since it uses bal instruction to compute branch distance.


Modified:
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsLongBranch.cpp
    llvm/trunk/test/CodeGen/Mips/longbranch.ll

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=160601&r1=160600&r2=160601&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Fri Jul 20 22:30:44 2012
@@ -1005,6 +1005,10 @@
 def BLEZ    : CBranchZero<0x06, 0, "blez", setle, CPURegs>;
 def BLTZ    : CBranchZero<0x01, 0, "bltz", setlt, CPURegs>;
 
+let rt = 0, rs = 0, isBranch = 1, isTerminator = 1, isBarrier = 1,
+    hasDelaySlot = 1, Defs = [RA] in
+def BAL_BR: FI<0x1, (outs), (ins brtarget:$imm16), "bal\t$imm16", [], IIBranch>;
+
 def JAL  : JumpLink<0x03, "jal">;
 def JALR : JumpLinkReg<0x00, 0x09, "jalr", CPURegs>;
 def BGEZAL  : BranchLink<"bgezal", 0x11, CPURegs>;

Modified: llvm/trunk/lib/Target/Mips/MipsLongBranch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsLongBranch.cpp?rev=160601&r1=160600&r2=160601&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsLongBranch.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsLongBranch.cpp Fri Jul 20 22:30:44 2012
@@ -73,9 +73,6 @@
     void splitMBB(MachineBasicBlock *MBB);
     void initMBBInfo();
     int64_t computeOffset(const MachineInstr *Br);
-    bool offsetFitsIntoField(const MachineInstr *Br);
-    unsigned addLongBranch(MachineBasicBlock &MBB, Iter Pos,
-                           MachineBasicBlock *Tgt, DebugLoc DL, bool Nop);
     void replaceBranch(MachineBasicBlock &MBB, Iter Br, DebugLoc DL,
                        MachineBasicBlock *MBBOpnd);
     void expandToLongBranch(MBBInfo &Info);
@@ -178,7 +175,9 @@
     ReverseIter Br = getNonDebugInstr(MBB->rbegin(), End);
 
     if ((Br != End) && !Br->isIndirectBranch() &&
-        (Br->isConditionalBranch() || Br->isUnconditionalBranch()))
+        (Br->isConditionalBranch() ||
+         (Br->isUnconditionalBranch() &&
+          TM.getRelocationModel() == Reloc::PIC_)))
       MBBInfos[I].Br = (++Br).base();
   }
 }
@@ -204,77 +203,6 @@
   return -Offset + 4;
 }
 
-// Insert the following sequence:
-// (pic or N64)
-//  lw $at, global_reg_slot
-//  lw $at, got($L1)($at)
-//  addiu $at, $at, lo($L1)
-//  jr $at
-//  noop
-// (static and !N64)
-//  lui $at, hi($L1)
-//  addiu $at, $at, lo($L1)
-//  jr $at
-//  noop
-unsigned MipsLongBranch::addLongBranch(MachineBasicBlock &MBB, Iter Pos,
-                                       MachineBasicBlock *Tgt, DebugLoc DL,
-                                       bool Nop) {
-  MF->getInfo<MipsFunctionInfo>()->setEmitNOAT();
-  bool IsPIC = (TM.getRelocationModel() == Reloc::PIC_);
-  unsigned ABI = TM.getSubtarget<MipsSubtarget>().getTargetABI();
-  bool N64 = (ABI == MipsSubtarget::N64);
-  unsigned NumInstrs;
-
-  if (IsPIC || N64) {
-    bool HasMips64 = TM.getSubtarget<MipsSubtarget>().hasMips64();
-    unsigned AT = N64 ? Mips::AT_64 : Mips::AT;
-    unsigned Load = N64 ? Mips::LD_P8 : Mips::LW;
-    unsigned ADDiu = N64 ? Mips::DADDiu : Mips::ADDiu;
-    unsigned JR = N64 ? Mips::JR64 : Mips::JR;
-    unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
-    unsigned OFSTFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
-    const MipsRegisterInfo *MRI =
-      static_cast<const MipsRegisterInfo*>(TM.getRegisterInfo());
-    unsigned SP = MRI->getFrameRegister(*MF);
-    unsigned GlobalRegFI = MF->getInfo<MipsFunctionInfo>()->getGlobalRegFI();
-    int64_t Offset = MF->getFrameInfo()->getObjectOffset(GlobalRegFI);
-
-    if (isInt<16>(Offset)) {
-      BuildMI(MBB, Pos, DL, TII->get(Load), AT).addReg(SP).addImm(Offset);
-      NumInstrs = 1;
-    } else {
-      unsigned ADDu = N64 ? Mips::DADDu : Mips::ADDu;
-      MipsAnalyzeImmediate::Inst LastInst(0, 0);
-
-      MF->getInfo<MipsFunctionInfo>()->setEmitNOAT();
-      NumInstrs = Mips::loadImmediate(Offset, N64, *TII, MBB, Pos, DL, true,
-                                      &LastInst) + 2;
-      BuildMI(MBB, Pos, DL, TII->get(ADDu), AT).addReg(SP).addReg(AT);
-      BuildMI(MBB, Pos, DL, TII->get(Load), AT).addReg(AT)
-        .addImm(SignExtend64<16>(LastInst.ImmOpnd));
-    }
-
-    BuildMI(MBB, Pos, DL, TII->get(Load), AT).addReg(AT).addMBB(Tgt, GOTFlag);
-    BuildMI(MBB, Pos, DL, TII->get(ADDiu), AT).addReg(AT).addMBB(Tgt, OFSTFlag);
-    BuildMI(MBB, Pos, DL, TII->get(JR)).addReg(Mips::AT, RegState::Kill);
-    NumInstrs += 3;
-  } else {
-    BuildMI(MBB, Pos, DL, TII->get(Mips::LUi), Mips::AT)
-      .addMBB(Tgt, MipsII::MO_ABS_HI);
-    BuildMI(MBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT)
-      .addReg(Mips::AT).addMBB(Tgt, MipsII::MO_ABS_LO);
-    BuildMI(MBB, Pos, DL, TII->get(Mips::JR)).addReg(Mips::AT, RegState::Kill);
-    NumInstrs = 3;
-  }
-
-  if (Nop) {
-    BuildMI(MBB, Pos, DL, TII->get(Mips::NOP))->setIsInsideBundle();
-    ++NumInstrs;
-  }
-
-  return NumInstrs;
-}
-
 // Replace Br with a branch which has the opposite condition code and a
 // MachineBasicBlock operand MBBOpnd.
 void MipsLongBranch::replaceBranch(MachineBasicBlock &MBB, Iter Br,
@@ -304,57 +232,138 @@
 void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
   I.HasLongBranch = true;
 
-  MachineBasicBlock *MBB = I.Br->getParent(), *Tgt = getTargetMBB(*I.Br);
-  DebugLoc DL = I.Br->getDebugLoc();
+  bool IsPIC = TM.getRelocationModel() == Reloc::PIC_;
+  unsigned ABI = TM.getSubtarget<MipsSubtarget>().getTargetABI();
+  bool N64 = ABI == MipsSubtarget::N64;
 
-  if (I.Br->isUnconditionalBranch()) {
-    // Unconditional branch before transformation:
-    //   b $tgt
-    //   delay-slot-instr
+  MachineBasicBlock::iterator Pos;
+  MachineBasicBlock *MBB = I.Br->getParent(), *TgtMBB = getTargetMBB(*I.Br);
+  DebugLoc DL = I.Br->getDebugLoc();
+  const BasicBlock *BB = MBB->getBasicBlock();
+  MachineFunction::iterator FallThroughMBB = ++MachineFunction::iterator(MBB);
+  MachineBasicBlock *LongBrMBB = MF->CreateMachineBasicBlock(BB);
+
+  MF->insert(FallThroughMBB, LongBrMBB);
+  MBB->removeSuccessor(TgtMBB);
+  MBB->addSuccessor(LongBrMBB);
+
+  if (IsPIC) {
+    // $longbr:
+    //  addiu $sp, $sp, -regsize * 2
+    //  sw $ra, 0($sp)
+    //  bal $baltgt
+    //  sw $a3, regsize($sp)
+    // $baltgt:
+    //  lui $a3, %hi($baltgt)
+    //  lui $at, %hi($tgt)
+    //  addiu $a3, $a3, %lo($baltgt)
+    //  addiu $at, $at, %lo($tgt)
+    //  subu $at, $at, $a3
+    //  addu $at, $ra, $at
     //
-    // after transformation:
-    //   delay-slot-instr
-    //   lw $at, global_reg_slot
-    //   lw $at, %got($tgt)($at)
-    //   addiu $at, $at, %lo($tgt)
-    //   jr $at
-    //   nop
-    I.Size += (addLongBranch(*MBB, llvm::next(Iter(I.Br)), Tgt, DL, true)
-               - 1) * 4;
-
-    // Remove branch and clear InsideBundle bit of the next instruction.
-    llvm::next(MachineBasicBlock::instr_iterator(I.Br))
-      ->setIsInsideBundle(false);
-    I.Br->eraseFromParent();
-    return;
-  }
+    //  if n64:
+    //   lui $a3, %highest($baltgt)
+    //   lui $ra, %highest($tgt)
+    //   addiu $a3, $a3, %higher($baltgt)
+    //   addiu $ra, $ra, %higher($tgt)
+    //   dsll $a3, $a3, 32
+    //   dsll $ra, $ra, 32
+    //   subu $at, $at, $a3
+    //   addu $at, $at, $ra
+    //
+    //  lw $ra, 0($sp)
+    //  lw $a3, regsize($sp)
+    //  jr $at
+    //  addiu $sp, $sp, regsize * 2
+    // $fallthrough:
+    //
+    MF->getInfo<MipsFunctionInfo>()->setEmitNOAT();
+    MachineBasicBlock *BalTgtMBB = MF->CreateMachineBasicBlock(BB);
+    MF->insert(FallThroughMBB, BalTgtMBB);
+    LongBrMBB->addSuccessor(BalTgtMBB);
+    BalTgtMBB->addSuccessor(TgtMBB);
 
-  assert(I.Br->isConditionalBranch() && "Conditional branch expected.");
+    int RegSize = N64 ? 8 : 4;
+    unsigned AT = N64 ? Mips::AT_64 : Mips::AT;
+    unsigned A3 = N64 ? Mips::A3_64 : Mips::A3;
+    unsigned SP = N64 ? Mips::SP_64 : Mips::SP;
+    unsigned RA = N64 ? Mips::RA_64 : Mips::RA;
+    unsigned Load = N64 ? Mips::LD_P8 : Mips::LW;
+    unsigned Store = N64 ? Mips::SD_P8 : Mips::SW;
+    unsigned LUi = N64 ? Mips::LUi64 : Mips::LUi;
+    unsigned ADDiu = N64 ? Mips::DADDiu : Mips::ADDiu;
+    unsigned ADDu = N64 ? Mips::DADDu : Mips::ADDu;
+    unsigned SUBu = N64 ? Mips::SUBu : Mips::SUBu;
+    unsigned JR = N64 ? Mips::JR64 : Mips::JR;
 
-  // Conditional branch before transformation:
-  //   b cc, $tgt
-  //   delay-slot-instr
-  //  FallThrough:
-  //
-  // after transformation:
-  //   b !cc, FallThrough
-  //   delay-slot-instr
-  //  NewMBB:
-  //   lw $at, global_reg_slot
-  //   lw $at, %got($tgt)($at)
-  //   addiu $at, $at, %lo($tgt)
-  //   jr $at
-  //   noop
-  //  FallThrough:
+    Pos = LongBrMBB->begin();
 
-  MachineBasicBlock *NewMBB = MF->CreateMachineBasicBlock(MBB->getBasicBlock());
-  MF->insert(llvm::next(MachineFunction::iterator(MBB)), NewMBB);
-  MBB->removeSuccessor(Tgt);
-  MBB->addSuccessor(NewMBB);
-  NewMBB->addSuccessor(Tgt);
+    BuildMI(*LongBrMBB, Pos, DL, TII->get(ADDiu), SP).addReg(SP)
+      .addImm(-RegSize * 2);
+    BuildMI(*LongBrMBB, Pos, DL, TII->get(Store)).addReg(RA).addReg(SP)
+      .addImm(0);
+    BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB);
+    BuildMI(*LongBrMBB, Pos, DL, TII->get(Store)).addReg(A3).addReg(SP)
+      .addImm(RegSize)->setIsInsideBundle();
+
+    Pos = BalTgtMBB->begin();
+
+    BuildMI(*BalTgtMBB, Pos, DL, TII->get(LUi), A3)
+      .addMBB(BalTgtMBB, MipsII::MO_ABS_HI);
+    BuildMI(*BalTgtMBB, Pos, DL, TII->get(LUi), AT)
+      .addMBB(TgtMBB, MipsII::MO_ABS_HI);
+    BuildMI(*BalTgtMBB, Pos, DL, TII->get(ADDiu), A3).addReg(A3)
+      .addMBB(BalTgtMBB, MipsII::MO_ABS_LO);
+    BuildMI(*BalTgtMBB, Pos, DL, TII->get(ADDiu), AT).addReg(AT)
+      .addMBB(TgtMBB, MipsII::MO_ABS_LO);
+    BuildMI(*BalTgtMBB, Pos, DL, TII->get(SUBu), AT).addReg(AT).addReg(A3);
+    BuildMI(*BalTgtMBB, Pos, DL, TII->get(ADDu), AT).addReg(RA).addReg(AT);
+
+    if (N64) {
+      BuildMI(*BalTgtMBB, Pos, DL, TII->get(LUi), A3)
+        .addMBB(BalTgtMBB, MipsII::MO_HIGHEST);
+      BuildMI(*BalTgtMBB, Pos, DL, TII->get(LUi), RA)
+        .addMBB(TgtMBB, MipsII::MO_HIGHEST);
+      BuildMI(*BalTgtMBB, Pos, DL, TII->get(ADDiu), A3).addReg(A3)
+        .addMBB(BalTgtMBB, MipsII::MO_HIGHER);
+      BuildMI(*BalTgtMBB, Pos, DL, TII->get(ADDiu), RA).addReg(RA)
+        .addMBB(TgtMBB, MipsII::MO_HIGHER);
+      BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DSLL), A3).addReg(A3)
+        .addImm(32);
+      BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DSLL), RA).addReg(RA)
+        .addImm(32);
+      BuildMI(*BalTgtMBB, Pos, DL, TII->get(SUBu), AT).addReg(AT).addReg(A3);
+      BuildMI(*BalTgtMBB, Pos, DL, TII->get(ADDu), AT).addReg(AT).addReg(RA);
+      I.Size += 4 * 8;
+    }
+
+    BuildMI(*BalTgtMBB, Pos, DL, TII->get(Load), RA).addReg(SP).addImm(0);
+    BuildMI(*BalTgtMBB, Pos, DL, TII->get(Load), A3).addReg(SP).addImm(RegSize);
+    BuildMI(*BalTgtMBB, Pos, DL, TII->get(JR)).addReg(AT);
+    BuildMI(*BalTgtMBB, Pos, DL, TII->get(ADDiu), SP).addReg(SP)
+      .addImm(RegSize * 2)->setIsInsideBundle();
+    I.Size += 4 * 14;
+  } else {
+    // $longbr:
+    //  j $tgt
+    //  nop
+    // $fallthrough:
+    //
+    Pos = LongBrMBB->begin();
+    LongBrMBB->addSuccessor(TgtMBB);
+    BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::J)).addMBB(TgtMBB);
+    BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::NOP))->setIsInsideBundle();
+    I.Size += 4 * 2;
+  }
 
-  I.Size += addLongBranch(*NewMBB, NewMBB->begin(), Tgt, DL, true) * 4;
-  replaceBranch(*MBB, I.Br, DL, *MBB->succ_begin());
+  if (I.Br->isUnconditionalBranch()) {
+    // Change branch destination.
+    assert(I.Br->getDesc().getNumOperands() == 1);
+    I.Br->RemoveOperand(0);
+    I.Br->addOperand(MachineOperand::CreateMBB(LongBrMBB));
+  } else
+    // Change branch destination and reverse condition.
+    replaceBranch(*MBB, I.Br, DL, FallThroughMBB);
 }
 
 static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII) {
@@ -380,7 +389,6 @@
   MF = &F;
   initMBBInfo();
 
-  bool IsPIC = (TM.getRelocationModel() == Reloc::PIC_);
   SmallVector<MBBInfo, 16>::iterator I, E = MBBInfos.end();
   bool EverMadeChange = false, MadeChange = true;
 
@@ -393,17 +401,10 @@
       if (!I->Br || I->HasLongBranch)
         continue;
 
-      if (!ForceLongBranch) {
-        int64_t Offset = computeOffset(I->Br);
-
+      if (!ForceLongBranch)
         // Check if offset fits into 16-bit immediate field of branches.
-        if ((I->Br->isConditionalBranch() || IsPIC) && isInt<16>(Offset / 4))
-          continue;
-
-        // Check if offset fits into 26-bit immediate field of jumps (J).
-        if (I->Br->isUnconditionalBranch() && !IsPIC && isInt<26>(Offset / 4))
+        if (isInt<16>(computeOffset(I->Br) / 4))
           continue;
-      }
 
       expandToLongBranch(*I);
       ++LongBranches;

Modified: llvm/trunk/test/CodeGen/Mips/longbranch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/longbranch.ll?rev=160601&r1=160600&r2=160601&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/longbranch.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/longbranch.ll Fri Jul 20 22:30:44 2012
@@ -1,12 +1,14 @@
-; RUN: llc -march=mipsel -force-mips-long-branch < %s | FileCheck %s
+; RUN: llc -march=mipsel -force-mips-long-branch < %s | FileCheck %s -check-prefix=O32
+; RUN: llc -march=mips64el -mcpu=mips64 -mattr=n64  -force-mips-long-branch < %s | FileCheck %s -check-prefix=N64
 
 @g0 = external global i32
 
 define void @foo1(i32 %s) nounwind {
 entry:
-; CHECK: lw  $[[R0:[a-z0-9]+]], %got($BB0_3)(${{[a-z0-9]+}})
-; CHECK: addiu $[[R1:[a-z0-9]+]], $[[R0]], %lo($BB0_3)
-; CHECK: jr  $[[R1]]
+; O32: bal
+; N64: bal
+; N64: highest
+; N64: higher
 
   %tobool = icmp eq i32 %s, 0
   br i1 %tobool, label %if.end, label %if.then





More information about the llvm-commits mailing list