Encode pc-relative conditional branch offset as pc+(num of bytes / 4). The
[oota-llvm.git] / lib / Target / PowerPC / PPCBranchSelector.cpp
1 //===-- PPCBranchSelector.cpp - Emit long conditional branches-----*- C++ -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Nate Baegeman and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a pass that scans a machine function to determine which
11 // conditional branches need more than 16 bits of displacement to reach their
12 // target basic block.  It does this in two passes; a calculation of basic block
13 // positions pass, and a branch psuedo op to machine branch opcode pass.  This
14 // pass should be run last, just before the assembly printer.
15 //
16 //===----------------------------------------------------------------------===//
17
18 #include "PPC.h"
19 #include "PPCInstrBuilder.h"
20 #include "PPCInstrInfo.h"
21 #include "llvm/CodeGen/MachineFunctionPass.h"
22 #include "llvm/Support/Visibility.h"
23 #include <map>
24 using namespace llvm;
25
26 namespace {
27   struct VISIBILITY_HIDDEN PPCBSel : public MachineFunctionPass {
28     // OffsetMap - Mapping between BB and byte offset from start of function
29     std::map<MachineBasicBlock*, unsigned> OffsetMap;
30
31     virtual bool runOnMachineFunction(MachineFunction &Fn);
32
33     virtual const char *getPassName() const {
34       return "PowerPC Branch Selection";
35     }
36   };
37 }
38
39 /// createPPCBranchSelectionPass - returns an instance of the Branch Selection
40 /// Pass
41 ///
42 FunctionPass *llvm::createPPCBranchSelectionPass() {
43   return new PPCBSel();
44 }
45
46 /// getNumBytesForInstruction - Return the number of bytes of code the specified
47 /// instruction may be.  This returns the maximum number of bytes.
48 ///
49 static unsigned getNumBytesForInstruction(MachineInstr *MI) {
50   switch (MI->getOpcode()) {
51   case PPC::COND_BRANCH:
52     // while this will be 4 most of the time, if we emit 8 it is just a
53     // minor pessimization that saves us from having to worry about
54     // keeping the offsets up to date later when we emit long branch glue.
55     return 8;
56   case PPC::IMPLICIT_DEF_GPRC: // no asm emitted
57   case PPC::IMPLICIT_DEF_G8RC: // no asm emitted
58   case PPC::IMPLICIT_DEF_F4: // no asm emitted
59   case PPC::IMPLICIT_DEF_F8: // no asm emitted
60     return 0;
61   case PPC::INLINEASM:    // Inline Asm: Variable size.
62     for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
63       if (MI->getOperand(i).isExternalSymbol()) {
64         const char *AsmStr = MI->getOperand(i).getSymbolName();
65         // Count the number of newline's in the asm string.
66         unsigned NumInstrs = 0;
67         for (; *AsmStr; ++AsmStr)
68           NumInstrs += *AsmStr == '\n';
69         return NumInstrs*4;
70       }
71     assert(0 && "INLINEASM didn't have format string??");
72   default:
73     return 4; // PowerPC instructions are all 4 bytes
74   }
75 }
76
77
78 bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) {
79   // Running total of instructions encountered since beginning of function
80   unsigned ByteCount = 0;
81   
82   // For each MBB, add its offset to the offset map, and count up its
83   // instructions
84   for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
85        ++MFI) {
86     MachineBasicBlock *MBB = MFI;
87     OffsetMap[MBB] = ByteCount;
88     
89     for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
90          MBBI != EE; ++MBBI)
91       ByteCount += getNumBytesForInstruction(MBBI);
92   }
93   
94   // We're about to run over the MBB's again, so reset the ByteCount
95   ByteCount = 0;
96   
97   // For each MBB, find the conditional branch pseudo instructions, and
98   // calculate the difference between the target MBB and the current ICount
99   // to decide whether or not to emit a short or long branch.
100   //
101   // short branch:
102   // bCC .L_TARGET_MBB
103   //
104   // long branch:
105   // bInverseCC $PC+8
106   // b .L_TARGET_MBB
107   for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
108        ++MFI) {
109     MachineBasicBlock *MBB = MFI;
110     
111     for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
112          MBBI != EE; ++MBBI) {
113       // We may end up deleting the MachineInstr that MBBI points to, so
114       // remember its opcode now so we can refer to it after calling erase()
115       unsigned ByteSize = getNumBytesForInstruction(MBBI);
116       if (MBBI->getOpcode() == PPC::COND_BRANCH) {
117         MachineBasicBlock::iterator MBBJ = MBBI;
118         ++MBBJ;
119         
120         // condbranch operands:
121         // 0. CR0 register
122         // 1. bc opcode
123         // 2. target MBB
124         // 3. fallthrough MBB
125         MachineBasicBlock *trueMBB =
126           MBBI->getOperand(2).getMachineBasicBlock();
127         
128         int Displacement = OffsetMap[trueMBB] - ByteCount;
129         unsigned Opcode = MBBI->getOperand(1).getImmedValue();
130         unsigned CRReg = MBBI->getOperand(0).getReg();
131         unsigned Inverted = PPCInstrInfo::invertPPCBranchOpcode(Opcode);
132         
133         if (Displacement >= -32768 && Displacement <= 32767) {
134           BuildMI(*MBB, MBBJ, Opcode, 2).addReg(CRReg).addMBB(trueMBB);
135         } else {
136           BuildMI(*MBB, MBBJ, Inverted, 2).addReg(CRReg).addImm(2);
137           BuildMI(*MBB, MBBJ, PPC::B, 1).addMBB(trueMBB);
138         }
139         
140         // Erase the psuedo COND_BRANCH instruction, and then back up the
141         // iterator so that when the for loop increments it, we end up in
142         // the correct place rather than iterating off the end.
143         MBB->erase(MBBI);
144         MBBI = --MBBJ;
145       }
146       ByteCount += ByteSize;
147     }
148   }
149   
150   OffsetMap.clear();
151   return true;
152 }
153