[PPC] Disassemble little endian ppc instructions in the right byte order
[oota-llvm.git] / lib / Target / PowerPC / PPCBranchSelector.cpp
index e60399c56d10a9b803064bfeec205f0084427280..940d55ac1f36e68cb0a29c5f7bf8ecc8ee9e6bc1 100644 (file)
@@ -1,47 +1,61 @@
-//===-- PPCBranchSelector.cpp - Emit long conditional branches-----*- C++ -*-=//
+//===-- PPCBranchSelector.cpp - Emit long conditional branches ------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Nate Baegeman and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 // This file contains a pass that scans a machine function to determine which
 // conditional branches need more than 16 bits of displacement to reach their
 // target basic block.  It does this in two passes; a calculation of basic block
-// positions pass, and a branch psuedo op to machine branch opcode pass.  This
+// positions pass, and a branch pseudo op to machine branch opcode pass.  This
 // pass should be run last, just before the assembly printer.
 //
 //===----------------------------------------------------------------------===//
 
 #include "PPC.h"
+#include "MCTargetDesc/PPCPredicates.h"
 #include "PPCInstrBuilder.h"
 #include "PPCInstrInfo.h"
-#include "PPCPredicates.h"
+#include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetAsmInfo.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
 using namespace llvm;
 
-static Statistic<> NumExpanded("ppc-branch-select",
-                               "Num branches expanded to long format");
+#define DEBUG_TYPE "ppc-branch-select"
+
+STATISTIC(NumExpanded, "Number of branches expanded to long format");
+
+namespace llvm {
+  void initializePPCBSelPass(PassRegistry&);
+}
 
 namespace {
-  struct VISIBILITY_HIDDEN PPCBSel : public MachineFunctionPass {
-    /// OffsetMap - Mapping between BB # and byte offset from start of function.
-    std::vector<unsigned> OffsetMap;
+  struct PPCBSel : public MachineFunctionPass {
+    static char ID;
+    PPCBSel() : MachineFunctionPass(ID) {
+      initializePPCBSelPass(*PassRegistry::getPassRegistry());
+    }
 
-    virtual bool runOnMachineFunction(MachineFunction &Fn);
+    /// BlockSizes - The sizes of the basic blocks in the function.
+    std::vector<unsigned> BlockSizes;
 
-    virtual const char *getPassName() const {
-      return "PowerPC Branch Selection";
+    bool runOnMachineFunction(MachineFunction &Fn) override;
+
+    const char *getPassName() const override {
+      return "PowerPC Branch Selector";
     }
   };
+  char PPCBSel::ID = 0;
 }
 
+INITIALIZE_PASS(PPCBSel, "ppc-branch-select", "PowerPC Branch Selector",
+                false, false)
+
 /// createPPCBranchSelectionPass - returns an instance of the Branch Selection
 /// Pass
 ///
@@ -49,126 +63,175 @@ FunctionPass *llvm::createPPCBranchSelectionPass() {
   return new PPCBSel();
 }
 
-/// getNumBytesForInstruction - Return the number of bytes of code the specified
-/// instruction may be.  This returns the maximum number of bytes.
-///
-static unsigned getNumBytesForInstruction(MachineInstr *MI) {
-  switch (MI->getOpcode()) {
-  case PPC::COND_BRANCH:
-    // while this will be 4 most of the time, if we emit 8 it is just a
-    // minor pessimization that saves us from having to worry about
-    // keeping the offsets up to date later when we emit long branch glue.
-    return 8;
-  case PPC::IMPLICIT_DEF_GPRC: // no asm emitted
-  case PPC::IMPLICIT_DEF_G8RC: // no asm emitted
-  case PPC::IMPLICIT_DEF_F4:   // no asm emitted
-  case PPC::IMPLICIT_DEF_F8:   // no asm emitted
-  case PPC::IMPLICIT_DEF_VRRC: // no asm emitted
-    return 0;
-  case PPC::INLINEASM: {       // Inline Asm: Variable size.
-    MachineFunction *MF = MI->getParent()->getParent();
-    const char *AsmStr = MI->getOperand(0).getSymbolName();
-    return MF->getTarget().getTargetAsmInfo()->getInlineAsmLength(AsmStr);
-  }
-  default:
-    return 4; // PowerPC instructions are all 4 bytes
-  }
-}
+bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) {
+  const PPCInstrInfo *TII =
+      static_cast<const PPCInstrInfo *>(Fn.getSubtarget().getInstrInfo());
+  // Give the blocks of the function a dense, in-order, numbering.
+  Fn.RenumberBlocks();
+  BlockSizes.resize(Fn.getNumBlockIDs());
 
+  auto GetAlignmentAdjustment =
+    [TII](MachineBasicBlock &MBB, unsigned Offset) -> unsigned {
+    unsigned Align = MBB.getAlignment();
+    if (!Align)
+      return 0;
 
-bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) {
-  // Running total of instructions encountered since beginning of function
-  unsigned ByteCount = 0;
-  
-  OffsetMap.resize(Fn.getNumBlockIDs());
-  
-  // For each MBB, add its offset to the offset map, and count up its
-  // instructions
+    unsigned AlignAmt = 1 << Align;
+    unsigned ParentAlign = MBB.getParent()->getAlignment();
+
+    if (Align <= ParentAlign)
+      return OffsetToAlignment(Offset, AlignAmt);
+
+    // The alignment of this MBB is larger than the function's alignment, so we
+    // can't tell whether or not it will insert nops. Assume that it will.
+    return AlignAmt + OffsetToAlignment(Offset, AlignAmt);
+  };
+
+  // Measure each MBB and compute a size for the entire function.
+  unsigned FuncSize = 0;
   for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
        ++MFI) {
     MachineBasicBlock *MBB = MFI;
-    OffsetMap[MBB->getNumber()] = ByteCount;
-    
+
+    // The end of the previous block may have extra nops if this block has an
+    // alignment requirement.
+    if (MBB->getNumber() > 0) {
+      unsigned AlignExtra = GetAlignmentAdjustment(*MBB, FuncSize);
+      BlockSizes[MBB->getNumber()-1] += AlignExtra;
+      FuncSize += AlignExtra;
+    }
+
+    unsigned BlockSize = 0;
     for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
          MBBI != EE; ++MBBI)
-      ByteCount += getNumBytesForInstruction(MBBI);
+      BlockSize += TII->GetInstSizeInBytes(MBBI);
+    
+    BlockSizes[MBB->getNumber()] = BlockSize;
+    FuncSize += BlockSize;
   }
   
