convert PPC::BCC to use the 'pred' operand instead of separate predicate
[oota-llvm.git] / lib / Target / PowerPC / PPCBranchSelector.cpp
index 657ff6ce633e0a09072a8bd4d01d490c5f8b0bd4..db85738ccc55fce11f8edf1f3d7f0a2504db6d4d 100644 (file)
 #include "PPC.h"
 #include "PPCInstrBuilder.h"
 #include "PPCInstrInfo.h"
+#include "PPCPredicates.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
-#include <map>
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Compiler.h"
 using namespace llvm;
 
+static Statistic<> NumExpanded("ppc-branch-select",
+                               "Num branches expanded to long format");
+
 namespace {
-  struct PPCBSel : public MachineFunctionPass {
-    // OffsetMap - Mapping between BB and byte offset from start of function
-    std::map<MachineBasicBlock*, unsigned> OffsetMap;
+  struct VISIBILITY_HIDDEN PPCBSel : public MachineFunctionPass {
+    /// OffsetMap - Mapping between BB # and byte offset from start of function.
+    std::vector<unsigned> OffsetMap;
 
     virtual bool runOnMachineFunction(MachineFunction &Fn);
 
@@ -47,26 +54,22 @@ FunctionPass *llvm::createPPCBranchSelectionPass() {
 ///
 static unsigned getNumBytesForInstruction(MachineInstr *MI) {
   switch (MI->getOpcode()) {
-  case PPC::COND_BRANCH:
+  case PPC::BCC:
     // 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_GPR: // no asm emitted
-  case PPC::IMPLICIT_DEF_F4: // no asm emitted
-  case PPC::IMPLICIT_DEF_F8: // no asm emitted
+  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.
-    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
-      if (MI->getOperand(i).isExternalSymbol()) {
-        const char *AsmStr = MI->getOperand(i).getSymbolName();
-        // Count the number of newline's in the asm string.
-        unsigned NumInstrs = 0;
-        for (; *AsmStr; ++AsmStr)
-          NumInstrs += *AsmStr == '\n';
-        return NumInstrs*4;
-      }
-    assert(0 && "INLINEASM didn't have format string??");
+  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
   }
@@ -77,12 +80,14 @@ 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
   for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
        ++MFI) {
     MachineBasicBlock *MBB = MFI;
-    OffsetMap[MBB] = ByteCount;
+    OffsetMap[MBB->getNumber()] = ByteCount;
     
     for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
          MBBI != EE; ++MBBI)
@@ -111,36 +116,54 @@ bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) {
       // 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) {
-        MachineBasicBlock::iterator MBBJ = MBBI;
-        ++MBBJ;
-        
-        // condbranch operands:
-        // 0. CR0 register
-        // 1. bc opcode
-        // 2. target MBB
-        // 3. fallthrough MBB
-        MachineBasicBlock *trueMBB =
-          MBBI->getOperand(2).getMachineBasicBlock();
-        
-        int Displacement = OffsetMap[trueMBB] - ByteCount;
-        unsigned Opcode = MBBI->getOperand(1).getImmedValue();
-        unsigned CRReg = MBBI->getOperand(0).getReg();
-        unsigned Inverted = PPCInstrInfo::invertPPCBranchOpcode(Opcode);
-        
-        if (Displacement >= -32768 && Displacement <= 32767) {
-          BuildMI(*MBB, MBBJ, Opcode, 2).addReg(CRReg).addMBB(trueMBB);
-        } else {
-          BuildMI(*MBB, MBBJ, Inverted, 2).addReg(CRReg).addImm(8);
-          BuildMI(*MBB, MBBJ, PPC::B, 1).addMBB(trueMBB);
-        }
+      if (MBBI->getOpcode() != PPC::BCC) {
+        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(0).getImm();
+      unsigned CRReg = MBBI->getOperand(1).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);
         
-        // 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;
+      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).
+        ++NumExpanded;
+        BuildMI(*MBB, MBBI, Opcode, 2).addReg(CRReg).addImm(2);
+        MBBJ = BuildMI(*MBB, MBBI, PPC::B, 1).addMBB(DestMBB);
       }
+      
+      // Erase the psuedo BCC 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;
     }
   }