xref: /aosp_15_r20/external/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- MipsConstantIslandPass.cpp - Emit Pc Relative loads----------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker //
11*9880d681SAndroid Build Coastguard Worker // This pass is used to make Pc relative loads of constants.
12*9880d681SAndroid Build Coastguard Worker // For now, only Mips16 will use this.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker // Loading constants inline is expensive on Mips16 and it's in general better
15*9880d681SAndroid Build Coastguard Worker // to place the constant nearby in code space and then it can be loaded with a
16*9880d681SAndroid Build Coastguard Worker // simple 16 bit load instruction.
17*9880d681SAndroid Build Coastguard Worker //
18*9880d681SAndroid Build Coastguard Worker // The constants can be not just numbers but addresses of functions and labels.
19*9880d681SAndroid Build Coastguard Worker // This can be particularly helpful in static relocation mode for embedded
20*9880d681SAndroid Build Coastguard Worker // non-linux targets.
21*9880d681SAndroid Build Coastguard Worker //
22*9880d681SAndroid Build Coastguard Worker //
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker #include "Mips.h"
25*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/MipsBaseInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "Mips16InstrInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "MipsMachineFunction.h"
28*9880d681SAndroid Build Coastguard Worker #include "MipsTargetMachine.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBasicBlock.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineConstantPool.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/InstIterator.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
45*9880d681SAndroid Build Coastguard Worker #include <algorithm>
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker using namespace llvm;
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "mips-constant-islands"
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker STATISTIC(NumCPEs,       "Number of constpool entries");
52*9880d681SAndroid Build Coastguard Worker STATISTIC(NumSplit,      "Number of uncond branches inserted");
53*9880d681SAndroid Build Coastguard Worker STATISTIC(NumCBrFixed,   "Number of cond branches fixed");
54*9880d681SAndroid Build Coastguard Worker STATISTIC(NumUBrFixed,   "Number of uncond branches fixed");
55*9880d681SAndroid Build Coastguard Worker 
56*9880d681SAndroid Build Coastguard Worker // FIXME: This option should be removed once it has received sufficient testing.
57*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
58*9880d681SAndroid Build Coastguard Worker AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true),
59*9880d681SAndroid Build Coastguard Worker           cl::desc("Align constant islands in code"));
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker 
62*9880d681SAndroid Build Coastguard Worker // Rather than do make check tests with huge amounts of code, we force
63*9880d681SAndroid Build Coastguard Worker // the test to use this amount.
64*9880d681SAndroid Build Coastguard Worker //
65*9880d681SAndroid Build Coastguard Worker static cl::opt<int> ConstantIslandsSmallOffset(
66*9880d681SAndroid Build Coastguard Worker   "mips-constant-islands-small-offset",
67*9880d681SAndroid Build Coastguard Worker   cl::init(0),
68*9880d681SAndroid Build Coastguard Worker   cl::desc("Make small offsets be this amount for testing purposes"),
69*9880d681SAndroid Build Coastguard Worker   cl::Hidden);
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker //
72*9880d681SAndroid Build Coastguard Worker // For testing purposes we tell it to not use relaxed load forms so that it
73*9880d681SAndroid Build Coastguard Worker // will split blocks.
74*9880d681SAndroid Build Coastguard Worker //
75*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> NoLoadRelaxation(
76*9880d681SAndroid Build Coastguard Worker   "mips-constant-islands-no-load-relaxation",
77*9880d681SAndroid Build Coastguard Worker   cl::init(false),
78*9880d681SAndroid Build Coastguard Worker   cl::desc("Don't relax loads to long loads - for testing purposes"),
79*9880d681SAndroid Build Coastguard Worker   cl::Hidden);
80*9880d681SAndroid Build Coastguard Worker 
branchTargetOperand(MachineInstr * MI)81*9880d681SAndroid Build Coastguard Worker static unsigned int branchTargetOperand(MachineInstr *MI) {
82*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
83*9880d681SAndroid Build Coastguard Worker   case Mips::Bimm16:
84*9880d681SAndroid Build Coastguard Worker   case Mips::BimmX16:
85*9880d681SAndroid Build Coastguard Worker   case Mips::Bteqz16:
86*9880d681SAndroid Build Coastguard Worker   case Mips::BteqzX16:
87*9880d681SAndroid Build Coastguard Worker   case Mips::Btnez16:
88*9880d681SAndroid Build Coastguard Worker   case Mips::BtnezX16:
89*9880d681SAndroid Build Coastguard Worker   case Mips::JalB16:
90*9880d681SAndroid Build Coastguard Worker     return 0;
91*9880d681SAndroid Build Coastguard Worker   case Mips::BeqzRxImm16:
92*9880d681SAndroid Build Coastguard Worker   case Mips::BeqzRxImmX16:
93*9880d681SAndroid Build Coastguard Worker   case Mips::BnezRxImm16:
94*9880d681SAndroid Build Coastguard Worker   case Mips::BnezRxImmX16:
95*9880d681SAndroid Build Coastguard Worker     return 1;
96*9880d681SAndroid Build Coastguard Worker   }
97*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unknown branch type");
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker 
longformBranchOpcode(unsigned int Opcode)100*9880d681SAndroid Build Coastguard Worker static unsigned int longformBranchOpcode(unsigned int Opcode) {
101*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
102*9880d681SAndroid Build Coastguard Worker   case Mips::Bimm16:
103*9880d681SAndroid Build Coastguard Worker   case Mips::BimmX16:
104*9880d681SAndroid Build Coastguard Worker     return Mips::BimmX16;
105*9880d681SAndroid Build Coastguard Worker   case Mips::Bteqz16:
106*9880d681SAndroid Build Coastguard Worker   case Mips::BteqzX16:
107*9880d681SAndroid Build Coastguard Worker     return Mips::BteqzX16;
108*9880d681SAndroid Build Coastguard Worker   case Mips::Btnez16:
109*9880d681SAndroid Build Coastguard Worker   case Mips::BtnezX16:
110*9880d681SAndroid Build Coastguard Worker     return Mips::BtnezX16;
111*9880d681SAndroid Build Coastguard Worker   case Mips::JalB16:
112*9880d681SAndroid Build Coastguard Worker     return Mips::JalB16;
113*9880d681SAndroid Build Coastguard Worker   case Mips::BeqzRxImm16:
114*9880d681SAndroid Build Coastguard Worker   case Mips::BeqzRxImmX16:
115*9880d681SAndroid Build Coastguard Worker     return Mips::BeqzRxImmX16;
116*9880d681SAndroid Build Coastguard Worker   case Mips::BnezRxImm16:
117*9880d681SAndroid Build Coastguard Worker   case Mips::BnezRxImmX16:
118*9880d681SAndroid Build Coastguard Worker     return Mips::BnezRxImmX16;
119*9880d681SAndroid Build Coastguard Worker   }
120*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unknown branch type");
121*9880d681SAndroid Build Coastguard Worker }
122*9880d681SAndroid Build Coastguard Worker 
123*9880d681SAndroid Build Coastguard Worker //
124*9880d681SAndroid Build Coastguard Worker // FIXME: need to go through this whole constant islands port and check the math
125*9880d681SAndroid Build Coastguard Worker // for branch ranges and clean this up and make some functions to calculate things
126*9880d681SAndroid Build Coastguard Worker // that are done many times identically.
127*9880d681SAndroid Build Coastguard Worker // Need to refactor some of the code to call this routine.
128*9880d681SAndroid Build Coastguard Worker //
branchMaxOffsets(unsigned int Opcode)129*9880d681SAndroid Build Coastguard Worker static unsigned int branchMaxOffsets(unsigned int Opcode) {
130*9880d681SAndroid Build Coastguard Worker   unsigned Bits, Scale;
131*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
132*9880d681SAndroid Build Coastguard Worker     case Mips::Bimm16:
133*9880d681SAndroid Build Coastguard Worker       Bits = 11;
134*9880d681SAndroid Build Coastguard Worker       Scale = 2;
135*9880d681SAndroid Build Coastguard Worker       break;
136*9880d681SAndroid Build Coastguard Worker     case Mips::BimmX16:
137*9880d681SAndroid Build Coastguard Worker       Bits = 16;
138*9880d681SAndroid Build Coastguard Worker       Scale = 2;
139*9880d681SAndroid Build Coastguard Worker       break;
140*9880d681SAndroid Build Coastguard Worker     case Mips::BeqzRxImm16:
141*9880d681SAndroid Build Coastguard Worker       Bits = 8;
142*9880d681SAndroid Build Coastguard Worker       Scale = 2;
143*9880d681SAndroid Build Coastguard Worker       break;
144*9880d681SAndroid Build Coastguard Worker     case Mips::BeqzRxImmX16:
145*9880d681SAndroid Build Coastguard Worker       Bits = 16;
146*9880d681SAndroid Build Coastguard Worker       Scale = 2;
147*9880d681SAndroid Build Coastguard Worker       break;
148*9880d681SAndroid Build Coastguard Worker     case Mips::BnezRxImm16:
149*9880d681SAndroid Build Coastguard Worker       Bits = 8;
150*9880d681SAndroid Build Coastguard Worker       Scale = 2;
151*9880d681SAndroid Build Coastguard Worker       break;
152*9880d681SAndroid Build Coastguard Worker     case Mips::BnezRxImmX16:
153*9880d681SAndroid Build Coastguard Worker       Bits = 16;
154*9880d681SAndroid Build Coastguard Worker       Scale = 2;
155*9880d681SAndroid Build Coastguard Worker       break;
156*9880d681SAndroid Build Coastguard Worker     case Mips::Bteqz16:
157*9880d681SAndroid Build Coastguard Worker       Bits = 8;
158*9880d681SAndroid Build Coastguard Worker       Scale = 2;
159*9880d681SAndroid Build Coastguard Worker       break;
160*9880d681SAndroid Build Coastguard Worker     case Mips::BteqzX16:
161*9880d681SAndroid Build Coastguard Worker       Bits = 16;
162*9880d681SAndroid Build Coastguard Worker       Scale = 2;
163*9880d681SAndroid Build Coastguard Worker       break;
164*9880d681SAndroid Build Coastguard Worker     case Mips::Btnez16:
165*9880d681SAndroid Build Coastguard Worker       Bits = 8;
166*9880d681SAndroid Build Coastguard Worker       Scale = 2;
167*9880d681SAndroid Build Coastguard Worker       break;
168*9880d681SAndroid Build Coastguard Worker     case Mips::BtnezX16:
169*9880d681SAndroid Build Coastguard Worker       Bits = 16;
170*9880d681SAndroid Build Coastguard Worker       Scale = 2;
171*9880d681SAndroid Build Coastguard Worker       break;
172*9880d681SAndroid Build Coastguard Worker     default:
173*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Unknown branch type");
174*9880d681SAndroid Build Coastguard Worker   }
175*9880d681SAndroid Build Coastguard Worker   unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
176*9880d681SAndroid Build Coastguard Worker   return MaxOffs;
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker namespace {
180*9880d681SAndroid Build Coastguard Worker 
181*9880d681SAndroid Build Coastguard Worker 
182*9880d681SAndroid Build Coastguard Worker   typedef MachineBasicBlock::iterator Iter;
183*9880d681SAndroid Build Coastguard Worker   typedef MachineBasicBlock::reverse_iterator ReverseIter;
184*9880d681SAndroid Build Coastguard Worker 
185*9880d681SAndroid Build Coastguard Worker   /// MipsConstantIslands - Due to limited PC-relative displacements, Mips
186*9880d681SAndroid Build Coastguard Worker   /// requires constant pool entries to be scattered among the instructions
187*9880d681SAndroid Build Coastguard Worker   /// inside a function.  To do this, it completely ignores the normal LLVM
188*9880d681SAndroid Build Coastguard Worker   /// constant pool; instead, it places constants wherever it feels like with
189*9880d681SAndroid Build Coastguard Worker   /// special instructions.
190*9880d681SAndroid Build Coastguard Worker   ///
191*9880d681SAndroid Build Coastguard Worker   /// The terminology used in this pass includes:
192*9880d681SAndroid Build Coastguard Worker   ///   Islands - Clumps of constants placed in the function.
193*9880d681SAndroid Build Coastguard Worker   ///   Water   - Potential places where an island could be formed.
194*9880d681SAndroid Build Coastguard Worker   ///   CPE     - A constant pool entry that has been placed somewhere, which
195*9880d681SAndroid Build Coastguard Worker   ///             tracks a list of users.
196*9880d681SAndroid Build Coastguard Worker 
197*9880d681SAndroid Build Coastguard Worker   class MipsConstantIslands : public MachineFunctionPass {
198*9880d681SAndroid Build Coastguard Worker 
199*9880d681SAndroid Build Coastguard Worker     /// BasicBlockInfo - Information about the offset and size of a single
200*9880d681SAndroid Build Coastguard Worker     /// basic block.
201*9880d681SAndroid Build Coastguard Worker     struct BasicBlockInfo {
202*9880d681SAndroid Build Coastguard Worker       /// Offset - Distance from the beginning of the function to the beginning
203*9880d681SAndroid Build Coastguard Worker       /// of this basic block.
204*9880d681SAndroid Build Coastguard Worker       ///
205*9880d681SAndroid Build Coastguard Worker       /// Offsets are computed assuming worst case padding before an aligned
206*9880d681SAndroid Build Coastguard Worker       /// block. This means that subtracting basic block offsets always gives a
207*9880d681SAndroid Build Coastguard Worker       /// conservative estimate of the real distance which may be smaller.
208*9880d681SAndroid Build Coastguard Worker       ///
209*9880d681SAndroid Build Coastguard Worker       /// Because worst case padding is used, the computed offset of an aligned
210*9880d681SAndroid Build Coastguard Worker       /// block may not actually be aligned.
211*9880d681SAndroid Build Coastguard Worker       unsigned Offset;
212*9880d681SAndroid Build Coastguard Worker 
213*9880d681SAndroid Build Coastguard Worker       /// Size - Size of the basic block in bytes.  If the block contains
214*9880d681SAndroid Build Coastguard Worker       /// inline assembly, this is a worst case estimate.
215*9880d681SAndroid Build Coastguard Worker       ///
216*9880d681SAndroid Build Coastguard Worker       /// The size does not include any alignment padding whether from the
217*9880d681SAndroid Build Coastguard Worker       /// beginning of the block, or from an aligned jump table at the end.
218*9880d681SAndroid Build Coastguard Worker       unsigned Size;
219*9880d681SAndroid Build Coastguard Worker 
220*9880d681SAndroid Build Coastguard Worker       // FIXME: ignore LogAlign for this patch
221*9880d681SAndroid Build Coastguard Worker       //
postOffset__anonbac959bb0111::MipsConstantIslands::BasicBlockInfo222*9880d681SAndroid Build Coastguard Worker       unsigned postOffset(unsigned LogAlign = 0) const {
223*9880d681SAndroid Build Coastguard Worker         unsigned PO = Offset + Size;
224*9880d681SAndroid Build Coastguard Worker         return PO;
225*9880d681SAndroid Build Coastguard Worker       }
226*9880d681SAndroid Build Coastguard Worker 
BasicBlockInfo__anonbac959bb0111::MipsConstantIslands::BasicBlockInfo227*9880d681SAndroid Build Coastguard Worker       BasicBlockInfo() : Offset(0), Size(0) {}
228*9880d681SAndroid Build Coastguard Worker 
229*9880d681SAndroid Build Coastguard Worker     };
230*9880d681SAndroid Build Coastguard Worker 
231*9880d681SAndroid Build Coastguard Worker     std::vector<BasicBlockInfo> BBInfo;
232*9880d681SAndroid Build Coastguard Worker 
233*9880d681SAndroid Build Coastguard Worker     /// WaterList - A sorted list of basic blocks where islands could be placed
234*9880d681SAndroid Build Coastguard Worker     /// (i.e. blocks that don't fall through to the following block, due
235*9880d681SAndroid Build Coastguard Worker     /// to a return, unreachable, or unconditional branch).
236*9880d681SAndroid Build Coastguard Worker     std::vector<MachineBasicBlock*> WaterList;
237*9880d681SAndroid Build Coastguard Worker 
238*9880d681SAndroid Build Coastguard Worker     /// NewWaterList - The subset of WaterList that was created since the
239*9880d681SAndroid Build Coastguard Worker     /// previous iteration by inserting unconditional branches.
240*9880d681SAndroid Build Coastguard Worker     SmallSet<MachineBasicBlock*, 4> NewWaterList;
241*9880d681SAndroid Build Coastguard Worker 
242*9880d681SAndroid Build Coastguard Worker     typedef std::vector<MachineBasicBlock*>::iterator water_iterator;
243*9880d681SAndroid Build Coastguard Worker 
244*9880d681SAndroid Build Coastguard Worker     /// CPUser - One user of a constant pool, keeping the machine instruction
245*9880d681SAndroid Build Coastguard Worker     /// pointer, the constant pool being referenced, and the max displacement
246*9880d681SAndroid Build Coastguard Worker     /// allowed from the instruction to the CP.  The HighWaterMark records the
247*9880d681SAndroid Build Coastguard Worker     /// highest basic block where a new CPEntry can be placed.  To ensure this
248*9880d681SAndroid Build Coastguard Worker     /// pass terminates, the CP entries are initially placed at the end of the
249*9880d681SAndroid Build Coastguard Worker     /// function and then move monotonically to lower addresses.  The
250*9880d681SAndroid Build Coastguard Worker     /// exception to this rule is when the current CP entry for a particular
251*9880d681SAndroid Build Coastguard Worker     /// CPUser is out of range, but there is another CP entry for the same
252*9880d681SAndroid Build Coastguard Worker     /// constant value in range.  We want to use the existing in-range CP
253*9880d681SAndroid Build Coastguard Worker     /// entry, but if it later moves out of range, the search for new water
254*9880d681SAndroid Build Coastguard Worker     /// should resume where it left off.  The HighWaterMark is used to record
255*9880d681SAndroid Build Coastguard Worker     /// that point.
256*9880d681SAndroid Build Coastguard Worker     struct CPUser {
257*9880d681SAndroid Build Coastguard Worker       MachineInstr *MI;
258*9880d681SAndroid Build Coastguard Worker       MachineInstr *CPEMI;
259*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock *HighWaterMark;
260*9880d681SAndroid Build Coastguard Worker     private:
261*9880d681SAndroid Build Coastguard Worker       unsigned MaxDisp;
262*9880d681SAndroid Build Coastguard Worker       unsigned LongFormMaxDisp; // mips16 has 16/32 bit instructions
263*9880d681SAndroid Build Coastguard Worker                                 // with different displacements
264*9880d681SAndroid Build Coastguard Worker       unsigned LongFormOpcode;
265*9880d681SAndroid Build Coastguard Worker     public:
266*9880d681SAndroid Build Coastguard Worker       bool NegOk;
CPUser__anonbac959bb0111::MipsConstantIslands::CPUser267*9880d681SAndroid Build Coastguard Worker       CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp,
268*9880d681SAndroid Build Coastguard Worker              bool neg,
269*9880d681SAndroid Build Coastguard Worker              unsigned longformmaxdisp, unsigned longformopcode)
270*9880d681SAndroid Build Coastguard Worker         : MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),
271*9880d681SAndroid Build Coastguard Worker           LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),
272*9880d681SAndroid Build Coastguard Worker           NegOk(neg){
273*9880d681SAndroid Build Coastguard Worker         HighWaterMark = CPEMI->getParent();
274*9880d681SAndroid Build Coastguard Worker       }
275*9880d681SAndroid Build Coastguard Worker       /// getMaxDisp - Returns the maximum displacement supported by MI.
getMaxDisp__anonbac959bb0111::MipsConstantIslands::CPUser276*9880d681SAndroid Build Coastguard Worker       unsigned getMaxDisp() const {
277*9880d681SAndroid Build Coastguard Worker         unsigned xMaxDisp = ConstantIslandsSmallOffset?
278*9880d681SAndroid Build Coastguard Worker                             ConstantIslandsSmallOffset: MaxDisp;
279*9880d681SAndroid Build Coastguard Worker         return xMaxDisp;
280*9880d681SAndroid Build Coastguard Worker       }
setMaxDisp__anonbac959bb0111::MipsConstantIslands::CPUser281*9880d681SAndroid Build Coastguard Worker       void setMaxDisp(unsigned val) {
282*9880d681SAndroid Build Coastguard Worker         MaxDisp = val;
283*9880d681SAndroid Build Coastguard Worker       }
getLongFormMaxDisp__anonbac959bb0111::MipsConstantIslands::CPUser284*9880d681SAndroid Build Coastguard Worker       unsigned getLongFormMaxDisp() const {
285*9880d681SAndroid Build Coastguard Worker         return LongFormMaxDisp;
286*9880d681SAndroid Build Coastguard Worker       }
getLongFormOpcode__anonbac959bb0111::MipsConstantIslands::CPUser287*9880d681SAndroid Build Coastguard Worker       unsigned getLongFormOpcode() const {
288*9880d681SAndroid Build Coastguard Worker           return LongFormOpcode;
289*9880d681SAndroid Build Coastguard Worker       }
290*9880d681SAndroid Build Coastguard Worker     };
291*9880d681SAndroid Build Coastguard Worker 
292*9880d681SAndroid Build Coastguard Worker     /// CPUsers - Keep track of all of the machine instructions that use various
293*9880d681SAndroid Build Coastguard Worker     /// constant pools and their max displacement.
294*9880d681SAndroid Build Coastguard Worker     std::vector<CPUser> CPUsers;
295*9880d681SAndroid Build Coastguard Worker 
296*9880d681SAndroid Build Coastguard Worker   /// CPEntry - One per constant pool entry, keeping the machine instruction
297*9880d681SAndroid Build Coastguard Worker   /// pointer, the constpool index, and the number of CPUser's which
298*9880d681SAndroid Build Coastguard Worker   /// reference this entry.
299*9880d681SAndroid Build Coastguard Worker   struct CPEntry {
300*9880d681SAndroid Build Coastguard Worker     MachineInstr *CPEMI;
301*9880d681SAndroid Build Coastguard Worker     unsigned CPI;
302*9880d681SAndroid Build Coastguard Worker     unsigned RefCount;
CPEntry__anonbac959bb0111::MipsConstantIslands::CPEntry303*9880d681SAndroid Build Coastguard Worker     CPEntry(MachineInstr *cpemi, unsigned cpi, unsigned rc = 0)
304*9880d681SAndroid Build Coastguard Worker       : CPEMI(cpemi), CPI(cpi), RefCount(rc) {}
305*9880d681SAndroid Build Coastguard Worker   };
306*9880d681SAndroid Build Coastguard Worker 
307*9880d681SAndroid Build Coastguard Worker   /// CPEntries - Keep track of all of the constant pool entry machine
308*9880d681SAndroid Build Coastguard Worker   /// instructions. For each original constpool index (i.e. those that
309*9880d681SAndroid Build Coastguard Worker   /// existed upon entry to this pass), it keeps a vector of entries.
310*9880d681SAndroid Build Coastguard Worker   /// Original elements are cloned as we go along; the clones are
311*9880d681SAndroid Build Coastguard Worker   /// put in the vector of the original element, but have distinct CPIs.
312*9880d681SAndroid Build Coastguard Worker   std::vector<std::vector<CPEntry> > CPEntries;
313*9880d681SAndroid Build Coastguard Worker 
314*9880d681SAndroid Build Coastguard Worker   /// ImmBranch - One per immediate branch, keeping the machine instruction
315*9880d681SAndroid Build Coastguard Worker   /// pointer, conditional or unconditional, the max displacement,
316*9880d681SAndroid Build Coastguard Worker   /// and (if isCond is true) the corresponding unconditional branch
317*9880d681SAndroid Build Coastguard Worker   /// opcode.
318*9880d681SAndroid Build Coastguard Worker   struct ImmBranch {
319*9880d681SAndroid Build Coastguard Worker     MachineInstr *MI;
320*9880d681SAndroid Build Coastguard Worker     unsigned MaxDisp : 31;
321*9880d681SAndroid Build Coastguard Worker     bool isCond : 1;
322*9880d681SAndroid Build Coastguard Worker     int UncondBr;
ImmBranch__anonbac959bb0111::MipsConstantIslands::ImmBranch323*9880d681SAndroid Build Coastguard Worker     ImmBranch(MachineInstr *mi, unsigned maxdisp, bool cond, int ubr)
324*9880d681SAndroid Build Coastguard Worker       : MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}
325*9880d681SAndroid Build Coastguard Worker   };
326*9880d681SAndroid Build Coastguard Worker 
327*9880d681SAndroid Build Coastguard Worker   /// ImmBranches - Keep track of all the immediate branch instructions.
328*9880d681SAndroid Build Coastguard Worker   ///
329*9880d681SAndroid Build Coastguard Worker   std::vector<ImmBranch> ImmBranches;
330*9880d681SAndroid Build Coastguard Worker 
331*9880d681SAndroid Build Coastguard Worker   /// HasFarJump - True if any far jump instruction has been emitted during
332*9880d681SAndroid Build Coastguard Worker   /// the branch fix up pass.
333*9880d681SAndroid Build Coastguard Worker   bool HasFarJump;
334*9880d681SAndroid Build Coastguard Worker 
335*9880d681SAndroid Build Coastguard Worker   const MipsSubtarget *STI;
336*9880d681SAndroid Build Coastguard Worker   const Mips16InstrInfo *TII;
337*9880d681SAndroid Build Coastguard Worker   MipsFunctionInfo *MFI;
338*9880d681SAndroid Build Coastguard Worker   MachineFunction *MF;
339*9880d681SAndroid Build Coastguard Worker   MachineConstantPool *MCP;
340*9880d681SAndroid Build Coastguard Worker 
341*9880d681SAndroid Build Coastguard Worker   unsigned PICLabelUId;
342*9880d681SAndroid Build Coastguard Worker   bool PrescannedForConstants;
343*9880d681SAndroid Build Coastguard Worker 
initPICLabelUId(unsigned UId)344*9880d681SAndroid Build Coastguard Worker   void initPICLabelUId(unsigned UId) {
345*9880d681SAndroid Build Coastguard Worker     PICLabelUId = UId;
346*9880d681SAndroid Build Coastguard Worker   }
347*9880d681SAndroid Build Coastguard Worker 
348*9880d681SAndroid Build Coastguard Worker 
createPICLabelUId()349*9880d681SAndroid Build Coastguard Worker   unsigned createPICLabelUId() {
350*9880d681SAndroid Build Coastguard Worker     return PICLabelUId++;
351*9880d681SAndroid Build Coastguard Worker   }
352*9880d681SAndroid Build Coastguard Worker 
353*9880d681SAndroid Build Coastguard Worker   public:
354*9880d681SAndroid Build Coastguard Worker     static char ID;
MipsConstantIslands()355*9880d681SAndroid Build Coastguard Worker     MipsConstantIslands()
356*9880d681SAndroid Build Coastguard Worker         : MachineFunctionPass(ID), STI(nullptr), MF(nullptr), MCP(nullptr),
357*9880d681SAndroid Build Coastguard Worker           PrescannedForConstants(false) {}
358*9880d681SAndroid Build Coastguard Worker 
getPassName() const359*9880d681SAndroid Build Coastguard Worker     const char *getPassName() const override {
360*9880d681SAndroid Build Coastguard Worker       return "Mips Constant Islands";
361*9880d681SAndroid Build Coastguard Worker     }
362*9880d681SAndroid Build Coastguard Worker 
363*9880d681SAndroid Build Coastguard Worker     bool runOnMachineFunction(MachineFunction &F) override;
364*9880d681SAndroid Build Coastguard Worker 
getRequiredProperties() const365*9880d681SAndroid Build Coastguard Worker     MachineFunctionProperties getRequiredProperties() const override {
366*9880d681SAndroid Build Coastguard Worker       return MachineFunctionProperties().set(
367*9880d681SAndroid Build Coastguard Worker           MachineFunctionProperties::Property::AllVRegsAllocated);
368*9880d681SAndroid Build Coastguard Worker     }
369*9880d681SAndroid Build Coastguard Worker 
370*9880d681SAndroid Build Coastguard Worker     void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
371*9880d681SAndroid Build Coastguard Worker     CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI);
372*9880d681SAndroid Build Coastguard Worker     unsigned getCPELogAlign(const MachineInstr &CPEMI);
373*9880d681SAndroid Build Coastguard Worker     void initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs);
374*9880d681SAndroid Build Coastguard Worker     unsigned getOffsetOf(MachineInstr *MI) const;
375*9880d681SAndroid Build Coastguard Worker     unsigned getUserOffset(CPUser&) const;
376*9880d681SAndroid Build Coastguard Worker     void dumpBBs();
377*9880d681SAndroid Build Coastguard Worker 
378*9880d681SAndroid Build Coastguard Worker     bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,
379*9880d681SAndroid Build Coastguard Worker                          unsigned Disp, bool NegativeOK);
380*9880d681SAndroid Build Coastguard Worker     bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,
381*9880d681SAndroid Build Coastguard Worker                          const CPUser &U);
382*9880d681SAndroid Build Coastguard Worker 
383*9880d681SAndroid Build Coastguard Worker     void computeBlockSize(MachineBasicBlock *MBB);
384*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *splitBlockBeforeInstr(MachineInstr &MI);
385*9880d681SAndroid Build Coastguard Worker     void updateForInsertedWaterBlock(MachineBasicBlock *NewBB);
386*9880d681SAndroid Build Coastguard Worker     void adjustBBOffsetsAfter(MachineBasicBlock *BB);
387*9880d681SAndroid Build Coastguard Worker     bool decrementCPEReferenceCount(unsigned CPI, MachineInstr* CPEMI);
388*9880d681SAndroid Build Coastguard Worker     int findInRangeCPEntry(CPUser& U, unsigned UserOffset);
389*9880d681SAndroid Build Coastguard Worker     int findLongFormInRangeCPEntry(CPUser& U, unsigned UserOffset);
390*9880d681SAndroid Build Coastguard Worker     bool findAvailableWater(CPUser&U, unsigned UserOffset,
391*9880d681SAndroid Build Coastguard Worker                             water_iterator &WaterIter);
392*9880d681SAndroid Build Coastguard Worker     void createNewWater(unsigned CPUserIndex, unsigned UserOffset,
393*9880d681SAndroid Build Coastguard Worker                         MachineBasicBlock *&NewMBB);
394*9880d681SAndroid Build Coastguard Worker     bool handleConstantPoolUser(unsigned CPUserIndex);
395*9880d681SAndroid Build Coastguard Worker     void removeDeadCPEMI(MachineInstr *CPEMI);
396*9880d681SAndroid Build Coastguard Worker     bool removeUnusedCPEntries();
397*9880d681SAndroid Build Coastguard Worker     bool isCPEntryInRange(MachineInstr *MI, unsigned UserOffset,
398*9880d681SAndroid Build Coastguard Worker                           MachineInstr *CPEMI, unsigned Disp, bool NegOk,
399*9880d681SAndroid Build Coastguard Worker                           bool DoDump = false);
400*9880d681SAndroid Build Coastguard Worker     bool isWaterInRange(unsigned UserOffset, MachineBasicBlock *Water,
401*9880d681SAndroid Build Coastguard Worker                         CPUser &U, unsigned &Growth);
402*9880d681SAndroid Build Coastguard Worker     bool isBBInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp);
403*9880d681SAndroid Build Coastguard Worker     bool fixupImmediateBr(ImmBranch &Br);
404*9880d681SAndroid Build Coastguard Worker     bool fixupConditionalBr(ImmBranch &Br);
405*9880d681SAndroid Build Coastguard Worker     bool fixupUnconditionalBr(ImmBranch &Br);
406*9880d681SAndroid Build Coastguard Worker 
407*9880d681SAndroid Build Coastguard Worker     void prescanForConstants();
408*9880d681SAndroid Build Coastguard Worker 
409*9880d681SAndroid Build Coastguard Worker   private:
410*9880d681SAndroid Build Coastguard Worker 
411*9880d681SAndroid Build Coastguard Worker   };
412*9880d681SAndroid Build Coastguard Worker 
413*9880d681SAndroid Build Coastguard Worker   char MipsConstantIslands::ID = 0;
414*9880d681SAndroid Build Coastguard Worker } // end of anonymous namespace
415*9880d681SAndroid Build Coastguard Worker 
isOffsetInRange(unsigned UserOffset,unsigned TrialOffset,const CPUser & U)416*9880d681SAndroid Build Coastguard Worker bool MipsConstantIslands::isOffsetInRange
417*9880d681SAndroid Build Coastguard Worker   (unsigned UserOffset, unsigned TrialOffset,
418*9880d681SAndroid Build Coastguard Worker    const CPUser &U) {
419*9880d681SAndroid Build Coastguard Worker   return isOffsetInRange(UserOffset, TrialOffset,
420*9880d681SAndroid Build Coastguard Worker                          U.getMaxDisp(), U.NegOk);
421*9880d681SAndroid Build Coastguard Worker }
422*9880d681SAndroid Build Coastguard Worker /// print block size and offset information - debugging
dumpBBs()423*9880d681SAndroid Build Coastguard Worker void MipsConstantIslands::dumpBBs() {
424*9880d681SAndroid Build Coastguard Worker   DEBUG({
425*9880d681SAndroid Build Coastguard Worker     for (unsigned J = 0, E = BBInfo.size(); J !=E; ++J) {
426*9880d681SAndroid Build Coastguard Worker       const BasicBlockInfo &BBI = BBInfo[J];
427*9880d681SAndroid Build Coastguard Worker       dbgs() << format("%08x BB#%u\t", BBI.Offset, J)
428*9880d681SAndroid Build Coastguard Worker              << format(" size=%#x\n", BBInfo[J].Size);
429*9880d681SAndroid Build Coastguard Worker     }
430*9880d681SAndroid Build Coastguard Worker   });
431*9880d681SAndroid Build Coastguard Worker }
432*9880d681SAndroid Build Coastguard Worker /// Returns a pass that converts branches to long branches.
createMipsConstantIslandPass()433*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createMipsConstantIslandPass() {
434*9880d681SAndroid Build Coastguard Worker   return new MipsConstantIslands();
435*9880d681SAndroid Build Coastguard Worker }
436*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & mf)437*9880d681SAndroid Build Coastguard Worker bool MipsConstantIslands::runOnMachineFunction(MachineFunction &mf) {
438*9880d681SAndroid Build Coastguard Worker   // The intention is for this to be a mips16 only pass for now
439*9880d681SAndroid Build Coastguard Worker   // FIXME:
440*9880d681SAndroid Build Coastguard Worker   MF = &mf;
441*9880d681SAndroid Build Coastguard Worker   MCP = mf.getConstantPool();
442*9880d681SAndroid Build Coastguard Worker   STI = &static_cast<const MipsSubtarget &>(mf.getSubtarget());
443*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "constant island machine function " << "\n");
444*9880d681SAndroid Build Coastguard Worker   if (!STI->inMips16Mode() || !MipsSubtarget::useConstantIslands()) {
445*9880d681SAndroid Build Coastguard Worker     return false;
446*9880d681SAndroid Build Coastguard Worker   }
447*9880d681SAndroid Build Coastguard Worker   TII = (const Mips16InstrInfo *)STI->getInstrInfo();
448*9880d681SAndroid Build Coastguard Worker   MFI = MF->getInfo<MipsFunctionInfo>();
449*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "constant island processing " << "\n");
450*9880d681SAndroid Build Coastguard Worker   //
451*9880d681SAndroid Build Coastguard Worker   // will need to make predermination if there is any constants we need to
452*9880d681SAndroid Build Coastguard Worker   // put in constant islands. TBD.
453*9880d681SAndroid Build Coastguard Worker   //
454*9880d681SAndroid Build Coastguard Worker   if (!PrescannedForConstants) prescanForConstants();
455*9880d681SAndroid Build Coastguard Worker 
456*9880d681SAndroid Build Coastguard Worker   HasFarJump = false;
457*9880d681SAndroid Build Coastguard Worker   // This pass invalidates liveness information when it splits basic blocks.
458*9880d681SAndroid Build Coastguard Worker   MF->getRegInfo().invalidateLiveness();
459*9880d681SAndroid Build Coastguard Worker 
460*9880d681SAndroid Build Coastguard Worker   // Renumber all of the machine basic blocks in the function, guaranteeing that
461*9880d681SAndroid Build Coastguard Worker   // the numbers agree with the position of the block in the function.
462*9880d681SAndroid Build Coastguard Worker   MF->RenumberBlocks();
463*9880d681SAndroid Build Coastguard Worker 
464*9880d681SAndroid Build Coastguard Worker   bool MadeChange = false;
465*9880d681SAndroid Build Coastguard Worker 
466*9880d681SAndroid Build Coastguard Worker   // Perform the initial placement of the constant pool entries.  To start with,
467*9880d681SAndroid Build Coastguard Worker   // we put them all at the end of the function.
468*9880d681SAndroid Build Coastguard Worker   std::vector<MachineInstr*> CPEMIs;
469*9880d681SAndroid Build Coastguard Worker   if (!MCP->isEmpty())
470*9880d681SAndroid Build Coastguard Worker     doInitialPlacement(CPEMIs);
471*9880d681SAndroid Build Coastguard Worker 
472*9880d681SAndroid Build Coastguard Worker   /// The next UID to take is the first unused one.
473*9880d681SAndroid Build Coastguard Worker   initPICLabelUId(CPEMIs.size());
474*9880d681SAndroid Build Coastguard Worker 
475*9880d681SAndroid Build Coastguard Worker   // Do the initial scan of the function, building up information about the
476*9880d681SAndroid Build Coastguard Worker   // sizes of each block, the location of all the water, and finding all of the
477*9880d681SAndroid Build Coastguard Worker   // constant pool users.
478*9880d681SAndroid Build Coastguard Worker   initializeFunctionInfo(CPEMIs);
479*9880d681SAndroid Build Coastguard Worker   CPEMIs.clear();
480*9880d681SAndroid Build Coastguard Worker   DEBUG(dumpBBs());
481*9880d681SAndroid Build Coastguard Worker 
482*9880d681SAndroid Build Coastguard Worker   /// Remove dead constant pool entries.
483*9880d681SAndroid Build Coastguard Worker   MadeChange |= removeUnusedCPEntries();
484*9880d681SAndroid Build Coastguard Worker 
485*9880d681SAndroid Build Coastguard Worker   // Iteratively place constant pool entries and fix up branches until there
486*9880d681SAndroid Build Coastguard Worker   // is no change.
487*9880d681SAndroid Build Coastguard Worker   unsigned NoCPIters = 0, NoBRIters = 0;
488*9880d681SAndroid Build Coastguard Worker   (void)NoBRIters;
489*9880d681SAndroid Build Coastguard Worker   while (true) {
490*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Beginning CP iteration #" << NoCPIters << '\n');
491*9880d681SAndroid Build Coastguard Worker     bool CPChange = false;
492*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = CPUsers.size(); i != e; ++i)
493*9880d681SAndroid Build Coastguard Worker       CPChange |= handleConstantPoolUser(i);
494*9880d681SAndroid Build Coastguard Worker     if (CPChange && ++NoCPIters > 30)
495*9880d681SAndroid Build Coastguard Worker       report_fatal_error("Constant Island pass failed to converge!");
496*9880d681SAndroid Build Coastguard Worker     DEBUG(dumpBBs());
497*9880d681SAndroid Build Coastguard Worker 
498*9880d681SAndroid Build Coastguard Worker     // Clear NewWaterList now.  If we split a block for branches, it should
499*9880d681SAndroid Build Coastguard Worker     // appear as "new water" for the next iteration of constant pool placement.
500*9880d681SAndroid Build Coastguard Worker     NewWaterList.clear();
501*9880d681SAndroid Build Coastguard Worker 
502*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Beginning BR iteration #" << NoBRIters << '\n');
503*9880d681SAndroid Build Coastguard Worker     bool BRChange = false;
504*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = ImmBranches.size(); i != e; ++i)
505*9880d681SAndroid Build Coastguard Worker       BRChange |= fixupImmediateBr(ImmBranches[i]);
506*9880d681SAndroid Build Coastguard Worker     if (BRChange && ++NoBRIters > 30)
507*9880d681SAndroid Build Coastguard Worker       report_fatal_error("Branch Fix Up pass failed to converge!");
508*9880d681SAndroid Build Coastguard Worker     DEBUG(dumpBBs());
509*9880d681SAndroid Build Coastguard Worker     if (!CPChange && !BRChange)
510*9880d681SAndroid Build Coastguard Worker       break;
511*9880d681SAndroid Build Coastguard Worker     MadeChange = true;
512*9880d681SAndroid Build Coastguard Worker   }
513*9880d681SAndroid Build Coastguard Worker 
514*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << '\n'; dumpBBs());
515*9880d681SAndroid Build Coastguard Worker 
516*9880d681SAndroid Build Coastguard Worker   BBInfo.clear();
517*9880d681SAndroid Build Coastguard Worker   WaterList.clear();
518*9880d681SAndroid Build Coastguard Worker   CPUsers.clear();
519*9880d681SAndroid Build Coastguard Worker   CPEntries.clear();
520*9880d681SAndroid Build Coastguard Worker   ImmBranches.clear();
521*9880d681SAndroid Build Coastguard Worker   return MadeChange;
522*9880d681SAndroid Build Coastguard Worker }
523*9880d681SAndroid Build Coastguard Worker 
524*9880d681SAndroid Build Coastguard Worker /// doInitialPlacement - Perform the initial placement of the constant pool
525*9880d681SAndroid Build Coastguard Worker /// entries.  To start with, we put them all at the end of the function.
526*9880d681SAndroid Build Coastguard Worker void
doInitialPlacement(std::vector<MachineInstr * > & CPEMIs)527*9880d681SAndroid Build Coastguard Worker MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
528*9880d681SAndroid Build Coastguard Worker   // Create the basic block to hold the CPE's.
529*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *BB = MF->CreateMachineBasicBlock();
530*9880d681SAndroid Build Coastguard Worker   MF->push_back(BB);
531*9880d681SAndroid Build Coastguard Worker 
532*9880d681SAndroid Build Coastguard Worker 
533*9880d681SAndroid Build Coastguard Worker   // MachineConstantPool measures alignment in bytes. We measure in log2(bytes).
534*9880d681SAndroid Build Coastguard Worker   unsigned MaxAlign = Log2_32(MCP->getConstantPoolAlignment());
535*9880d681SAndroid Build Coastguard Worker 
536*9880d681SAndroid Build Coastguard Worker   // Mark the basic block as required by the const-pool.
537*9880d681SAndroid Build Coastguard Worker   // If AlignConstantIslands isn't set, use 4-byte alignment for everything.
538*9880d681SAndroid Build Coastguard Worker   BB->setAlignment(AlignConstantIslands ? MaxAlign : 2);
539*9880d681SAndroid Build Coastguard Worker 
540*9880d681SAndroid Build Coastguard Worker   // The function needs to be as aligned as the basic blocks. The linker may
541*9880d681SAndroid Build Coastguard Worker   // move functions around based on their alignment.
542*9880d681SAndroid Build Coastguard Worker   MF->ensureAlignment(BB->getAlignment());
543*9880d681SAndroid Build Coastguard Worker 
544*9880d681SAndroid Build Coastguard Worker   // Order the entries in BB by descending alignment.  That ensures correct
545*9880d681SAndroid Build Coastguard Worker   // alignment of all entries as long as BB is sufficiently aligned.  Keep
546*9880d681SAndroid Build Coastguard Worker   // track of the insertion point for each alignment.  We are going to bucket
547*9880d681SAndroid Build Coastguard Worker   // sort the entries as they are created.
548*9880d681SAndroid Build Coastguard Worker   SmallVector<MachineBasicBlock::iterator, 8> InsPoint(MaxAlign + 1, BB->end());
549*9880d681SAndroid Build Coastguard Worker 
550*9880d681SAndroid Build Coastguard Worker   // Add all of the constants from the constant pool to the end block, use an
551*9880d681SAndroid Build Coastguard Worker   // identity mapping of CPI's to CPE's.
552*9880d681SAndroid Build Coastguard Worker   const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
553*9880d681SAndroid Build Coastguard Worker 
554*9880d681SAndroid Build Coastguard Worker   const DataLayout &TD = MF->getDataLayout();
555*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = CPs.size(); i != e; ++i) {
556*9880d681SAndroid Build Coastguard Worker     unsigned Size = TD.getTypeAllocSize(CPs[i].getType());
557*9880d681SAndroid Build Coastguard Worker     assert(Size >= 4 && "Too small constant pool entry");
558*9880d681SAndroid Build Coastguard Worker     unsigned Align = CPs[i].getAlignment();
559*9880d681SAndroid Build Coastguard Worker     assert(isPowerOf2_32(Align) && "Invalid alignment");
560*9880d681SAndroid Build Coastguard Worker     // Verify that all constant pool entries are a multiple of their alignment.
561*9880d681SAndroid Build Coastguard Worker     // If not, we would have to pad them out so that instructions stay aligned.
562*9880d681SAndroid Build Coastguard Worker     assert((Size % Align) == 0 && "CP Entry not multiple of 4 bytes!");
563*9880d681SAndroid Build Coastguard Worker 
564*9880d681SAndroid Build Coastguard Worker     // Insert CONSTPOOL_ENTRY before entries with a smaller alignment.
565*9880d681SAndroid Build Coastguard Worker     unsigned LogAlign = Log2_32(Align);
566*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator InsAt = InsPoint[LogAlign];
567*9880d681SAndroid Build Coastguard Worker 
568*9880d681SAndroid Build Coastguard Worker     MachineInstr *CPEMI =
569*9880d681SAndroid Build Coastguard Worker       BuildMI(*BB, InsAt, DebugLoc(), TII->get(Mips::CONSTPOOL_ENTRY))
570*9880d681SAndroid Build Coastguard Worker         .addImm(i).addConstantPoolIndex(i).addImm(Size);
571*9880d681SAndroid Build Coastguard Worker 
572*9880d681SAndroid Build Coastguard Worker     CPEMIs.push_back(CPEMI);
573*9880d681SAndroid Build Coastguard Worker 
574*9880d681SAndroid Build Coastguard Worker     // Ensure that future entries with higher alignment get inserted before
575*9880d681SAndroid Build Coastguard Worker     // CPEMI. This is bucket sort with iterators.
576*9880d681SAndroid Build Coastguard Worker     for (unsigned a = LogAlign + 1; a <= MaxAlign; ++a)
577*9880d681SAndroid Build Coastguard Worker       if (InsPoint[a] == InsAt)
578*9880d681SAndroid Build Coastguard Worker         InsPoint[a] = CPEMI;
579*9880d681SAndroid Build Coastguard Worker     // Add a new CPEntry, but no corresponding CPUser yet.
580*9880d681SAndroid Build Coastguard Worker     CPEntries.emplace_back(1, CPEntry(CPEMI, i));
581*9880d681SAndroid Build Coastguard Worker     ++NumCPEs;
582*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Moved CPI#" << i << " to end of function, size = "
583*9880d681SAndroid Build Coastguard Worker                  << Size << ", align = " << Align <<'\n');
584*9880d681SAndroid Build Coastguard Worker   }
585*9880d681SAndroid Build Coastguard Worker   DEBUG(BB->dump());
586*9880d681SAndroid Build Coastguard Worker }
587*9880d681SAndroid Build Coastguard Worker 
588*9880d681SAndroid Build Coastguard Worker /// BBHasFallthrough - Return true if the specified basic block can fallthrough
589*9880d681SAndroid Build Coastguard Worker /// into the block immediately after it.
BBHasFallthrough(MachineBasicBlock * MBB)590*9880d681SAndroid Build Coastguard Worker static bool BBHasFallthrough(MachineBasicBlock *MBB) {
591*9880d681SAndroid Build Coastguard Worker   // Get the next machine basic block in the function.
592*9880d681SAndroid Build Coastguard Worker   MachineFunction::iterator MBBI = MBB->getIterator();
593*9880d681SAndroid Build Coastguard Worker   // Can't fall off end of function.
594*9880d681SAndroid Build Coastguard Worker   if (std::next(MBBI) == MBB->getParent()->end())
595*9880d681SAndroid Build Coastguard Worker     return false;
596*9880d681SAndroid Build Coastguard Worker 
597*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *NextBB = &*std::next(MBBI);
598*9880d681SAndroid Build Coastguard Worker   for (MachineBasicBlock::succ_iterator I = MBB->succ_begin(),
599*9880d681SAndroid Build Coastguard Worker        E = MBB->succ_end(); I != E; ++I)
600*9880d681SAndroid Build Coastguard Worker     if (*I == NextBB)
601*9880d681SAndroid Build Coastguard Worker       return true;
602*9880d681SAndroid Build Coastguard Worker 
603*9880d681SAndroid Build Coastguard Worker   return false;
604*9880d681SAndroid Build Coastguard Worker }
605*9880d681SAndroid Build Coastguard Worker 
606*9880d681SAndroid Build Coastguard Worker /// findConstPoolEntry - Given the constpool index and CONSTPOOL_ENTRY MI,
607*9880d681SAndroid Build Coastguard Worker /// look up the corresponding CPEntry.
608*9880d681SAndroid Build Coastguard Worker MipsConstantIslands::CPEntry
findConstPoolEntry(unsigned CPI,const MachineInstr * CPEMI)609*9880d681SAndroid Build Coastguard Worker *MipsConstantIslands::findConstPoolEntry(unsigned CPI,
610*9880d681SAndroid Build Coastguard Worker                                         const MachineInstr *CPEMI) {
611*9880d681SAndroid Build Coastguard Worker   std::vector<CPEntry> &CPEs = CPEntries[CPI];
612*9880d681SAndroid Build Coastguard Worker   // Number of entries per constpool index should be small, just do a
613*9880d681SAndroid Build Coastguard Worker   // linear search.
614*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = CPEs.size(); i != e; ++i) {
615*9880d681SAndroid Build Coastguard Worker     if (CPEs[i].CPEMI == CPEMI)
616*9880d681SAndroid Build Coastguard Worker       return &CPEs[i];
617*9880d681SAndroid Build Coastguard Worker   }
618*9880d681SAndroid Build Coastguard Worker   return nullptr;
619*9880d681SAndroid Build Coastguard Worker }
620*9880d681SAndroid Build Coastguard Worker 
621*9880d681SAndroid Build Coastguard Worker /// getCPELogAlign - Returns the required alignment of the constant pool entry
622*9880d681SAndroid Build Coastguard Worker /// represented by CPEMI.  Alignment is measured in log2(bytes) units.
getCPELogAlign(const MachineInstr & CPEMI)623*9880d681SAndroid Build Coastguard Worker unsigned MipsConstantIslands::getCPELogAlign(const MachineInstr &CPEMI) {
624*9880d681SAndroid Build Coastguard Worker   assert(CPEMI.getOpcode() == Mips::CONSTPOOL_ENTRY);
625*9880d681SAndroid Build Coastguard Worker 
626*9880d681SAndroid Build Coastguard Worker   // Everything is 4-byte aligned unless AlignConstantIslands is set.
627*9880d681SAndroid Build Coastguard Worker   if (!AlignConstantIslands)
628*9880d681SAndroid Build Coastguard Worker     return 2;
629*9880d681SAndroid Build Coastguard Worker 
630*9880d681SAndroid Build Coastguard Worker   unsigned CPI = CPEMI.getOperand(1).getIndex();
631*9880d681SAndroid Build Coastguard Worker   assert(CPI < MCP->getConstants().size() && "Invalid constant pool index.");
632*9880d681SAndroid Build Coastguard Worker   unsigned Align = MCP->getConstants()[CPI].getAlignment();
633*9880d681SAndroid Build Coastguard Worker   assert(isPowerOf2_32(Align) && "Invalid CPE alignment");
634*9880d681SAndroid Build Coastguard Worker   return Log2_32(Align);
635*9880d681SAndroid Build Coastguard Worker }
636*9880d681SAndroid Build Coastguard Worker 
637*9880d681SAndroid Build Coastguard Worker /// initializeFunctionInfo - Do the initial scan of the function, building up
638*9880d681SAndroid Build Coastguard Worker /// information about the sizes of each block, the location of all the water,
639*9880d681SAndroid Build Coastguard Worker /// and finding all of the constant pool users.
640*9880d681SAndroid Build Coastguard Worker void MipsConstantIslands::
initializeFunctionInfo(const std::vector<MachineInstr * > & CPEMIs)641*9880d681SAndroid Build Coastguard Worker initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
642*9880d681SAndroid Build Coastguard Worker   BBInfo.clear();
643*9880d681SAndroid Build Coastguard Worker   BBInfo.resize(MF->getNumBlockIDs());
644*9880d681SAndroid Build Coastguard Worker 
645*9880d681SAndroid Build Coastguard Worker   // First thing, compute the size of all basic blocks, and see if the function
646*9880d681SAndroid Build Coastguard Worker   // has any inline assembly in it. If so, we have to be conservative about
647*9880d681SAndroid Build Coastguard Worker   // alignment assumptions, as we don't know for sure the size of any
648*9880d681SAndroid Build Coastguard Worker   // instructions in the inline assembly.
649*9880d681SAndroid Build Coastguard Worker   for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I)
650*9880d681SAndroid Build Coastguard Worker     computeBlockSize(&*I);
651*9880d681SAndroid Build Coastguard Worker 
652*9880d681SAndroid Build Coastguard Worker 
653*9880d681SAndroid Build Coastguard Worker   // Compute block offsets.
654*9880d681SAndroid Build Coastguard Worker   adjustBBOffsetsAfter(&MF->front());
655*9880d681SAndroid Build Coastguard Worker 
656*9880d681SAndroid Build Coastguard Worker   // Now go back through the instructions and build up our data structures.
657*9880d681SAndroid Build Coastguard Worker   for (MachineBasicBlock &MBB : *MF) {
658*9880d681SAndroid Build Coastguard Worker     // If this block doesn't fall through into the next MBB, then this is
659*9880d681SAndroid Build Coastguard Worker     // 'water' that a constant pool island could be placed.
660*9880d681SAndroid Build Coastguard Worker     if (!BBHasFallthrough(&MBB))
661*9880d681SAndroid Build Coastguard Worker       WaterList.push_back(&MBB);
662*9880d681SAndroid Build Coastguard Worker     for (MachineInstr &MI : MBB) {
663*9880d681SAndroid Build Coastguard Worker       if (MI.isDebugValue())
664*9880d681SAndroid Build Coastguard Worker         continue;
665*9880d681SAndroid Build Coastguard Worker 
666*9880d681SAndroid Build Coastguard Worker       int Opc = MI.getOpcode();
667*9880d681SAndroid Build Coastguard Worker       if (MI.isBranch()) {
668*9880d681SAndroid Build Coastguard Worker         bool isCond = false;
669*9880d681SAndroid Build Coastguard Worker         unsigned Bits = 0;
670*9880d681SAndroid Build Coastguard Worker         unsigned Scale = 1;
671*9880d681SAndroid Build Coastguard Worker         int UOpc = Opc;
672*9880d681SAndroid Build Coastguard Worker         switch (Opc) {
673*9880d681SAndroid Build Coastguard Worker         default:
674*9880d681SAndroid Build Coastguard Worker           continue;  // Ignore other branches for now
675*9880d681SAndroid Build Coastguard Worker         case Mips::Bimm16:
676*9880d681SAndroid Build Coastguard Worker           Bits = 11;
677*9880d681SAndroid Build Coastguard Worker           Scale = 2;
678*9880d681SAndroid Build Coastguard Worker           isCond = false;
679*9880d681SAndroid Build Coastguard Worker           break;
680*9880d681SAndroid Build Coastguard Worker         case Mips::BimmX16:
681*9880d681SAndroid Build Coastguard Worker           Bits = 16;
682*9880d681SAndroid Build Coastguard Worker           Scale = 2;
683*9880d681SAndroid Build Coastguard Worker           isCond = false;
684*9880d681SAndroid Build Coastguard Worker           break;
685*9880d681SAndroid Build Coastguard Worker         case Mips::BeqzRxImm16:
686*9880d681SAndroid Build Coastguard Worker           UOpc=Mips::Bimm16;
687*9880d681SAndroid Build Coastguard Worker           Bits = 8;
688*9880d681SAndroid Build Coastguard Worker           Scale = 2;
689*9880d681SAndroid Build Coastguard Worker           isCond = true;
690*9880d681SAndroid Build Coastguard Worker           break;
691*9880d681SAndroid Build Coastguard Worker         case Mips::BeqzRxImmX16:
692*9880d681SAndroid Build Coastguard Worker           UOpc=Mips::Bimm16;
693*9880d681SAndroid Build Coastguard Worker           Bits = 16;
694*9880d681SAndroid Build Coastguard Worker           Scale = 2;
695*9880d681SAndroid Build Coastguard Worker           isCond = true;
696*9880d681SAndroid Build Coastguard Worker           break;
697*9880d681SAndroid Build Coastguard Worker         case Mips::BnezRxImm16:
698*9880d681SAndroid Build Coastguard Worker           UOpc=Mips::Bimm16;
699*9880d681SAndroid Build Coastguard Worker           Bits = 8;
700*9880d681SAndroid Build Coastguard Worker           Scale = 2;
701*9880d681SAndroid Build Coastguard Worker           isCond = true;
702*9880d681SAndroid Build Coastguard Worker           break;
703*9880d681SAndroid Build Coastguard Worker         case Mips::BnezRxImmX16:
704*9880d681SAndroid Build Coastguard Worker           UOpc=Mips::Bimm16;
705*9880d681SAndroid Build Coastguard Worker           Bits = 16;
706*9880d681SAndroid Build Coastguard Worker           Scale = 2;
707*9880d681SAndroid Build Coastguard Worker           isCond = true;
708*9880d681SAndroid Build Coastguard Worker           break;
709*9880d681SAndroid Build Coastguard Worker         case Mips::Bteqz16:
710*9880d681SAndroid Build Coastguard Worker           UOpc=Mips::Bimm16;
711*9880d681SAndroid Build Coastguard Worker           Bits = 8;
712*9880d681SAndroid Build Coastguard Worker           Scale = 2;
713*9880d681SAndroid Build Coastguard Worker           isCond = true;
714*9880d681SAndroid Build Coastguard Worker           break;
715*9880d681SAndroid Build Coastguard Worker         case Mips::BteqzX16:
716*9880d681SAndroid Build Coastguard Worker           UOpc=Mips::Bimm16;
717*9880d681SAndroid Build Coastguard Worker           Bits = 16;
718*9880d681SAndroid Build Coastguard Worker           Scale = 2;
719*9880d681SAndroid Build Coastguard Worker           isCond = true;
720*9880d681SAndroid Build Coastguard Worker           break;
721*9880d681SAndroid Build Coastguard Worker         case Mips::Btnez16:
722*9880d681SAndroid Build Coastguard Worker           UOpc=Mips::Bimm16;
723*9880d681SAndroid Build Coastguard Worker           Bits = 8;
724*9880d681SAndroid Build Coastguard Worker           Scale = 2;
725*9880d681SAndroid Build Coastguard Worker           isCond = true;
726*9880d681SAndroid Build Coastguard Worker           break;
727*9880d681SAndroid Build Coastguard Worker         case Mips::BtnezX16:
728*9880d681SAndroid Build Coastguard Worker           UOpc=Mips::Bimm16;
729*9880d681SAndroid Build Coastguard Worker           Bits = 16;
730*9880d681SAndroid Build Coastguard Worker           Scale = 2;
731*9880d681SAndroid Build Coastguard Worker           isCond = true;
732*9880d681SAndroid Build Coastguard Worker           break;
733*9880d681SAndroid Build Coastguard Worker         }
734*9880d681SAndroid Build Coastguard Worker         // Record this immediate branch.
735*9880d681SAndroid Build Coastguard Worker         unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
736*9880d681SAndroid Build Coastguard Worker         ImmBranches.push_back(ImmBranch(&MI, MaxOffs, isCond, UOpc));
737*9880d681SAndroid Build Coastguard Worker       }
738*9880d681SAndroid Build Coastguard Worker 
739*9880d681SAndroid Build Coastguard Worker       if (Opc == Mips::CONSTPOOL_ENTRY)
740*9880d681SAndroid Build Coastguard Worker         continue;
741*9880d681SAndroid Build Coastguard Worker 
742*9880d681SAndroid Build Coastguard Worker 
743*9880d681SAndroid Build Coastguard Worker       // Scan the instructions for constant pool operands.
744*9880d681SAndroid Build Coastguard Worker       for (unsigned op = 0, e = MI.getNumOperands(); op != e; ++op)
745*9880d681SAndroid Build Coastguard Worker         if (MI.getOperand(op).isCPI()) {
746*9880d681SAndroid Build Coastguard Worker 
747*9880d681SAndroid Build Coastguard Worker           // We found one.  The addressing mode tells us the max displacement
748*9880d681SAndroid Build Coastguard Worker           // from the PC that this instruction permits.
749*9880d681SAndroid Build Coastguard Worker 
750*9880d681SAndroid Build Coastguard Worker           // Basic size info comes from the TSFlags field.
751*9880d681SAndroid Build Coastguard Worker           unsigned Bits = 0;
752*9880d681SAndroid Build Coastguard Worker           unsigned Scale = 1;
753*9880d681SAndroid Build Coastguard Worker           bool NegOk = false;
754*9880d681SAndroid Build Coastguard Worker           unsigned LongFormBits = 0;
755*9880d681SAndroid Build Coastguard Worker           unsigned LongFormScale = 0;
756*9880d681SAndroid Build Coastguard Worker           unsigned LongFormOpcode = 0;
757*9880d681SAndroid Build Coastguard Worker           switch (Opc) {
758*9880d681SAndroid Build Coastguard Worker           default:
759*9880d681SAndroid Build Coastguard Worker             llvm_unreachable("Unknown addressing mode for CP reference!");
760*9880d681SAndroid Build Coastguard Worker           case Mips::LwRxPcTcp16:
761*9880d681SAndroid Build Coastguard Worker             Bits = 8;
762*9880d681SAndroid Build Coastguard Worker             Scale = 4;
763*9880d681SAndroid Build Coastguard Worker             LongFormOpcode = Mips::LwRxPcTcpX16;
764*9880d681SAndroid Build Coastguard Worker             LongFormBits = 14;
765*9880d681SAndroid Build Coastguard Worker             LongFormScale = 1;
766*9880d681SAndroid Build Coastguard Worker             break;
767*9880d681SAndroid Build Coastguard Worker           case Mips::LwRxPcTcpX16:
768*9880d681SAndroid Build Coastguard Worker             Bits = 14;
769*9880d681SAndroid Build Coastguard Worker             Scale = 1;
770*9880d681SAndroid Build Coastguard Worker             NegOk = true;
771*9880d681SAndroid Build Coastguard Worker             break;
772*9880d681SAndroid Build Coastguard Worker           }
773*9880d681SAndroid Build Coastguard Worker           // Remember that this is a user of a CP entry.
774*9880d681SAndroid Build Coastguard Worker           unsigned CPI = MI.getOperand(op).getIndex();
775*9880d681SAndroid Build Coastguard Worker           MachineInstr *CPEMI = CPEMIs[CPI];
776*9880d681SAndroid Build Coastguard Worker           unsigned MaxOffs = ((1 << Bits)-1) * Scale;
777*9880d681SAndroid Build Coastguard Worker           unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;
778*9880d681SAndroid Build Coastguard Worker           CPUsers.push_back(CPUser(&MI, CPEMI, MaxOffs, NegOk, LongFormMaxOffs,
779*9880d681SAndroid Build Coastguard Worker                                    LongFormOpcode));
780*9880d681SAndroid Build Coastguard Worker 
781*9880d681SAndroid Build Coastguard Worker           // Increment corresponding CPEntry reference count.
782*9880d681SAndroid Build Coastguard Worker           CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
783*9880d681SAndroid Build Coastguard Worker           assert(CPE && "Cannot find a corresponding CPEntry!");
784*9880d681SAndroid Build Coastguard Worker           CPE->RefCount++;
785*9880d681SAndroid Build Coastguard Worker 
786*9880d681SAndroid Build Coastguard Worker           // Instructions can only use one CP entry, don't bother scanning the
787*9880d681SAndroid Build Coastguard Worker           // rest of the operands.
788*9880d681SAndroid Build Coastguard Worker           break;
789*9880d681SAndroid Build Coastguard Worker 
790*9880d681SAndroid Build Coastguard Worker         }
791*9880d681SAndroid Build Coastguard Worker 
792*9880d681SAndroid Build Coastguard Worker     }
793*9880d681SAndroid Build Coastguard Worker   }
794*9880d681SAndroid Build Coastguard Worker 
795*9880d681SAndroid Build Coastguard Worker }
796*9880d681SAndroid Build Coastguard Worker 
797*9880d681SAndroid Build Coastguard Worker /// computeBlockSize - Compute the size and some alignment information for MBB.
798*9880d681SAndroid Build Coastguard Worker /// This function updates BBInfo directly.
computeBlockSize(MachineBasicBlock * MBB)799*9880d681SAndroid Build Coastguard Worker void MipsConstantIslands::computeBlockSize(MachineBasicBlock *MBB) {
800*9880d681SAndroid Build Coastguard Worker   BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];
801*9880d681SAndroid Build Coastguard Worker   BBI.Size = 0;
802*9880d681SAndroid Build Coastguard Worker 
803*9880d681SAndroid Build Coastguard Worker   for (const MachineInstr &MI : *MBB)
804*9880d681SAndroid Build Coastguard Worker     BBI.Size += TII->GetInstSizeInBytes(MI);
805*9880d681SAndroid Build Coastguard Worker }
806*9880d681SAndroid Build Coastguard Worker 
807*9880d681SAndroid Build Coastguard Worker /// getOffsetOf - Return the current offset of the specified machine instruction
808*9880d681SAndroid Build Coastguard Worker /// from the start of the function.  This offset changes as stuff is moved
809*9880d681SAndroid Build Coastguard Worker /// around inside the function.
getOffsetOf(MachineInstr * MI) const810*9880d681SAndroid Build Coastguard Worker unsigned MipsConstantIslands::getOffsetOf(MachineInstr *MI) const {
811*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *MBB = MI->getParent();
812*9880d681SAndroid Build Coastguard Worker 
813*9880d681SAndroid Build Coastguard Worker   // The offset is composed of two things: the sum of the sizes of all MBB's
814*9880d681SAndroid Build Coastguard Worker   // before this instruction's block, and the offset from the start of the block
815*9880d681SAndroid Build Coastguard Worker   // it is in.
816*9880d681SAndroid Build Coastguard Worker   unsigned Offset = BBInfo[MBB->getNumber()].Offset;
817*9880d681SAndroid Build Coastguard Worker 
818*9880d681SAndroid Build Coastguard Worker   // Sum instructions before MI in MBB.
819*9880d681SAndroid Build Coastguard Worker   for (MachineBasicBlock::iterator I = MBB->begin(); &*I != MI; ++I) {
820*9880d681SAndroid Build Coastguard Worker     assert(I != MBB->end() && "Didn't find MI in its own basic block?");
821*9880d681SAndroid Build Coastguard Worker     Offset += TII->GetInstSizeInBytes(*I);
822*9880d681SAndroid Build Coastguard Worker   }
823*9880d681SAndroid Build Coastguard Worker   return Offset;
824*9880d681SAndroid Build Coastguard Worker }
825*9880d681SAndroid Build Coastguard Worker 
826*9880d681SAndroid Build Coastguard Worker /// CompareMBBNumbers - Little predicate function to sort the WaterList by MBB
827*9880d681SAndroid Build Coastguard Worker /// ID.
CompareMBBNumbers(const MachineBasicBlock * LHS,const MachineBasicBlock * RHS)828*9880d681SAndroid Build Coastguard Worker static bool CompareMBBNumbers(const MachineBasicBlock *LHS,
829*9880d681SAndroid Build Coastguard Worker                               const MachineBasicBlock *RHS) {
830*9880d681SAndroid Build Coastguard Worker   return LHS->getNumber() < RHS->getNumber();
831*9880d681SAndroid Build Coastguard Worker }
832*9880d681SAndroid Build Coastguard Worker 
833*9880d681SAndroid Build Coastguard Worker /// updateForInsertedWaterBlock - When a block is newly inserted into the
834*9880d681SAndroid Build Coastguard Worker /// machine function, it upsets all of the block numbers.  Renumber the blocks
835*9880d681SAndroid Build Coastguard Worker /// and update the arrays that parallel this numbering.
updateForInsertedWaterBlock(MachineBasicBlock * NewBB)836*9880d681SAndroid Build Coastguard Worker void MipsConstantIslands::updateForInsertedWaterBlock
837*9880d681SAndroid Build Coastguard Worker   (MachineBasicBlock *NewBB) {
838*9880d681SAndroid Build Coastguard Worker   // Renumber the MBB's to keep them consecutive.
839*9880d681SAndroid Build Coastguard Worker   NewBB->getParent()->RenumberBlocks(NewBB);
840*9880d681SAndroid Build Coastguard Worker 
841*9880d681SAndroid Build Coastguard Worker   // Insert an entry into BBInfo to align it properly with the (newly
842*9880d681SAndroid Build Coastguard Worker   // renumbered) block numbers.
843*9880d681SAndroid Build Coastguard Worker   BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
844*9880d681SAndroid Build Coastguard Worker 
845*9880d681SAndroid Build Coastguard Worker   // Next, update WaterList.  Specifically, we need to add NewMBB as having
846*9880d681SAndroid Build Coastguard Worker   // available water after it.
847*9880d681SAndroid Build Coastguard Worker   water_iterator IP =
848*9880d681SAndroid Build Coastguard Worker     std::lower_bound(WaterList.begin(), WaterList.end(), NewBB,
849*9880d681SAndroid Build Coastguard Worker                      CompareMBBNumbers);
850*9880d681SAndroid Build Coastguard Worker   WaterList.insert(IP, NewBB);
851*9880d681SAndroid Build Coastguard Worker }
852*9880d681SAndroid Build Coastguard Worker 
getUserOffset(CPUser & U) const853*9880d681SAndroid Build Coastguard Worker unsigned MipsConstantIslands::getUserOffset(CPUser &U) const {
854*9880d681SAndroid Build Coastguard Worker   return getOffsetOf(U.MI);
855*9880d681SAndroid Build Coastguard Worker }
856*9880d681SAndroid Build Coastguard Worker 
857*9880d681SAndroid Build Coastguard Worker /// Split the basic block containing MI into two blocks, which are joined by
858*9880d681SAndroid Build Coastguard Worker /// an unconditional branch.  Update data structures and renumber blocks to
859*9880d681SAndroid Build Coastguard Worker /// account for this change and returns the newly created block.
860*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *
splitBlockBeforeInstr(MachineInstr & MI)861*9880d681SAndroid Build Coastguard Worker MipsConstantIslands::splitBlockBeforeInstr(MachineInstr &MI) {
862*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *OrigBB = MI.getParent();
863*9880d681SAndroid Build Coastguard Worker 
864*9880d681SAndroid Build Coastguard Worker   // Create a new MBB for the code after the OrigBB.
865*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *NewBB =
866*9880d681SAndroid Build Coastguard Worker     MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());
867*9880d681SAndroid Build Coastguard Worker   MachineFunction::iterator MBBI = ++OrigBB->getIterator();
868*9880d681SAndroid Build Coastguard Worker   MF->insert(MBBI, NewBB);
869*9880d681SAndroid Build Coastguard Worker 
870*9880d681SAndroid Build Coastguard Worker   // Splice the instructions starting with MI over to NewBB.
871*9880d681SAndroid Build Coastguard Worker   NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end());
872*9880d681SAndroid Build Coastguard Worker 
873*9880d681SAndroid Build Coastguard Worker   // Add an unconditional branch from OrigBB to NewBB.
874*9880d681SAndroid Build Coastguard Worker   // Note the new unconditional branch is not being recorded.
875*9880d681SAndroid Build Coastguard Worker   // There doesn't seem to be meaningful DebugInfo available; this doesn't
876*9880d681SAndroid Build Coastguard Worker   // correspond to anything in the source.
877*9880d681SAndroid Build Coastguard Worker   BuildMI(OrigBB, DebugLoc(), TII->get(Mips::Bimm16)).addMBB(NewBB);
878*9880d681SAndroid Build Coastguard Worker   ++NumSplit;
879*9880d681SAndroid Build Coastguard Worker 
880*9880d681SAndroid Build Coastguard Worker   // Update the CFG.  All succs of OrigBB are now succs of NewBB.
881*9880d681SAndroid Build Coastguard Worker   NewBB->transferSuccessors(OrigBB);
882*9880d681SAndroid Build Coastguard Worker 
883*9880d681SAndroid Build Coastguard Worker   // OrigBB branches to NewBB.
884*9880d681SAndroid Build Coastguard Worker   OrigBB->addSuccessor(NewBB);
885*9880d681SAndroid Build Coastguard Worker 
886*9880d681SAndroid Build Coastguard Worker   // Update internal data structures to account for the newly inserted MBB.
887*9880d681SAndroid Build Coastguard Worker   // This is almost the same as updateForInsertedWaterBlock, except that
888*9880d681SAndroid Build Coastguard Worker   // the Water goes after OrigBB, not NewBB.
889*9880d681SAndroid Build Coastguard Worker   MF->RenumberBlocks(NewBB);
890*9880d681SAndroid Build Coastguard Worker 
891*9880d681SAndroid Build Coastguard Worker   // Insert an entry into BBInfo to align it properly with the (newly
892*9880d681SAndroid Build Coastguard Worker   // renumbered) block numbers.
893*9880d681SAndroid Build Coastguard Worker   BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
894*9880d681SAndroid Build Coastguard Worker 
895*9880d681SAndroid Build Coastguard Worker   // Next, update WaterList.  Specifically, we need to add OrigMBB as having
896*9880d681SAndroid Build Coastguard Worker   // available water after it (but not if it's already there, which happens
897*9880d681SAndroid Build Coastguard Worker   // when splitting before a conditional branch that is followed by an
898*9880d681SAndroid Build Coastguard Worker   // unconditional branch - in that case we want to insert NewBB).
899*9880d681SAndroid Build Coastguard Worker   water_iterator IP =
900*9880d681SAndroid Build Coastguard Worker     std::lower_bound(WaterList.begin(), WaterList.end(), OrigBB,
901*9880d681SAndroid Build Coastguard Worker                      CompareMBBNumbers);
902*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock* WaterBB = *IP;
903*9880d681SAndroid Build Coastguard Worker   if (WaterBB == OrigBB)
904*9880d681SAndroid Build Coastguard Worker     WaterList.insert(std::next(IP), NewBB);
905*9880d681SAndroid Build Coastguard Worker   else
906*9880d681SAndroid Build Coastguard Worker     WaterList.insert(IP, OrigBB);
907*9880d681SAndroid Build Coastguard Worker   NewWaterList.insert(OrigBB);
908*9880d681SAndroid Build Coastguard Worker 
909*9880d681SAndroid Build Coastguard Worker   // Figure out how large the OrigBB is.  As the first half of the original
910*9880d681SAndroid Build Coastguard Worker   // block, it cannot contain a tablejump.  The size includes
911*9880d681SAndroid Build Coastguard Worker   // the new jump we added.  (It should be possible to do this without
912*9880d681SAndroid Build Coastguard Worker   // recounting everything, but it's very confusing, and this is rarely
913*9880d681SAndroid Build Coastguard Worker   // executed.)
914*9880d681SAndroid Build Coastguard Worker   computeBlockSize(OrigBB);
915*9880d681SAndroid Build Coastguard Worker 
916*9880d681SAndroid Build Coastguard Worker   // Figure out how large the NewMBB is.  As the second half of the original
917*9880d681SAndroid Build Coastguard Worker   // block, it may contain a tablejump.
918*9880d681SAndroid Build Coastguard Worker   computeBlockSize(NewBB);
919*9880d681SAndroid Build Coastguard Worker 
920*9880d681SAndroid Build Coastguard Worker   // All BBOffsets following these blocks must be modified.
921*9880d681SAndroid Build Coastguard Worker   adjustBBOffsetsAfter(OrigBB);
922*9880d681SAndroid Build Coastguard Worker 
923*9880d681SAndroid Build Coastguard Worker   return NewBB;
924*9880d681SAndroid Build Coastguard Worker }
925*9880d681SAndroid Build Coastguard Worker 
926*9880d681SAndroid Build Coastguard Worker 
927*9880d681SAndroid Build Coastguard Worker 
928*9880d681SAndroid Build Coastguard Worker /// isOffsetInRange - Checks whether UserOffset (the location of a constant pool
929*9880d681SAndroid Build Coastguard Worker /// reference) is within MaxDisp of TrialOffset (a proposed location of a
930*9880d681SAndroid Build Coastguard Worker /// constant pool entry).
isOffsetInRange(unsigned UserOffset,unsigned TrialOffset,unsigned MaxDisp,bool NegativeOK)931*9880d681SAndroid Build Coastguard Worker bool MipsConstantIslands::isOffsetInRange(unsigned UserOffset,
932*9880d681SAndroid Build Coastguard Worker                                          unsigned TrialOffset, unsigned MaxDisp,
933*9880d681SAndroid Build Coastguard Worker                                          bool NegativeOK) {
934*9880d681SAndroid Build Coastguard Worker   if (UserOffset <= TrialOffset) {
935*9880d681SAndroid Build Coastguard Worker     // User before the Trial.
936*9880d681SAndroid Build Coastguard Worker     if (TrialOffset - UserOffset <= MaxDisp)
937*9880d681SAndroid Build Coastguard Worker       return true;
938*9880d681SAndroid Build Coastguard Worker   } else if (NegativeOK) {
939*9880d681SAndroid Build Coastguard Worker     if (UserOffset - TrialOffset <= MaxDisp)
940*9880d681SAndroid Build Coastguard Worker       return true;
941*9880d681SAndroid Build Coastguard Worker   }
942*9880d681SAndroid Build Coastguard Worker   return false;
943*9880d681SAndroid Build Coastguard Worker }
944*9880d681SAndroid Build Coastguard Worker 
945*9880d681SAndroid Build Coastguard Worker /// isWaterInRange - Returns true if a CPE placed after the specified
946*9880d681SAndroid Build Coastguard Worker /// Water (a basic block) will be in range for the specific MI.
947*9880d681SAndroid Build Coastguard Worker ///
948*9880d681SAndroid Build Coastguard Worker /// Compute how much the function will grow by inserting a CPE after Water.
isWaterInRange(unsigned UserOffset,MachineBasicBlock * Water,CPUser & U,unsigned & Growth)949*9880d681SAndroid Build Coastguard Worker bool MipsConstantIslands::isWaterInRange(unsigned UserOffset,
950*9880d681SAndroid Build Coastguard Worker                                         MachineBasicBlock* Water, CPUser &U,
951*9880d681SAndroid Build Coastguard Worker                                         unsigned &Growth) {
952*9880d681SAndroid Build Coastguard Worker   unsigned CPELogAlign = getCPELogAlign(*U.CPEMI);
953*9880d681SAndroid Build Coastguard Worker   unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset(CPELogAlign);
954*9880d681SAndroid Build Coastguard Worker   unsigned NextBlockOffset, NextBlockAlignment;
955*9880d681SAndroid Build Coastguard Worker   MachineFunction::const_iterator NextBlock = ++Water->getIterator();
956*9880d681SAndroid Build Coastguard Worker   if (NextBlock == MF->end()) {
957*9880d681SAndroid Build Coastguard Worker     NextBlockOffset = BBInfo[Water->getNumber()].postOffset();
958*9880d681SAndroid Build Coastguard Worker     NextBlockAlignment = 0;
959*9880d681SAndroid Build Coastguard Worker   } else {
960*9880d681SAndroid Build Coastguard Worker     NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
961*9880d681SAndroid Build Coastguard Worker     NextBlockAlignment = NextBlock->getAlignment();
962*9880d681SAndroid Build Coastguard Worker   }
963*9880d681SAndroid Build Coastguard Worker   unsigned Size = U.CPEMI->getOperand(2).getImm();
964*9880d681SAndroid Build Coastguard Worker   unsigned CPEEnd = CPEOffset + Size;
965*9880d681SAndroid Build Coastguard Worker 
966*9880d681SAndroid Build Coastguard Worker   // The CPE may be able to hide in the alignment padding before the next
967*9880d681SAndroid Build Coastguard Worker   // block. It may also cause more padding to be required if it is more aligned
968*9880d681SAndroid Build Coastguard Worker   // that the next block.
969*9880d681SAndroid Build Coastguard Worker   if (CPEEnd > NextBlockOffset) {
970*9880d681SAndroid Build Coastguard Worker     Growth = CPEEnd - NextBlockOffset;
971*9880d681SAndroid Build Coastguard Worker     // Compute the padding that would go at the end of the CPE to align the next
972*9880d681SAndroid Build Coastguard Worker     // block.
973*9880d681SAndroid Build Coastguard Worker     Growth += OffsetToAlignment(CPEEnd, 1ULL << NextBlockAlignment);
974*9880d681SAndroid Build Coastguard Worker 
975*9880d681SAndroid Build Coastguard Worker     // If the CPE is to be inserted before the instruction, that will raise
976*9880d681SAndroid Build Coastguard Worker     // the offset of the instruction. Also account for unknown alignment padding
977*9880d681SAndroid Build Coastguard Worker     // in blocks between CPE and the user.
978*9880d681SAndroid Build Coastguard Worker     if (CPEOffset < UserOffset)
979*9880d681SAndroid Build Coastguard Worker       UserOffset += Growth;
980*9880d681SAndroid Build Coastguard Worker   } else
981*9880d681SAndroid Build Coastguard Worker     // CPE fits in existing padding.
982*9880d681SAndroid Build Coastguard Worker     Growth = 0;
983*9880d681SAndroid Build Coastguard Worker 
984*9880d681SAndroid Build Coastguard Worker   return isOffsetInRange(UserOffset, CPEOffset, U);
985*9880d681SAndroid Build Coastguard Worker }
986*9880d681SAndroid Build Coastguard Worker 
987*9880d681SAndroid Build Coastguard Worker /// isCPEntryInRange - Returns true if the distance between specific MI and
988*9880d681SAndroid Build Coastguard Worker /// specific ConstPool entry instruction can fit in MI's displacement field.
isCPEntryInRange(MachineInstr * MI,unsigned UserOffset,MachineInstr * CPEMI,unsigned MaxDisp,bool NegOk,bool DoDump)989*9880d681SAndroid Build Coastguard Worker bool MipsConstantIslands::isCPEntryInRange
990*9880d681SAndroid Build Coastguard Worker   (MachineInstr *MI, unsigned UserOffset,
991*9880d681SAndroid Build Coastguard Worker    MachineInstr *CPEMI, unsigned MaxDisp,
992*9880d681SAndroid Build Coastguard Worker    bool NegOk, bool DoDump) {
993*9880d681SAndroid Build Coastguard Worker   unsigned CPEOffset  = getOffsetOf(CPEMI);
994*9880d681SAndroid Build Coastguard Worker 
995*9880d681SAndroid Build Coastguard Worker   if (DoDump) {
996*9880d681SAndroid Build Coastguard Worker     DEBUG({
997*9880d681SAndroid Build Coastguard Worker       unsigned Block = MI->getParent()->getNumber();
998*9880d681SAndroid Build Coastguard Worker       const BasicBlockInfo &BBI = BBInfo[Block];
999*9880d681SAndroid Build Coastguard Worker       dbgs() << "User of CPE#" << CPEMI->getOperand(0).getImm()
1000*9880d681SAndroid Build Coastguard Worker              << " max delta=" << MaxDisp
1001*9880d681SAndroid Build Coastguard Worker              << format(" insn address=%#x", UserOffset)
1002*9880d681SAndroid Build Coastguard Worker              << " in BB#" << Block << ": "
1003*9880d681SAndroid Build Coastguard Worker              << format("%#x-%x\t", BBI.Offset, BBI.postOffset()) << *MI
1004*9880d681SAndroid Build Coastguard Worker              << format("CPE address=%#x offset=%+d: ", CPEOffset,
1005*9880d681SAndroid Build Coastguard Worker                        int(CPEOffset-UserOffset));
1006*9880d681SAndroid Build Coastguard Worker     });
1007*9880d681SAndroid Build Coastguard Worker   }
1008*9880d681SAndroid Build Coastguard Worker 
1009*9880d681SAndroid Build Coastguard Worker   return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
1010*9880d681SAndroid Build Coastguard Worker }
1011*9880d681SAndroid Build Coastguard Worker 
1012*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
1013*9880d681SAndroid Build Coastguard Worker /// BBIsJumpedOver - Return true of the specified basic block's only predecessor
1014*9880d681SAndroid Build Coastguard Worker /// unconditionally branches to its only successor.
BBIsJumpedOver(MachineBasicBlock * MBB)1015*9880d681SAndroid Build Coastguard Worker static bool BBIsJumpedOver(MachineBasicBlock *MBB) {
1016*9880d681SAndroid Build Coastguard Worker   if (MBB->pred_size() != 1 || MBB->succ_size() != 1)
1017*9880d681SAndroid Build Coastguard Worker     return false;
1018*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *Succ = *MBB->succ_begin();
1019*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *Pred = *MBB->pred_begin();
1020*9880d681SAndroid Build Coastguard Worker   MachineInstr *PredMI = &Pred->back();
1021*9880d681SAndroid Build Coastguard Worker   if (PredMI->getOpcode() == Mips::Bimm16)
1022*9880d681SAndroid Build Coastguard Worker     return PredMI->getOperand(0).getMBB() == Succ;
1023*9880d681SAndroid Build Coastguard Worker   return false;
1024*9880d681SAndroid Build Coastguard Worker }
1025*9880d681SAndroid Build Coastguard Worker #endif
1026*9880d681SAndroid Build Coastguard Worker 
adjustBBOffsetsAfter(MachineBasicBlock * BB)1027*9880d681SAndroid Build Coastguard Worker void MipsConstantIslands::adjustBBOffsetsAfter(MachineBasicBlock *BB) {
1028*9880d681SAndroid Build Coastguard Worker   unsigned BBNum = BB->getNumber();
1029*9880d681SAndroid Build Coastguard Worker   for(unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++i) {
1030*9880d681SAndroid Build Coastguard Worker     // Get the offset and known bits at the end of the layout predecessor.
1031*9880d681SAndroid Build Coastguard Worker     // Include the alignment of the current block.
1032*9880d681SAndroid Build Coastguard Worker     unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;
1033*9880d681SAndroid Build Coastguard Worker     BBInfo[i].Offset = Offset;
1034*9880d681SAndroid Build Coastguard Worker   }
1035*9880d681SAndroid Build Coastguard Worker }
1036*9880d681SAndroid Build Coastguard Worker 
1037*9880d681SAndroid Build Coastguard Worker /// decrementCPEReferenceCount - find the constant pool entry with index CPI
1038*9880d681SAndroid Build Coastguard Worker /// and instruction CPEMI, and decrement its refcount.  If the refcount
1039*9880d681SAndroid Build Coastguard Worker /// becomes 0 remove the entry and instruction.  Returns true if we removed
1040*9880d681SAndroid Build Coastguard Worker /// the entry, false if we didn't.
1041*9880d681SAndroid Build Coastguard Worker 
decrementCPEReferenceCount(unsigned CPI,MachineInstr * CPEMI)1042*9880d681SAndroid Build Coastguard Worker bool MipsConstantIslands::decrementCPEReferenceCount(unsigned CPI,
1043*9880d681SAndroid Build Coastguard Worker                                                     MachineInstr *CPEMI) {
1044*9880d681SAndroid Build Coastguard Worker   // Find the old entry. Eliminate it if it is no longer used.
1045*9880d681SAndroid Build Coastguard Worker   CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
1046*9880d681SAndroid Build Coastguard Worker   assert(CPE && "Unexpected!");
1047*9880d681SAndroid Build Coastguard Worker   if (--CPE->RefCount == 0) {
1048*9880d681SAndroid Build Coastguard Worker     removeDeadCPEMI(CPEMI);
1049*9880d681SAndroid Build Coastguard Worker     CPE->CPEMI = nullptr;
1050*9880d681SAndroid Build Coastguard Worker     --NumCPEs;
1051*9880d681SAndroid Build Coastguard Worker     return true;
1052*9880d681SAndroid Build Coastguard Worker   }
1053*9880d681SAndroid Build Coastguard Worker   return false;
1054*9880d681SAndroid Build Coastguard Worker }
1055*9880d681SAndroid Build Coastguard Worker 
1056*9880d681SAndroid Build Coastguard Worker /// LookForCPEntryInRange - see if the currently referenced CPE is in range;
1057*9880d681SAndroid Build Coastguard Worker /// if not, see if an in-range clone of the CPE is in range, and if so,
1058*9880d681SAndroid Build Coastguard Worker /// change the data structures so the user references the clone.  Returns:
1059*9880d681SAndroid Build Coastguard Worker /// 0 = no existing entry found
1060*9880d681SAndroid Build Coastguard Worker /// 1 = entry found, and there were no code insertions or deletions
1061*9880d681SAndroid Build Coastguard Worker /// 2 = entry found, and there were code insertions or deletions
findInRangeCPEntry(CPUser & U,unsigned UserOffset)1062*9880d681SAndroid Build Coastguard Worker int MipsConstantIslands::findInRangeCPEntry(CPUser& U, unsigned UserOffset)
1063*9880d681SAndroid Build Coastguard Worker {
1064*9880d681SAndroid Build Coastguard Worker   MachineInstr *UserMI = U.MI;
1065*9880d681SAndroid Build Coastguard Worker   MachineInstr *CPEMI  = U.CPEMI;
1066*9880d681SAndroid Build Coastguard Worker 
1067*9880d681SAndroid Build Coastguard Worker   // Check to see if the CPE is already in-range.
1068*9880d681SAndroid Build Coastguard Worker   if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk,
1069*9880d681SAndroid Build Coastguard Worker                        true)) {
1070*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "In range\n");
1071*9880d681SAndroid Build Coastguard Worker     return 1;
1072*9880d681SAndroid Build Coastguard Worker   }
1073*9880d681SAndroid Build Coastguard Worker 
1074*9880d681SAndroid Build Coastguard Worker   // No.  Look for previously created clones of the CPE that are in range.
1075*9880d681SAndroid Build Coastguard Worker   unsigned CPI = CPEMI->getOperand(1).getIndex();
1076*9880d681SAndroid Build Coastguard Worker   std::vector<CPEntry> &CPEs = CPEntries[CPI];
1077*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = CPEs.size(); i != e; ++i) {
1078*9880d681SAndroid Build Coastguard Worker     // We already tried this one
1079*9880d681SAndroid Build Coastguard Worker     if (CPEs[i].CPEMI == CPEMI)
1080*9880d681SAndroid Build Coastguard Worker       continue;
1081*9880d681SAndroid Build Coastguard Worker     // Removing CPEs can leave empty entries, skip
1082*9880d681SAndroid Build Coastguard Worker     if (CPEs[i].CPEMI == nullptr)
1083*9880d681SAndroid Build Coastguard Worker       continue;
1084*9880d681SAndroid Build Coastguard Worker     if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI, U.getMaxDisp(),
1085*9880d681SAndroid Build Coastguard Worker                      U.NegOk)) {
1086*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#"
1087*9880d681SAndroid Build Coastguard Worker                    << CPEs[i].CPI << "\n");
1088*9880d681SAndroid Build Coastguard Worker       // Point the CPUser node to the replacement
1089*9880d681SAndroid Build Coastguard Worker       U.CPEMI = CPEs[i].CPEMI;
1090*9880d681SAndroid Build Coastguard Worker       // Change the CPI in the instruction operand to refer to the clone.
1091*9880d681SAndroid Build Coastguard Worker       for (unsigned j = 0, e = UserMI->getNumOperands(); j != e; ++j)
1092*9880d681SAndroid Build Coastguard Worker         if (UserMI->getOperand(j).isCPI()) {
1093*9880d681SAndroid Build Coastguard Worker           UserMI->getOperand(j).setIndex(CPEs[i].CPI);
1094*9880d681SAndroid Build Coastguard Worker           break;
1095*9880d681SAndroid Build Coastguard Worker         }
1096*9880d681SAndroid Build Coastguard Worker       // Adjust the refcount of the clone...
1097*9880d681SAndroid Build Coastguard Worker       CPEs[i].RefCount++;
1098*9880d681SAndroid Build Coastguard Worker       // ...and the original.  If we didn't remove the old entry, none of the
1099*9880d681SAndroid Build Coastguard Worker       // addresses changed, so we don't need another pass.
1100*9880d681SAndroid Build Coastguard Worker       return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1101*9880d681SAndroid Build Coastguard Worker     }
1102*9880d681SAndroid Build Coastguard Worker   }
1103*9880d681SAndroid Build Coastguard Worker   return 0;
1104*9880d681SAndroid Build Coastguard Worker }
1105*9880d681SAndroid Build Coastguard Worker 
1106*9880d681SAndroid Build Coastguard Worker /// LookForCPEntryInRange - see if the currently referenced CPE is in range;
1107*9880d681SAndroid Build Coastguard Worker /// This version checks if the longer form of the instruction can be used to
1108*9880d681SAndroid Build Coastguard Worker /// to satisfy things.
1109*9880d681SAndroid Build Coastguard Worker /// if not, see if an in-range clone of the CPE is in range, and if so,
1110*9880d681SAndroid Build Coastguard Worker /// change the data structures so the user references the clone.  Returns:
1111*9880d681SAndroid Build Coastguard Worker /// 0 = no existing entry found
1112*9880d681SAndroid Build Coastguard Worker /// 1 = entry found, and there were no code insertions or deletions
1113*9880d681SAndroid Build Coastguard Worker /// 2 = entry found, and there were code insertions or deletions
findLongFormInRangeCPEntry(CPUser & U,unsigned UserOffset)1114*9880d681SAndroid Build Coastguard Worker int MipsConstantIslands::findLongFormInRangeCPEntry
1115*9880d681SAndroid Build Coastguard Worker   (CPUser& U, unsigned UserOffset)
1116*9880d681SAndroid Build Coastguard Worker {
1117*9880d681SAndroid Build Coastguard Worker   MachineInstr *UserMI = U.MI;
1118*9880d681SAndroid Build Coastguard Worker   MachineInstr *CPEMI  = U.CPEMI;
1119*9880d681SAndroid Build Coastguard Worker 
1120*9880d681SAndroid Build Coastguard Worker   // Check to see if the CPE is already in-range.
1121*9880d681SAndroid Build Coastguard Worker   if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
1122*9880d681SAndroid Build Coastguard Worker                        U.getLongFormMaxDisp(), U.NegOk,
1123*9880d681SAndroid Build Coastguard Worker                        true)) {
1124*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "In range\n");
1125*9880d681SAndroid Build Coastguard Worker     UserMI->setDesc(TII->get(U.getLongFormOpcode()));
1126*9880d681SAndroid Build Coastguard Worker     U.setMaxDisp(U.getLongFormMaxDisp());
1127*9880d681SAndroid Build Coastguard Worker     return 2;  // instruction is longer length now
1128*9880d681SAndroid Build Coastguard Worker   }
1129*9880d681SAndroid Build Coastguard Worker 
1130*9880d681SAndroid Build Coastguard Worker   // No.  Look for previously created clones of the CPE that are in range.
1131*9880d681SAndroid Build Coastguard Worker   unsigned CPI = CPEMI->getOperand(1).getIndex();
1132*9880d681SAndroid Build Coastguard Worker   std::vector<CPEntry> &CPEs = CPEntries[CPI];
1133*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = CPEs.size(); i != e; ++i) {
1134*9880d681SAndroid Build Coastguard Worker     // We already tried this one
1135*9880d681SAndroid Build Coastguard Worker     if (CPEs[i].CPEMI == CPEMI)
1136*9880d681SAndroid Build Coastguard Worker       continue;
1137*9880d681SAndroid Build Coastguard Worker     // Removing CPEs can leave empty entries, skip
1138*9880d681SAndroid Build Coastguard Worker     if (CPEs[i].CPEMI == nullptr)
1139*9880d681SAndroid Build Coastguard Worker       continue;
1140*9880d681SAndroid Build Coastguard Worker     if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI,
1141*9880d681SAndroid Build Coastguard Worker                          U.getLongFormMaxDisp(), U.NegOk)) {
1142*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#"
1143*9880d681SAndroid Build Coastguard Worker                    << CPEs[i].CPI << "\n");
1144*9880d681SAndroid Build Coastguard Worker       // Point the CPUser node to the replacement
1145*9880d681SAndroid Build Coastguard Worker       U.CPEMI = CPEs[i].CPEMI;
1146*9880d681SAndroid Build Coastguard Worker       // Change the CPI in the instruction operand to refer to the clone.
1147*9880d681SAndroid Build Coastguard Worker       for (unsigned j = 0, e = UserMI->getNumOperands(); j != e; ++j)
1148*9880d681SAndroid Build Coastguard Worker         if (UserMI->getOperand(j).isCPI()) {
1149*9880d681SAndroid Build Coastguard Worker           UserMI->getOperand(j).setIndex(CPEs[i].CPI);
1150*9880d681SAndroid Build Coastguard Worker           break;
1151*9880d681SAndroid Build Coastguard Worker         }
1152*9880d681SAndroid Build Coastguard Worker       // Adjust the refcount of the clone...
1153*9880d681SAndroid Build Coastguard Worker       CPEs[i].RefCount++;
1154*9880d681SAndroid Build Coastguard Worker       // ...and the original.  If we didn't remove the old entry, none of the
1155*9880d681SAndroid Build Coastguard Worker       // addresses changed, so we don't need another pass.
1156*9880d681SAndroid Build Coastguard Worker       return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1157*9880d681SAndroid Build Coastguard Worker     }
1158*9880d681SAndroid Build Coastguard Worker   }
1159*9880d681SAndroid Build Coastguard Worker   return 0;
1160*9880d681SAndroid Build Coastguard Worker }
1161*9880d681SAndroid Build Coastguard Worker 
1162*9880d681SAndroid Build Coastguard Worker /// getUnconditionalBrDisp - Returns the maximum displacement that can fit in
1163*9880d681SAndroid Build Coastguard Worker /// the specific unconditional branch instruction.
getUnconditionalBrDisp(int Opc)1164*9880d681SAndroid Build Coastguard Worker static inline unsigned getUnconditionalBrDisp(int Opc) {
1165*9880d681SAndroid Build Coastguard Worker   switch (Opc) {
1166*9880d681SAndroid Build Coastguard Worker   case Mips::Bimm16:
1167*9880d681SAndroid Build Coastguard Worker     return ((1<<10)-1)*2;
1168*9880d681SAndroid Build Coastguard Worker   case Mips::BimmX16:
1169*9880d681SAndroid Build Coastguard Worker     return ((1<<16)-1)*2;
1170*9880d681SAndroid Build Coastguard Worker   default:
1171*9880d681SAndroid Build Coastguard Worker     break;
1172*9880d681SAndroid Build Coastguard Worker   }
1173*9880d681SAndroid Build Coastguard Worker   return ((1<<16)-1)*2;
1174*9880d681SAndroid Build Coastguard Worker }
1175*9880d681SAndroid Build Coastguard Worker 
1176*9880d681SAndroid Build Coastguard Worker /// findAvailableWater - Look for an existing entry in the WaterList in which
1177*9880d681SAndroid Build Coastguard Worker /// we can place the CPE referenced from U so it's within range of U's MI.
1178*9880d681SAndroid Build Coastguard Worker /// Returns true if found, false if not.  If it returns true, WaterIter
1179*9880d681SAndroid Build Coastguard Worker /// is set to the WaterList entry.
1180*9880d681SAndroid Build Coastguard Worker /// To ensure that this pass
1181*9880d681SAndroid Build Coastguard Worker /// terminates, the CPE location for a particular CPUser is only allowed to
1182*9880d681SAndroid Build Coastguard Worker /// move to a lower address, so search backward from the end of the list and
1183*9880d681SAndroid Build Coastguard Worker /// prefer the first water that is in range.
findAvailableWater(CPUser & U,unsigned UserOffset,water_iterator & WaterIter)1184*9880d681SAndroid Build Coastguard Worker bool MipsConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset,
1185*9880d681SAndroid Build Coastguard Worker                                       water_iterator &WaterIter) {
1186*9880d681SAndroid Build Coastguard Worker   if (WaterList.empty())
1187*9880d681SAndroid Build Coastguard Worker     return false;
1188*9880d681SAndroid Build Coastguard Worker 
1189*9880d681SAndroid Build Coastguard Worker   unsigned BestGrowth = ~0u;
1190*9880d681SAndroid Build Coastguard Worker   for (water_iterator IP = std::prev(WaterList.end()), B = WaterList.begin();;
1191*9880d681SAndroid Build Coastguard Worker        --IP) {
1192*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock* WaterBB = *IP;
1193*9880d681SAndroid Build Coastguard Worker     // Check if water is in range and is either at a lower address than the
1194*9880d681SAndroid Build Coastguard Worker     // current "high water mark" or a new water block that was created since
1195*9880d681SAndroid Build Coastguard Worker     // the previous iteration by inserting an unconditional branch.  In the
1196*9880d681SAndroid Build Coastguard Worker     // latter case, we want to allow resetting the high water mark back to
1197*9880d681SAndroid Build Coastguard Worker     // this new water since we haven't seen it before.  Inserting branches
1198*9880d681SAndroid Build Coastguard Worker     // should be relatively uncommon and when it does happen, we want to be
1199*9880d681SAndroid Build Coastguard Worker     // sure to take advantage of it for all the CPEs near that block, so that
1200*9880d681SAndroid Build Coastguard Worker     // we don't insert more branches than necessary.
1201*9880d681SAndroid Build Coastguard Worker     unsigned Growth;
1202*9880d681SAndroid Build Coastguard Worker     if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
1203*9880d681SAndroid Build Coastguard Worker         (WaterBB->getNumber() < U.HighWaterMark->getNumber() ||
1204*9880d681SAndroid Build Coastguard Worker          NewWaterList.count(WaterBB)) && Growth < BestGrowth) {
1205*9880d681SAndroid Build Coastguard Worker       // This is the least amount of required padding seen so far.
1206*9880d681SAndroid Build Coastguard Worker       BestGrowth = Growth;
1207*9880d681SAndroid Build Coastguard Worker       WaterIter = IP;
1208*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << "Found water after BB#" << WaterBB->getNumber()
1209*9880d681SAndroid Build Coastguard Worker                    << " Growth=" << Growth << '\n');
1210*9880d681SAndroid Build Coastguard Worker 
1211*9880d681SAndroid Build Coastguard Worker       // Keep looking unless it is perfect.
1212*9880d681SAndroid Build Coastguard Worker       if (BestGrowth == 0)
1213*9880d681SAndroid Build Coastguard Worker         return true;
1214*9880d681SAndroid Build Coastguard Worker     }
1215*9880d681SAndroid Build Coastguard Worker     if (IP == B)
1216*9880d681SAndroid Build Coastguard Worker       break;
1217*9880d681SAndroid Build Coastguard Worker   }
1218*9880d681SAndroid Build Coastguard Worker   return BestGrowth != ~0u;
1219*9880d681SAndroid Build Coastguard Worker }
1220*9880d681SAndroid Build Coastguard Worker 
1221*9880d681SAndroid Build Coastguard Worker /// createNewWater - No existing WaterList entry will work for
1222*9880d681SAndroid Build Coastguard Worker /// CPUsers[CPUserIndex], so create a place to put the CPE.  The end of the
1223*9880d681SAndroid Build Coastguard Worker /// block is used if in range, and the conditional branch munged so control
1224*9880d681SAndroid Build Coastguard Worker /// flow is correct.  Otherwise the block is split to create a hole with an
1225*9880d681SAndroid Build Coastguard Worker /// unconditional branch around it.  In either case NewMBB is set to a
1226*9880d681SAndroid Build Coastguard Worker /// block following which the new island can be inserted (the WaterList
1227*9880d681SAndroid Build Coastguard Worker /// is not adjusted).
createNewWater(unsigned CPUserIndex,unsigned UserOffset,MachineBasicBlock * & NewMBB)1228*9880d681SAndroid Build Coastguard Worker void MipsConstantIslands::createNewWater(unsigned CPUserIndex,
1229*9880d681SAndroid Build Coastguard Worker                                         unsigned UserOffset,
1230*9880d681SAndroid Build Coastguard Worker                                         MachineBasicBlock *&NewMBB) {
1231*9880d681SAndroid Build Coastguard Worker   CPUser &U = CPUsers[CPUserIndex];
1232*9880d681SAndroid Build Coastguard Worker   MachineInstr *UserMI = U.MI;
1233*9880d681SAndroid Build Coastguard Worker   MachineInstr *CPEMI  = U.CPEMI;
1234*9880d681SAndroid Build Coastguard Worker   unsigned CPELogAlign = getCPELogAlign(*CPEMI);
1235*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *UserMBB = UserMI->getParent();
1236*9880d681SAndroid Build Coastguard Worker   const BasicBlockInfo &UserBBI = BBInfo[UserMBB->getNumber()];
1237*9880d681SAndroid Build Coastguard Worker 
1238*9880d681SAndroid Build Coastguard Worker   // If the block does not end in an unconditional branch already, and if the
1239*9880d681SAndroid Build Coastguard Worker   // end of the block is within range, make new water there.
1240*9880d681SAndroid Build Coastguard Worker   if (BBHasFallthrough(UserMBB)) {
1241*9880d681SAndroid Build Coastguard Worker     // Size of branch to insert.
1242*9880d681SAndroid Build Coastguard Worker     unsigned Delta = 2;
1243*9880d681SAndroid Build Coastguard Worker     // Compute the offset where the CPE will begin.
1244*9880d681SAndroid Build Coastguard Worker     unsigned CPEOffset = UserBBI.postOffset(CPELogAlign) + Delta;
1245*9880d681SAndroid Build Coastguard Worker 
1246*9880d681SAndroid Build Coastguard Worker     if (isOffsetInRange(UserOffset, CPEOffset, U)) {
1247*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << "Split at end of BB#" << UserMBB->getNumber()
1248*9880d681SAndroid Build Coastguard Worker             << format(", expected CPE offset %#x\n", CPEOffset));
1249*9880d681SAndroid Build Coastguard Worker       NewMBB = &*++UserMBB->getIterator();
1250*9880d681SAndroid Build Coastguard Worker       // Add an unconditional branch from UserMBB to fallthrough block.  Record
1251*9880d681SAndroid Build Coastguard Worker       // it for branch lengthening; this new branch will not get out of range,
1252*9880d681SAndroid Build Coastguard Worker       // but if the preceding conditional branch is out of range, the targets
1253*9880d681SAndroid Build Coastguard Worker       // will be exchanged, and the altered branch may be out of range, so the
1254*9880d681SAndroid Build Coastguard Worker       // machinery has to know about it.
1255*9880d681SAndroid Build Coastguard Worker       int UncondBr = Mips::Bimm16;
1256*9880d681SAndroid Build Coastguard Worker       BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB);
1257*9880d681SAndroid Build Coastguard Worker       unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
1258*9880d681SAndroid Build Coastguard Worker       ImmBranches.push_back(ImmBranch(&UserMBB->back(),
1259*9880d681SAndroid Build Coastguard Worker                                       MaxDisp, false, UncondBr));
1260*9880d681SAndroid Build Coastguard Worker       BBInfo[UserMBB->getNumber()].Size += Delta;
1261*9880d681SAndroid Build Coastguard Worker       adjustBBOffsetsAfter(UserMBB);
1262*9880d681SAndroid Build Coastguard Worker       return;
1263*9880d681SAndroid Build Coastguard Worker     }
1264*9880d681SAndroid Build Coastguard Worker   }
1265*9880d681SAndroid Build Coastguard Worker 
1266*9880d681SAndroid Build Coastguard Worker   // What a big block.  Find a place within the block to split it.
1267*9880d681SAndroid Build Coastguard Worker 
1268*9880d681SAndroid Build Coastguard Worker   // Try to split the block so it's fully aligned.  Compute the latest split
1269*9880d681SAndroid Build Coastguard Worker   // point where we can add a 4-byte branch instruction, and then align to
1270*9880d681SAndroid Build Coastguard Worker   // LogAlign which is the largest possible alignment in the function.
1271*9880d681SAndroid Build Coastguard Worker   unsigned LogAlign = MF->getAlignment();
1272*9880d681SAndroid Build Coastguard Worker   assert(LogAlign >= CPELogAlign && "Over-aligned constant pool entry");
1273*9880d681SAndroid Build Coastguard Worker   unsigned BaseInsertOffset = UserOffset + U.getMaxDisp();
1274*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << format("Split in middle of big block before %#x",
1275*9880d681SAndroid Build Coastguard Worker                          BaseInsertOffset));
1276*9880d681SAndroid Build Coastguard Worker 
1277*9880d681SAndroid Build Coastguard Worker   // The 4 in the following is for the unconditional branch we'll be inserting
1278*9880d681SAndroid Build Coastguard Worker   // Alignment of the island is handled
1279*9880d681SAndroid Build Coastguard Worker   // inside isOffsetInRange.
1280*9880d681SAndroid Build Coastguard Worker   BaseInsertOffset -= 4;
1281*9880d681SAndroid Build Coastguard Worker 
1282*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << format(", adjusted to %#x", BaseInsertOffset)
1283*9880d681SAndroid Build Coastguard Worker                << " la=" << LogAlign << '\n');
1284*9880d681SAndroid Build Coastguard Worker 
1285*9880d681SAndroid Build Coastguard Worker   // This could point off the end of the block if we've already got constant
1286*9880d681SAndroid Build Coastguard Worker   // pool entries following this block; only the last one is in the water list.
1287*9880d681SAndroid Build Coastguard Worker   // Back past any possible branches (allow for a conditional and a maximally
1288*9880d681SAndroid Build Coastguard Worker   // long unconditional).
1289*9880d681SAndroid Build Coastguard Worker   if (BaseInsertOffset + 8 >= UserBBI.postOffset()) {
1290*9880d681SAndroid Build Coastguard Worker     BaseInsertOffset = UserBBI.postOffset() - 8;
1291*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << format("Move inside block: %#x\n", BaseInsertOffset));
1292*9880d681SAndroid Build Coastguard Worker   }
1293*9880d681SAndroid Build Coastguard Worker   unsigned EndInsertOffset = BaseInsertOffset + 4 +
1294*9880d681SAndroid Build Coastguard Worker     CPEMI->getOperand(2).getImm();
1295*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator MI = UserMI;
1296*9880d681SAndroid Build Coastguard Worker   ++MI;
1297*9880d681SAndroid Build Coastguard Worker   unsigned CPUIndex = CPUserIndex+1;
1298*9880d681SAndroid Build Coastguard Worker   unsigned NumCPUsers = CPUsers.size();
1299*9880d681SAndroid Build Coastguard Worker   //MachineInstr *LastIT = 0;
1300*9880d681SAndroid Build Coastguard Worker   for (unsigned Offset = UserOffset + TII->GetInstSizeInBytes(*UserMI);
1301*9880d681SAndroid Build Coastguard Worker        Offset < BaseInsertOffset;
1302*9880d681SAndroid Build Coastguard Worker        Offset += TII->GetInstSizeInBytes(*MI), MI = std::next(MI)) {
1303*9880d681SAndroid Build Coastguard Worker     assert(MI != UserMBB->end() && "Fell off end of block");
1304*9880d681SAndroid Build Coastguard Worker     if (CPUIndex < NumCPUsers &&
1305*9880d681SAndroid Build Coastguard Worker         CPUsers[CPUIndex].MI == static_cast<MachineInstr *>(MI)) {
1306*9880d681SAndroid Build Coastguard Worker       CPUser &U = CPUsers[CPUIndex];
1307*9880d681SAndroid Build Coastguard Worker       if (!isOffsetInRange(Offset, EndInsertOffset, U)) {
1308*9880d681SAndroid Build Coastguard Worker         // Shift intertion point by one unit of alignment so it is within reach.
1309*9880d681SAndroid Build Coastguard Worker         BaseInsertOffset -= 1u << LogAlign;
1310*9880d681SAndroid Build Coastguard Worker         EndInsertOffset  -= 1u << LogAlign;
1311*9880d681SAndroid Build Coastguard Worker       }
1312*9880d681SAndroid Build Coastguard Worker       // This is overly conservative, as we don't account for CPEMIs being
1313*9880d681SAndroid Build Coastguard Worker       // reused within the block, but it doesn't matter much.  Also assume CPEs
1314*9880d681SAndroid Build Coastguard Worker       // are added in order with alignment padding.  We may eventually be able
1315*9880d681SAndroid Build Coastguard Worker       // to pack the aligned CPEs better.
1316*9880d681SAndroid Build Coastguard Worker       EndInsertOffset += U.CPEMI->getOperand(2).getImm();
1317*9880d681SAndroid Build Coastguard Worker       CPUIndex++;
1318*9880d681SAndroid Build Coastguard Worker     }
1319*9880d681SAndroid Build Coastguard Worker   }
1320*9880d681SAndroid Build Coastguard Worker 
1321*9880d681SAndroid Build Coastguard Worker   NewMBB = splitBlockBeforeInstr(*--MI);
1322*9880d681SAndroid Build Coastguard Worker }
1323*9880d681SAndroid Build Coastguard Worker 
1324*9880d681SAndroid Build Coastguard Worker /// handleConstantPoolUser - Analyze the specified user, checking to see if it
1325*9880d681SAndroid Build Coastguard Worker /// is out-of-range.  If so, pick up the constant pool value and move it some
1326*9880d681SAndroid Build Coastguard Worker /// place in-range.  Return true if we changed any addresses (thus must run
1327*9880d681SAndroid Build Coastguard Worker /// another pass of branch lengthening), false otherwise.
handleConstantPoolUser(unsigned CPUserIndex)1328*9880d681SAndroid Build Coastguard Worker bool MipsConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) {
1329*9880d681SAndroid Build Coastguard Worker   CPUser &U = CPUsers[CPUserIndex];
1330*9880d681SAndroid Build Coastguard Worker   MachineInstr *UserMI = U.MI;
1331*9880d681SAndroid Build Coastguard Worker   MachineInstr *CPEMI  = U.CPEMI;
1332*9880d681SAndroid Build Coastguard Worker   unsigned CPI = CPEMI->getOperand(1).getIndex();
1333*9880d681SAndroid Build Coastguard Worker   unsigned Size = CPEMI->getOperand(2).getImm();
1334*9880d681SAndroid Build Coastguard Worker   // Compute this only once, it's expensive.
1335*9880d681SAndroid Build Coastguard Worker   unsigned UserOffset = getUserOffset(U);
1336*9880d681SAndroid Build Coastguard Worker 
1337*9880d681SAndroid Build Coastguard Worker   // See if the current entry is within range, or there is a clone of it
1338*9880d681SAndroid Build Coastguard Worker   // in range.
1339*9880d681SAndroid Build Coastguard Worker   int result = findInRangeCPEntry(U, UserOffset);
1340*9880d681SAndroid Build Coastguard Worker   if (result==1) return false;
1341*9880d681SAndroid Build Coastguard Worker   else if (result==2) return true;
1342*9880d681SAndroid Build Coastguard Worker 
1343*9880d681SAndroid Build Coastguard Worker 
1344*9880d681SAndroid Build Coastguard Worker   // Look for water where we can place this CPE.
1345*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock();
1346*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *NewMBB;
1347*9880d681SAndroid Build Coastguard Worker   water_iterator IP;
1348*9880d681SAndroid Build Coastguard Worker   if (findAvailableWater(U, UserOffset, IP)) {
1349*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Found water in range\n");
1350*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *WaterBB = *IP;
1351*9880d681SAndroid Build Coastguard Worker 
1352*9880d681SAndroid Build Coastguard Worker     // If the original WaterList entry was "new water" on this iteration,
1353*9880d681SAndroid Build Coastguard Worker     // propagate that to the new island.  This is just keeping NewWaterList
1354*9880d681SAndroid Build Coastguard Worker     // updated to match the WaterList, which will be updated below.
1355*9880d681SAndroid Build Coastguard Worker     if (NewWaterList.erase(WaterBB))
1356*9880d681SAndroid Build Coastguard Worker       NewWaterList.insert(NewIsland);
1357*9880d681SAndroid Build Coastguard Worker 
1358*9880d681SAndroid Build Coastguard Worker     // The new CPE goes before the following block (NewMBB).
1359*9880d681SAndroid Build Coastguard Worker     NewMBB = &*++WaterBB->getIterator();
1360*9880d681SAndroid Build Coastguard Worker   } else {
1361*9880d681SAndroid Build Coastguard Worker     // No water found.
1362*9880d681SAndroid Build Coastguard Worker     // we first see if a longer form of the instrucion could have reached
1363*9880d681SAndroid Build Coastguard Worker     // the constant. in that case we won't bother to split
1364*9880d681SAndroid Build Coastguard Worker     if (!NoLoadRelaxation) {
1365*9880d681SAndroid Build Coastguard Worker       result = findLongFormInRangeCPEntry(U, UserOffset);
1366*9880d681SAndroid Build Coastguard Worker       if (result != 0) return true;
1367*9880d681SAndroid Build Coastguard Worker     }
1368*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "No water found\n");
1369*9880d681SAndroid Build Coastguard Worker     createNewWater(CPUserIndex, UserOffset, NewMBB);
1370*9880d681SAndroid Build Coastguard Worker 
1371*9880d681SAndroid Build Coastguard Worker     // splitBlockBeforeInstr adds to WaterList, which is important when it is
1372*9880d681SAndroid Build Coastguard Worker     // called while handling branches so that the water will be seen on the
1373*9880d681SAndroid Build Coastguard Worker     // next iteration for constant pools, but in this context, we don't want
1374*9880d681SAndroid Build Coastguard Worker     // it.  Check for this so it will be removed from the WaterList.
1375*9880d681SAndroid Build Coastguard Worker     // Also remove any entry from NewWaterList.
1376*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *WaterBB = &*--NewMBB->getIterator();
1377*9880d681SAndroid Build Coastguard Worker     IP = std::find(WaterList.begin(), WaterList.end(), WaterBB);
1378*9880d681SAndroid Build Coastguard Worker     if (IP != WaterList.end())
1379*9880d681SAndroid Build Coastguard Worker       NewWaterList.erase(WaterBB);
1380*9880d681SAndroid Build Coastguard Worker 
1381*9880d681SAndroid Build Coastguard Worker     // We are adding new water.  Update NewWaterList.
1382*9880d681SAndroid Build Coastguard Worker     NewWaterList.insert(NewIsland);
1383*9880d681SAndroid Build Coastguard Worker   }
1384*9880d681SAndroid Build Coastguard Worker 
1385*9880d681SAndroid Build Coastguard Worker   // Remove the original WaterList entry; we want subsequent insertions in
1386*9880d681SAndroid Build Coastguard Worker   // this vicinity to go after the one we're about to insert.  This
1387*9880d681SAndroid Build Coastguard Worker   // considerably reduces the number of times we have to move the same CPE
1388*9880d681SAndroid Build Coastguard Worker   // more than once and is also important to ensure the algorithm terminates.
1389*9880d681SAndroid Build Coastguard Worker   if (IP != WaterList.end())
1390*9880d681SAndroid Build Coastguard Worker     WaterList.erase(IP);
1391*9880d681SAndroid Build Coastguard Worker 
1392*9880d681SAndroid Build Coastguard Worker   // Okay, we know we can put an island before NewMBB now, do it!
1393*9880d681SAndroid Build Coastguard Worker   MF->insert(NewMBB->getIterator(), NewIsland);
1394*9880d681SAndroid Build Coastguard Worker 
1395*9880d681SAndroid Build Coastguard Worker   // Update internal data structures to account for the newly inserted MBB.
1396*9880d681SAndroid Build Coastguard Worker   updateForInsertedWaterBlock(NewIsland);
1397*9880d681SAndroid Build Coastguard Worker 
1398*9880d681SAndroid Build Coastguard Worker   // Decrement the old entry, and remove it if refcount becomes 0.
1399*9880d681SAndroid Build Coastguard Worker   decrementCPEReferenceCount(CPI, CPEMI);
1400*9880d681SAndroid Build Coastguard Worker 
1401*9880d681SAndroid Build Coastguard Worker   // No existing clone of this CPE is within range.
1402*9880d681SAndroid Build Coastguard Worker   // We will be generating a new clone.  Get a UID for it.
1403*9880d681SAndroid Build Coastguard Worker   unsigned ID = createPICLabelUId();
1404*9880d681SAndroid Build Coastguard Worker 
1405*9880d681SAndroid Build Coastguard Worker   // Now that we have an island to add the CPE to, clone the original CPE and
1406*9880d681SAndroid Build Coastguard Worker   // add it to the island.
1407*9880d681SAndroid Build Coastguard Worker   U.HighWaterMark = NewIsland;
1408*9880d681SAndroid Build Coastguard Worker   U.CPEMI = BuildMI(NewIsland, DebugLoc(), TII->get(Mips::CONSTPOOL_ENTRY))
1409*9880d681SAndroid Build Coastguard Worker                 .addImm(ID).addConstantPoolIndex(CPI).addImm(Size);
1410*9880d681SAndroid Build Coastguard Worker   CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));
1411*9880d681SAndroid Build Coastguard Worker   ++NumCPEs;
1412*9880d681SAndroid Build Coastguard Worker 
1413*9880d681SAndroid Build Coastguard Worker   // Mark the basic block as aligned as required by the const-pool entry.
1414*9880d681SAndroid Build Coastguard Worker   NewIsland->setAlignment(getCPELogAlign(*U.CPEMI));
1415*9880d681SAndroid Build Coastguard Worker 
1416*9880d681SAndroid Build Coastguard Worker   // Increase the size of the island block to account for the new entry.
1417*9880d681SAndroid Build Coastguard Worker   BBInfo[NewIsland->getNumber()].Size += Size;
1418*9880d681SAndroid Build Coastguard Worker   adjustBBOffsetsAfter(&*--NewIsland->getIterator());
1419*9880d681SAndroid Build Coastguard Worker 
1420*9880d681SAndroid Build Coastguard Worker   // Finally, change the CPI in the instruction operand to be ID.
1421*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = UserMI->getNumOperands(); i != e; ++i)
1422*9880d681SAndroid Build Coastguard Worker     if (UserMI->getOperand(i).isCPI()) {
1423*9880d681SAndroid Build Coastguard Worker       UserMI->getOperand(i).setIndex(ID);
1424*9880d681SAndroid Build Coastguard Worker       break;
1425*9880d681SAndroid Build Coastguard Worker     }
1426*9880d681SAndroid Build Coastguard Worker 
1427*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "  Moved CPE to #" << ID << " CPI=" << CPI
1428*9880d681SAndroid Build Coastguard Worker         << format(" offset=%#x\n", BBInfo[NewIsland->getNumber()].Offset));
1429*9880d681SAndroid Build Coastguard Worker 
1430*9880d681SAndroid Build Coastguard Worker   return true;
1431*9880d681SAndroid Build Coastguard Worker }
1432*9880d681SAndroid Build Coastguard Worker 
1433*9880d681SAndroid Build Coastguard Worker /// removeDeadCPEMI - Remove a dead constant pool entry instruction. Update
1434*9880d681SAndroid Build Coastguard Worker /// sizes and offsets of impacted basic blocks.
removeDeadCPEMI(MachineInstr * CPEMI)1435*9880d681SAndroid Build Coastguard Worker void MipsConstantIslands::removeDeadCPEMI(MachineInstr *CPEMI) {
1436*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *CPEBB = CPEMI->getParent();
1437*9880d681SAndroid Build Coastguard Worker   unsigned Size = CPEMI->getOperand(2).getImm();
1438*9880d681SAndroid Build Coastguard Worker   CPEMI->eraseFromParent();
1439*9880d681SAndroid Build Coastguard Worker   BBInfo[CPEBB->getNumber()].Size -= Size;
1440*9880d681SAndroid Build Coastguard Worker   // All succeeding offsets have the current size value added in, fix this.
1441*9880d681SAndroid Build Coastguard Worker   if (CPEBB->empty()) {
1442*9880d681SAndroid Build Coastguard Worker     BBInfo[CPEBB->getNumber()].Size = 0;
1443*9880d681SAndroid Build Coastguard Worker 
1444*9880d681SAndroid Build Coastguard Worker     // This block no longer needs to be aligned.
1445*9880d681SAndroid Build Coastguard Worker     CPEBB->setAlignment(0);
1446*9880d681SAndroid Build Coastguard Worker   } else
1447*9880d681SAndroid Build Coastguard Worker     // Entries are sorted by descending alignment, so realign from the front.
1448*9880d681SAndroid Build Coastguard Worker     CPEBB->setAlignment(getCPELogAlign(*CPEBB->begin()));
1449*9880d681SAndroid Build Coastguard Worker 
1450*9880d681SAndroid Build Coastguard Worker   adjustBBOffsetsAfter(CPEBB);
1451*9880d681SAndroid Build Coastguard Worker   // An island has only one predecessor BB and one successor BB. Check if
1452*9880d681SAndroid Build Coastguard Worker   // this BB's predecessor jumps directly to this BB's successor. This
1453*9880d681SAndroid Build Coastguard Worker   // shouldn't happen currently.
1454*9880d681SAndroid Build Coastguard Worker   assert(!BBIsJumpedOver(CPEBB) && "How did this happen?");
1455*9880d681SAndroid Build Coastguard Worker   // FIXME: remove the empty blocks after all the work is done?
1456*9880d681SAndroid Build Coastguard Worker }
1457*9880d681SAndroid Build Coastguard Worker 
1458*9880d681SAndroid Build Coastguard Worker /// removeUnusedCPEntries - Remove constant pool entries whose refcounts
1459*9880d681SAndroid Build Coastguard Worker /// are zero.
removeUnusedCPEntries()1460*9880d681SAndroid Build Coastguard Worker bool MipsConstantIslands::removeUnusedCPEntries() {
1461*9880d681SAndroid Build Coastguard Worker   unsigned MadeChange = false;
1462*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = CPEntries.size(); i != e; ++i) {
1463*9880d681SAndroid Build Coastguard Worker       std::vector<CPEntry> &CPEs = CPEntries[i];
1464*9880d681SAndroid Build Coastguard Worker       for (unsigned j = 0, ee = CPEs.size(); j != ee; ++j) {
1465*9880d681SAndroid Build Coastguard Worker         if (CPEs[j].RefCount == 0 && CPEs[j].CPEMI) {
1466*9880d681SAndroid Build Coastguard Worker           removeDeadCPEMI(CPEs[j].CPEMI);
1467*9880d681SAndroid Build Coastguard Worker           CPEs[j].CPEMI = nullptr;
1468*9880d681SAndroid Build Coastguard Worker           MadeChange = true;
1469*9880d681SAndroid Build Coastguard Worker         }
1470*9880d681SAndroid Build Coastguard Worker       }
1471*9880d681SAndroid Build Coastguard Worker   }
1472*9880d681SAndroid Build Coastguard Worker   return MadeChange;
1473*9880d681SAndroid Build Coastguard Worker }
1474*9880d681SAndroid Build Coastguard Worker 
1475*9880d681SAndroid Build Coastguard Worker /// isBBInRange - Returns true if the distance between specific MI and
1476*9880d681SAndroid Build Coastguard Worker /// specific BB can fit in MI's displacement field.
isBBInRange(MachineInstr * MI,MachineBasicBlock * DestBB,unsigned MaxDisp)1477*9880d681SAndroid Build Coastguard Worker bool MipsConstantIslands::isBBInRange
1478*9880d681SAndroid Build Coastguard Worker   (MachineInstr *MI,MachineBasicBlock *DestBB, unsigned MaxDisp) {
1479*9880d681SAndroid Build Coastguard Worker 
1480*9880d681SAndroid Build Coastguard Worker unsigned PCAdj = 4;
1481*9880d681SAndroid Build Coastguard Worker 
1482*9880d681SAndroid Build Coastguard Worker   unsigned BrOffset   = getOffsetOf(MI) + PCAdj;
1483*9880d681SAndroid Build Coastguard Worker   unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
1484*9880d681SAndroid Build Coastguard Worker 
1485*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Branch of destination BB#" << DestBB->getNumber()
1486*9880d681SAndroid Build Coastguard Worker                << " from BB#" << MI->getParent()->getNumber()
1487*9880d681SAndroid Build Coastguard Worker                << " max delta=" << MaxDisp
1488*9880d681SAndroid Build Coastguard Worker                << " from " << getOffsetOf(MI) << " to " << DestOffset
1489*9880d681SAndroid Build Coastguard Worker                << " offset " << int(DestOffset-BrOffset) << "\t" << *MI);
1490*9880d681SAndroid Build Coastguard Worker 
1491*9880d681SAndroid Build Coastguard Worker   if (BrOffset <= DestOffset) {
1492*9880d681SAndroid Build Coastguard Worker     // Branch before the Dest.
1493*9880d681SAndroid Build Coastguard Worker     if (DestOffset-BrOffset <= MaxDisp)
1494*9880d681SAndroid Build Coastguard Worker       return true;
1495*9880d681SAndroid Build Coastguard Worker   } else {
1496*9880d681SAndroid Build Coastguard Worker     if (BrOffset-DestOffset <= MaxDisp)
1497*9880d681SAndroid Build Coastguard Worker       return true;
1498*9880d681SAndroid Build Coastguard Worker   }
1499*9880d681SAndroid Build Coastguard Worker   return false;
1500*9880d681SAndroid Build Coastguard Worker }
1501*9880d681SAndroid Build Coastguard Worker 
1502*9880d681SAndroid Build Coastguard Worker /// fixupImmediateBr - Fix up an immediate branch whose destination is too far
1503*9880d681SAndroid Build Coastguard Worker /// away to fit in its displacement field.
fixupImmediateBr(ImmBranch & Br)1504*9880d681SAndroid Build Coastguard Worker bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {
1505*9880d681SAndroid Build Coastguard Worker   MachineInstr *MI = Br.MI;
1506*9880d681SAndroid Build Coastguard Worker   unsigned TargetOperand = branchTargetOperand(MI);
1507*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *DestBB = MI->getOperand(TargetOperand).getMBB();
1508*9880d681SAndroid Build Coastguard Worker 
1509*9880d681SAndroid Build Coastguard Worker   // Check to see if the DestBB is already in-range.
1510*9880d681SAndroid Build Coastguard Worker   if (isBBInRange(MI, DestBB, Br.MaxDisp))
1511*9880d681SAndroid Build Coastguard Worker     return false;
1512*9880d681SAndroid Build Coastguard Worker 
1513*9880d681SAndroid Build Coastguard Worker   if (!Br.isCond)
1514*9880d681SAndroid Build Coastguard Worker     return fixupUnconditionalBr(Br);
1515*9880d681SAndroid Build Coastguard Worker   return fixupConditionalBr(Br);
1516*9880d681SAndroid Build Coastguard Worker }
1517*9880d681SAndroid Build Coastguard Worker 
1518*9880d681SAndroid Build Coastguard Worker /// fixupUnconditionalBr - Fix up an unconditional branch whose destination is
1519*9880d681SAndroid Build Coastguard Worker /// too far away to fit in its displacement field. If the LR register has been
1520*9880d681SAndroid Build Coastguard Worker /// spilled in the epilogue, then we can use BL to implement a far jump.
1521*9880d681SAndroid Build Coastguard Worker /// Otherwise, add an intermediate branch instruction to a branch.
1522*9880d681SAndroid Build Coastguard Worker bool
fixupUnconditionalBr(ImmBranch & Br)1523*9880d681SAndroid Build Coastguard Worker MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
1524*9880d681SAndroid Build Coastguard Worker   MachineInstr *MI = Br.MI;
1525*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *MBB = MI->getParent();
1526*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();
1527*9880d681SAndroid Build Coastguard Worker   // Use BL to implement far jump.
1528*9880d681SAndroid Build Coastguard Worker   unsigned BimmX16MaxDisp = ((1 << 16)-1) * 2;
1529*9880d681SAndroid Build Coastguard Worker   if (isBBInRange(MI, DestBB, BimmX16MaxDisp)) {
1530*9880d681SAndroid Build Coastguard Worker     Br.MaxDisp = BimmX16MaxDisp;
1531*9880d681SAndroid Build Coastguard Worker     MI->setDesc(TII->get(Mips::BimmX16));
1532*9880d681SAndroid Build Coastguard Worker   }
1533*9880d681SAndroid Build Coastguard Worker   else {
1534*9880d681SAndroid Build Coastguard Worker     // need to give the math a more careful look here
1535*9880d681SAndroid Build Coastguard Worker     // this is really a segment address and not
1536*9880d681SAndroid Build Coastguard Worker     // a PC relative address. FIXME. But I think that
1537*9880d681SAndroid Build Coastguard Worker     // just reducing the bits by 1 as I've done is correct.
1538*9880d681SAndroid Build Coastguard Worker     // The basic block we are branching too much be longword aligned.
1539*9880d681SAndroid Build Coastguard Worker     // we know that RA is saved because we always save it right now.
1540*9880d681SAndroid Build Coastguard Worker     // this requirement will be relaxed later but we also have an alternate
1541*9880d681SAndroid Build Coastguard Worker     // way to implement this that I will implement that does not need jal.
1542*9880d681SAndroid Build Coastguard Worker     // We should have a way to back out this alignment restriction if we "can" later.
1543*9880d681SAndroid Build Coastguard Worker     // but it is not harmful.
1544*9880d681SAndroid Build Coastguard Worker     //
1545*9880d681SAndroid Build Coastguard Worker     DestBB->setAlignment(2);
1546*9880d681SAndroid Build Coastguard Worker     Br.MaxDisp = ((1<<24)-1) * 2;
1547*9880d681SAndroid Build Coastguard Worker     MI->setDesc(TII->get(Mips::JalB16));
1548*9880d681SAndroid Build Coastguard Worker   }
1549*9880d681SAndroid Build Coastguard Worker   BBInfo[MBB->getNumber()].Size += 2;
1550*9880d681SAndroid Build Coastguard Worker   adjustBBOffsetsAfter(MBB);
1551*9880d681SAndroid Build Coastguard Worker   HasFarJump = true;
1552*9880d681SAndroid Build Coastguard Worker   ++NumUBrFixed;
1553*9880d681SAndroid Build Coastguard Worker 
1554*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "  Changed B to long jump " << *MI);
1555*9880d681SAndroid Build Coastguard Worker 
1556*9880d681SAndroid Build Coastguard Worker   return true;
1557*9880d681SAndroid Build Coastguard Worker }
1558*9880d681SAndroid Build Coastguard Worker 
1559*9880d681SAndroid Build Coastguard Worker 
1560*9880d681SAndroid Build Coastguard Worker /// fixupConditionalBr - Fix up a conditional branch whose destination is too
1561*9880d681SAndroid Build Coastguard Worker /// far away to fit in its displacement field. It is converted to an inverse
1562*9880d681SAndroid Build Coastguard Worker /// conditional branch + an unconditional branch to the destination.
1563*9880d681SAndroid Build Coastguard Worker bool
fixupConditionalBr(ImmBranch & Br)1564*9880d681SAndroid Build Coastguard Worker MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
1565*9880d681SAndroid Build Coastguard Worker   MachineInstr *MI = Br.MI;
1566*9880d681SAndroid Build Coastguard Worker   unsigned TargetOperand = branchTargetOperand(MI);
1567*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *DestBB = MI->getOperand(TargetOperand).getMBB();
1568*9880d681SAndroid Build Coastguard Worker   unsigned Opcode = MI->getOpcode();
1569*9880d681SAndroid Build Coastguard Worker   unsigned LongFormOpcode = longformBranchOpcode(Opcode);
1570*9880d681SAndroid Build Coastguard Worker   unsigned LongFormMaxOff = branchMaxOffsets(LongFormOpcode);
1571*9880d681SAndroid Build Coastguard Worker 
1572*9880d681SAndroid Build Coastguard Worker   // Check to see if the DestBB is already in-range.
1573*9880d681SAndroid Build Coastguard Worker   if (isBBInRange(MI, DestBB, LongFormMaxOff)) {
1574*9880d681SAndroid Build Coastguard Worker     Br.MaxDisp = LongFormMaxOff;
1575*9880d681SAndroid Build Coastguard Worker     MI->setDesc(TII->get(LongFormOpcode));
1576*9880d681SAndroid Build Coastguard Worker     return true;
1577*9880d681SAndroid Build Coastguard Worker   }
1578*9880d681SAndroid Build Coastguard Worker 
1579*9880d681SAndroid Build Coastguard Worker   // Add an unconditional branch to the destination and invert the branch
1580*9880d681SAndroid Build Coastguard Worker   // condition to jump over it:
1581*9880d681SAndroid Build Coastguard Worker   // bteqz L1
1582*9880d681SAndroid Build Coastguard Worker   // =>
1583*9880d681SAndroid Build Coastguard Worker   // bnez L2
1584*9880d681SAndroid Build Coastguard Worker   // b   L1
1585*9880d681SAndroid Build Coastguard Worker   // L2:
1586*9880d681SAndroid Build Coastguard Worker 
1587*9880d681SAndroid Build Coastguard Worker   // If the branch is at the end of its MBB and that has a fall-through block,
1588*9880d681SAndroid Build Coastguard Worker   // direct the updated conditional branch to the fall-through block. Otherwise,
1589*9880d681SAndroid Build Coastguard Worker   // split the MBB before the next instruction.
1590*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *MBB = MI->getParent();
1591*9880d681SAndroid Build Coastguard Worker   MachineInstr *BMI = &MBB->back();
1592*9880d681SAndroid Build Coastguard Worker   bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB);
1593*9880d681SAndroid Build Coastguard Worker   unsigned OppositeBranchOpcode = TII->getOppositeBranchOpc(Opcode);
1594*9880d681SAndroid Build Coastguard Worker 
1595*9880d681SAndroid Build Coastguard Worker   ++NumCBrFixed;
1596*9880d681SAndroid Build Coastguard Worker   if (BMI != MI) {
1597*9880d681SAndroid Build Coastguard Worker     if (std::next(MachineBasicBlock::iterator(MI)) == std::prev(MBB->end()) &&
1598*9880d681SAndroid Build Coastguard Worker         BMI->isUnconditionalBranch()) {
1599*9880d681SAndroid Build Coastguard Worker       // Last MI in the BB is an unconditional branch. Can we simply invert the
1600*9880d681SAndroid Build Coastguard Worker       // condition and swap destinations:
1601*9880d681SAndroid Build Coastguard Worker       // beqz L1
1602*9880d681SAndroid Build Coastguard Worker       // b   L2
1603*9880d681SAndroid Build Coastguard Worker       // =>
1604*9880d681SAndroid Build Coastguard Worker       // bnez L2
1605*9880d681SAndroid Build Coastguard Worker       // b   L1
1606*9880d681SAndroid Build Coastguard Worker       unsigned BMITargetOperand = branchTargetOperand(BMI);
1607*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock *NewDest =
1608*9880d681SAndroid Build Coastguard Worker         BMI->getOperand(BMITargetOperand).getMBB();
1609*9880d681SAndroid Build Coastguard Worker       if (isBBInRange(MI, NewDest, Br.MaxDisp)) {
1610*9880d681SAndroid Build Coastguard Worker         DEBUG(dbgs() << "  Invert Bcc condition and swap its destination with "
1611*9880d681SAndroid Build Coastguard Worker                      << *BMI);
1612*9880d681SAndroid Build Coastguard Worker         MI->setDesc(TII->get(OppositeBranchOpcode));
1613*9880d681SAndroid Build Coastguard Worker         BMI->getOperand(BMITargetOperand).setMBB(DestBB);
1614*9880d681SAndroid Build Coastguard Worker         MI->getOperand(TargetOperand).setMBB(NewDest);
1615*9880d681SAndroid Build Coastguard Worker         return true;
1616*9880d681SAndroid Build Coastguard Worker       }
1617*9880d681SAndroid Build Coastguard Worker     }
1618*9880d681SAndroid Build Coastguard Worker   }
1619*9880d681SAndroid Build Coastguard Worker 
1620*9880d681SAndroid Build Coastguard Worker 
1621*9880d681SAndroid Build Coastguard Worker   if (NeedSplit) {
1622*9880d681SAndroid Build Coastguard Worker     splitBlockBeforeInstr(*MI);
1623*9880d681SAndroid Build Coastguard Worker     // No need for the branch to the next block. We're adding an unconditional
1624*9880d681SAndroid Build Coastguard Worker     // branch to the destination.
1625*9880d681SAndroid Build Coastguard Worker     int delta = TII->GetInstSizeInBytes(MBB->back());
1626*9880d681SAndroid Build Coastguard Worker     BBInfo[MBB->getNumber()].Size -= delta;
1627*9880d681SAndroid Build Coastguard Worker     MBB->back().eraseFromParent();
1628*9880d681SAndroid Build Coastguard Worker     // BBInfo[SplitBB].Offset is wrong temporarily, fixed below
1629*9880d681SAndroid Build Coastguard Worker   }
1630*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *NextBB = &*++MBB->getIterator();
1631*9880d681SAndroid Build Coastguard Worker 
1632*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "  Insert B to BB#" << DestBB->getNumber()
1633*9880d681SAndroid Build Coastguard Worker                << " also invert condition and change dest. to BB#"
1634*9880d681SAndroid Build Coastguard Worker                << NextBB->getNumber() << "\n");
1635*9880d681SAndroid Build Coastguard Worker 
1636*9880d681SAndroid Build Coastguard Worker   // Insert a new conditional branch and a new unconditional branch.
1637*9880d681SAndroid Build Coastguard Worker   // Also update the ImmBranch as well as adding a new entry for the new branch.
1638*9880d681SAndroid Build Coastguard Worker   if (MI->getNumExplicitOperands() == 2) {
1639*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DebugLoc(), TII->get(OppositeBranchOpcode))
1640*9880d681SAndroid Build Coastguard Worker            .addReg(MI->getOperand(0).getReg())
1641*9880d681SAndroid Build Coastguard Worker            .addMBB(NextBB);
1642*9880d681SAndroid Build Coastguard Worker   } else {
1643*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DebugLoc(), TII->get(OppositeBranchOpcode))
1644*9880d681SAndroid Build Coastguard Worker            .addMBB(NextBB);
1645*9880d681SAndroid Build Coastguard Worker   }
1646*9880d681SAndroid Build Coastguard Worker   Br.MI = &MBB->back();
1647*9880d681SAndroid Build Coastguard Worker   BBInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(MBB->back());
1648*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB);
1649*9880d681SAndroid Build Coastguard Worker   BBInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(MBB->back());
1650*9880d681SAndroid Build Coastguard Worker   unsigned MaxDisp = getUnconditionalBrDisp(Br.UncondBr);
1651*9880d681SAndroid Build Coastguard Worker   ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr));
1652*9880d681SAndroid Build Coastguard Worker 
1653*9880d681SAndroid Build Coastguard Worker   // Remove the old conditional branch.  It may or may not still be in MBB.
1654*9880d681SAndroid Build Coastguard Worker   BBInfo[MI->getParent()->getNumber()].Size -= TII->GetInstSizeInBytes(*MI);
1655*9880d681SAndroid Build Coastguard Worker   MI->eraseFromParent();
1656*9880d681SAndroid Build Coastguard Worker   adjustBBOffsetsAfter(MBB);
1657*9880d681SAndroid Build Coastguard Worker   return true;
1658*9880d681SAndroid Build Coastguard Worker }
1659*9880d681SAndroid Build Coastguard Worker 
1660*9880d681SAndroid Build Coastguard Worker 
prescanForConstants()1661*9880d681SAndroid Build Coastguard Worker void MipsConstantIslands::prescanForConstants() {
1662*9880d681SAndroid Build Coastguard Worker   unsigned J = 0;
1663*9880d681SAndroid Build Coastguard Worker   (void)J;
1664*9880d681SAndroid Build Coastguard Worker   for (MachineFunction::iterator B =
1665*9880d681SAndroid Build Coastguard Worker          MF->begin(), E = MF->end(); B != E; ++B) {
1666*9880d681SAndroid Build Coastguard Worker     for (MachineBasicBlock::instr_iterator I =
1667*9880d681SAndroid Build Coastguard Worker         B->instr_begin(), EB = B->instr_end(); I != EB; ++I) {
1668*9880d681SAndroid Build Coastguard Worker       switch(I->getDesc().getOpcode()) {
1669*9880d681SAndroid Build Coastguard Worker         case Mips::LwConstant32: {
1670*9880d681SAndroid Build Coastguard Worker           PrescannedForConstants = true;
1671*9880d681SAndroid Build Coastguard Worker           DEBUG(dbgs() << "constant island constant " << *I << "\n");
1672*9880d681SAndroid Build Coastguard Worker           J = I->getNumOperands();
1673*9880d681SAndroid Build Coastguard Worker           DEBUG(dbgs() << "num operands " << J  << "\n");
1674*9880d681SAndroid Build Coastguard Worker           MachineOperand& Literal = I->getOperand(1);
1675*9880d681SAndroid Build Coastguard Worker           if (Literal.isImm()) {
1676*9880d681SAndroid Build Coastguard Worker             int64_t V = Literal.getImm();
1677*9880d681SAndroid Build Coastguard Worker             DEBUG(dbgs() << "literal " << V  << "\n");
1678*9880d681SAndroid Build Coastguard Worker             Type *Int32Ty =
1679*9880d681SAndroid Build Coastguard Worker               Type::getInt32Ty(MF->getFunction()->getContext());
1680*9880d681SAndroid Build Coastguard Worker             const Constant *C = ConstantInt::get(Int32Ty, V);
1681*9880d681SAndroid Build Coastguard Worker             unsigned index = MCP->getConstantPoolIndex(C, 4);
1682*9880d681SAndroid Build Coastguard Worker             I->getOperand(2).ChangeToImmediate(index);
1683*9880d681SAndroid Build Coastguard Worker             DEBUG(dbgs() << "constant island constant " << *I << "\n");
1684*9880d681SAndroid Build Coastguard Worker             I->setDesc(TII->get(Mips::LwRxPcTcp16));
1685*9880d681SAndroid Build Coastguard Worker             I->RemoveOperand(1);
1686*9880d681SAndroid Build Coastguard Worker             I->RemoveOperand(1);
1687*9880d681SAndroid Build Coastguard Worker             I->addOperand(MachineOperand::CreateCPI(index, 0));
1688*9880d681SAndroid Build Coastguard Worker             I->addOperand(MachineOperand::CreateImm(4));
1689*9880d681SAndroid Build Coastguard Worker           }
1690*9880d681SAndroid Build Coastguard Worker           break;
1691*9880d681SAndroid Build Coastguard Worker         }
1692*9880d681SAndroid Build Coastguard Worker         default:
1693*9880d681SAndroid Build Coastguard Worker           break;
1694*9880d681SAndroid Build Coastguard Worker       }
1695*9880d681SAndroid Build Coastguard Worker     }
1696*9880d681SAndroid Build Coastguard Worker   }
1697*9880d681SAndroid Build Coastguard Worker }
1698