-  // We're about to run over the MBB's again, so reset the ByteCount
-  ByteCount = 0;
+  // If the entire function is smaller than the displacement of a branch field,
+  // we know we don't need to shrink any branches in this function.  This is a
+  // common case.
+  if (FuncSize < (1 << 15)) {
+    BlockSizes.clear();
+    return false;
+  }
   
-  // For each MBB, find the conditional branch pseudo instructions, and
-  // calculate the difference between the target MBB and the current ICount
-  // to decide whether or not to emit a short or long branch.
-  //
-  // short branch:
-  // bCC .L_TARGET_MBB
+  // For each conditional branch, if the offset to its destination is larger
+  // than the offset field allows, transform it into a long branch sequence
+  // like this:
+  //   short branch:
+  //     bCC MBB
+  //   long branch:
+  //     b!CC $PC+8
+  //     b MBB
   //
-  // long branch:
-  // bInverseCC $PC+8
-  // b .L_TARGET_MBB
-  for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
-       ++MFI) {
-    MachineBasicBlock *MBB = MFI;
-    
-    for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
-         MBBI != EE; ++MBBI) {
-      // We may end up deleting the MachineInstr that MBBI points to, so
-      // remember its opcode now so we can refer to it after calling erase()
-      unsigned ByteSize = getNumBytesForInstruction(MBBI);
-      if (MBBI->getOpcode() != PPC::COND_BRANCH) {
-        ByteCount += ByteSize;
-        continue;
-      }
-      
-      // condbranch operands:
-      // 0. CR register
-      // 1. PPC branch opcode
-      // 2. Target MBB
-      MachineBasicBlock *DestMBB = MBBI->getOperand(2).getMachineBasicBlock();
-      PPC::Predicate Pred = (PPC::Predicate)MBBI->getOperand(1).getImm();
-      unsigned CRReg = MBBI->getOperand(0).getReg();
-      int Displacement = OffsetMap[DestMBB->getNumber()] - ByteCount;
-
-      bool ShortBranchOk = Displacement >= -32768 && Displacement <= 32767;
-      
-      // Branch on opposite condition if a short branch isn't ok.
-      if (!ShortBranchOk)
-        Pred = PPC::InvertPredicate(Pred);
+  bool MadeChange = true;
+  bool EverMadeChange = false;
+  while (MadeChange) {
+    // Iteratively expand branches until we reach a fixed point.
+    MadeChange = false;
+  
+    for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
+         ++MFI) {
+      MachineBasicBlock &MBB = *MFI;
+      unsigned MBBStartOffset = 0;
+      for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
+           I != E; ++I) {
+        MachineBasicBlock *Dest = nullptr;
+        if (I->getOpcode() == PPC::BCC && !I->getOperand(2).isImm())
+          Dest = I->getOperand(2).getMBB();
+        else if ((I->getOpcode() == PPC::BC || I->getOpcode() == PPC::BCn) &&
+                 !I->getOperand(1).isImm())
+          Dest = I->getOperand(1).getMBB();
+        else if ((I->getOpcode() == PPC::BDNZ8 || I->getOpcode() == PPC::BDNZ ||
+                  I->getOpcode() == PPC::BDZ8  || I->getOpcode() == PPC::BDZ) &&
+                 !I->getOperand(0).isImm())
+          Dest = I->getOperand(0).getMBB();
+
+        if (!Dest) {
+          MBBStartOffset += TII->GetInstSizeInBytes(I);
+          continue;
+        }
         
-      unsigned Opcode;
-      switch (Pred) {
-      default: assert(0 && "Unknown cond branch predicate!");
-      case PPC::PRED_LT: Opcode = PPC::BLT; break;
-      case PPC::PRED_LE: Opcode = PPC::BLE; break;
-      case PPC::PRED_EQ: Opcode = PPC::BEQ; break;
-      case PPC::PRED_GE: Opcode = PPC::BGE; break;
-      case PPC::PRED_GT: Opcode = PPC::BGT; break;
-      case PPC::PRED_NE: Opcode = PPC::BNE; break;
-      case PPC::PRED_UN: Opcode = PPC::BUN; break;
-      case PPC::PRED_NU: Opcode = PPC::BNU; break;
-      }
-      
-      MachineBasicBlock::iterator MBBJ;
-      if (ShortBranchOk) {
-        MBBJ = BuildMI(*MBB, MBBI, Opcode, 2).addReg(CRReg).addMBB(DestMBB);
-      } else {
-        // Long branch, skip next branch instruction (i.e. $PC+8).
+        // Determine the offset from the current branch to the destination
+        // block.
+        int BranchSize;
+        if (Dest->getNumber() <= MBB.getNumber()) {
+          // If this is a backwards branch, the delta is the offset from the
+          // start of this block to this branch, plus the sizes of all blocks
+          // from this block to the dest.
+          BranchSize = MBBStartOffset;
+          
+          for (unsigned i = Dest->getNumber(), e = MBB.getNumber(); i != e; ++i)
+            BranchSize += BlockSizes[i];
+        } else {
+          // Otherwise, add the size of the blocks between this block and the
+          // dest to the number of bytes left in this block.
+          BranchSize = -MBBStartOffset;
+
+          for (unsigned i = MBB.getNumber(), e = Dest->getNumber(); i != e; ++i)
+            BranchSize += BlockSizes[i];
+        }
+
+        // If this branch is in range, ignore it.
+        if (isInt<16>(BranchSize)) {
+          MBBStartOffset += 4;
+          continue;
+        }
+
+        // Otherwise, we have to expand it to a long branch.
+        MachineInstr *OldBranch = I;
+        DebugLoc dl = OldBranch->getDebugLoc();
+        if (I->getOpcode() == PPC::BCC) {
+          // The BCC operands are:
+          // 0. PPC branch predicate
+          // 1. CR register
+          // 2. Target MBB
+          PPC::Predicate Pred = (PPC::Predicate)I->getOperand(0).getImm();
+          unsigned CRReg = I->getOperand(1).getReg();
+       
+          // Jump over the uncond branch inst (i.e. $PC+8) on opposite condition.
+          BuildMI(MBB, I, dl, TII->get(PPC::BCC))
+            .addImm(PPC::InvertPredicate(Pred)).addReg(CRReg).addImm(2);
+        } else if (I->getOpcode() == PPC::BC) {
+          unsigned CRBit = I->getOperand(0).getReg();
+          BuildMI(MBB, I, dl, TII->get(PPC::BCn)).addReg(CRBit).addImm(2);
+        } else if (I->getOpcode() == PPC::BCn) {
+          unsigned CRBit = I->getOperand(0).getReg();
+          BuildMI(MBB, I, dl, TII->get(PPC::BC)).addReg(CRBit).addImm(2);
+        } else if (I->getOpcode() == PPC::BDNZ) {
+          BuildMI(MBB, I, dl, TII->get(PPC::BDZ)).addImm(2);
+        } else if (I->getOpcode() == PPC::BDNZ8) {
+          BuildMI(MBB, I, dl, TII->get(PPC::BDZ8)).addImm(2);
+        } else if (I->getOpcode() == PPC::BDZ) {
+          BuildMI(MBB, I, dl, TII->get(PPC::BDNZ)).addImm(2);
+        } else if (I->getOpcode() == PPC::BDZ8) {
+          BuildMI(MBB, I, dl, TII->get(PPC::BDNZ8)).addImm(2);
+        } else {
+           llvm_unreachable("Unhandled branch type!");
+        }
+        
+        // Uncond branch to the real destination.
+        I = BuildMI(MBB, I, dl, TII->get(PPC::B)).addMBB(Dest);
+
+        // Remove the old branch from the function.
+        OldBranch->eraseFromParent();
+        
+        // Remember that this instruction is 8-bytes, increase the size of the
+        // block by 4, remember to iterate.
+        BlockSizes[MBB.getNumber()] += 4;
+        MBBStartOffset += 8;
         ++NumExpanded;
-        BuildMI(*MBB, MBBI, Opcode, 2).addReg(CRReg).addImm(2);
-        MBBJ = BuildMI(*MBB, MBBI, PPC::B, 1).addMBB(DestMBB);
+        MadeChange = true;
       }
-      
-      // Erase the psuedo COND_BRANCH instruction, and then back up the
-      // iterator so that when the for loop increments it, we end up in
-      // the correct place rather than iterating off the end.
-      MBB->erase(MBBI);
-      MBBI = MBBJ;
-      ByteCount += ByteSize;
     }
+    EverMadeChange |= MadeChange;
   }
   
-  OffsetMap.clear();
+  BlockSizes.clear();
   return true;
 }