xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
10b57cec5SDimitry Andric //===- MipsConstantIslandPass.cpp - Emit Pc Relative loads ----------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This pass is used to make Pc relative loads of constants.
100b57cec5SDimitry Andric // For now, only Mips16 will use this.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric // Loading constants inline is expensive on Mips16 and it's in general better
130b57cec5SDimitry Andric // to place the constant nearby in code space and then it can be loaded with a
140b57cec5SDimitry Andric // simple 16 bit load instruction.
150b57cec5SDimitry Andric //
160b57cec5SDimitry Andric // The constants can be not just numbers but addresses of functions and labels.
170b57cec5SDimitry Andric // This can be particularly helpful in static relocation mode for embedded
180b57cec5SDimitry Andric // non-linux targets.
190b57cec5SDimitry Andric //
200b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric #include "Mips.h"
230b57cec5SDimitry Andric #include "Mips16InstrInfo.h"
240b57cec5SDimitry Andric #include "MipsMachineFunction.h"
250b57cec5SDimitry Andric #include "MipsSubtarget.h"
260b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
270b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
280b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
290b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
300b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
370b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
380b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
390b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
400b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
410b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
420b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
430b57cec5SDimitry Andric #include "llvm/IR/Function.h"
440b57cec5SDimitry Andric #include "llvm/IR/Type.h"
450b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
460b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
470b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
480b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
490b57cec5SDimitry Andric #include "llvm/Support/Format.h"
500b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
510b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
520b57cec5SDimitry Andric #include <algorithm>
530b57cec5SDimitry Andric #include <cassert>
540b57cec5SDimitry Andric #include <cstdint>
550b57cec5SDimitry Andric #include <iterator>
560b57cec5SDimitry Andric #include <vector>
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric using namespace llvm;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric #define DEBUG_TYPE "mips-constant-islands"
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric STATISTIC(NumCPEs,       "Number of constpool entries");
630b57cec5SDimitry Andric STATISTIC(NumSplit,      "Number of uncond branches inserted");
640b57cec5SDimitry Andric STATISTIC(NumCBrFixed,   "Number of cond branches fixed");
650b57cec5SDimitry Andric STATISTIC(NumUBrFixed,   "Number of uncond branches fixed");
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric // FIXME: This option should be removed once it has received sufficient testing.
680b57cec5SDimitry Andric static cl::opt<bool>
690b57cec5SDimitry Andric AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true),
700b57cec5SDimitry Andric           cl::desc("Align constant islands in code"));
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric // Rather than do make check tests with huge amounts of code, we force
730b57cec5SDimitry Andric // the test to use this amount.
740b57cec5SDimitry Andric static cl::opt<int> ConstantIslandsSmallOffset(
750b57cec5SDimitry Andric   "mips-constant-islands-small-offset",
760b57cec5SDimitry Andric   cl::init(0),
770b57cec5SDimitry Andric   cl::desc("Make small offsets be this amount for testing purposes"),
780b57cec5SDimitry Andric   cl::Hidden);
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric // For testing purposes we tell it to not use relaxed load forms so that it
810b57cec5SDimitry Andric // will split blocks.
820b57cec5SDimitry Andric static cl::opt<bool> NoLoadRelaxation(
830b57cec5SDimitry Andric   "mips-constant-islands-no-load-relaxation",
840b57cec5SDimitry Andric   cl::init(false),
850b57cec5SDimitry Andric   cl::desc("Don't relax loads to long loads - for testing purposes"),
860b57cec5SDimitry Andric   cl::Hidden);
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric static unsigned int branchTargetOperand(MachineInstr *MI) {
890b57cec5SDimitry Andric   switch (MI->getOpcode()) {
900b57cec5SDimitry Andric   case Mips::Bimm16:
910b57cec5SDimitry Andric   case Mips::BimmX16:
920b57cec5SDimitry Andric   case Mips::Bteqz16:
930b57cec5SDimitry Andric   case Mips::BteqzX16:
940b57cec5SDimitry Andric   case Mips::Btnez16:
950b57cec5SDimitry Andric   case Mips::BtnezX16:
960b57cec5SDimitry Andric   case Mips::JalB16:
970b57cec5SDimitry Andric     return 0;
980b57cec5SDimitry Andric   case Mips::BeqzRxImm16:
990b57cec5SDimitry Andric   case Mips::BeqzRxImmX16:
1000b57cec5SDimitry Andric   case Mips::BnezRxImm16:
1010b57cec5SDimitry Andric   case Mips::BnezRxImmX16:
1020b57cec5SDimitry Andric     return 1;
1030b57cec5SDimitry Andric   }
1040b57cec5SDimitry Andric   llvm_unreachable("Unknown branch type");
1050b57cec5SDimitry Andric }
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric static unsigned int longformBranchOpcode(unsigned int Opcode) {
1080b57cec5SDimitry Andric   switch (Opcode) {
1090b57cec5SDimitry Andric   case Mips::Bimm16:
1100b57cec5SDimitry Andric   case Mips::BimmX16:
1110b57cec5SDimitry Andric     return Mips::BimmX16;
1120b57cec5SDimitry Andric   case Mips::Bteqz16:
1130b57cec5SDimitry Andric   case Mips::BteqzX16:
1140b57cec5SDimitry Andric     return Mips::BteqzX16;
1150b57cec5SDimitry Andric   case Mips::Btnez16:
1160b57cec5SDimitry Andric   case Mips::BtnezX16:
1170b57cec5SDimitry Andric     return Mips::BtnezX16;
1180b57cec5SDimitry Andric   case Mips::JalB16:
1190b57cec5SDimitry Andric     return Mips::JalB16;
1200b57cec5SDimitry Andric   case Mips::BeqzRxImm16:
1210b57cec5SDimitry Andric   case Mips::BeqzRxImmX16:
1220b57cec5SDimitry Andric     return Mips::BeqzRxImmX16;
1230b57cec5SDimitry Andric   case Mips::BnezRxImm16:
1240b57cec5SDimitry Andric   case Mips::BnezRxImmX16:
1250b57cec5SDimitry Andric     return Mips::BnezRxImmX16;
1260b57cec5SDimitry Andric   }
1270b57cec5SDimitry Andric   llvm_unreachable("Unknown branch type");
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric 
130480093f4SDimitry Andric // FIXME: need to go through this whole constant islands port and check
131480093f4SDimitry Andric // the math for branch ranges and clean this up and make some functions
132480093f4SDimitry Andric // to calculate things that are done many times identically.
1330b57cec5SDimitry Andric // Need to refactor some of the code to call this routine.
1340b57cec5SDimitry Andric static unsigned int branchMaxOffsets(unsigned int Opcode) {
1350b57cec5SDimitry Andric   unsigned Bits, Scale;
1360b57cec5SDimitry Andric   switch (Opcode) {
1370b57cec5SDimitry Andric     case Mips::Bimm16:
1380b57cec5SDimitry Andric       Bits = 11;
1390b57cec5SDimitry Andric       Scale = 2;
1400b57cec5SDimitry Andric       break;
1410b57cec5SDimitry Andric     case Mips::BimmX16:
1420b57cec5SDimitry Andric       Bits = 16;
1430b57cec5SDimitry Andric       Scale = 2;
1440b57cec5SDimitry Andric       break;
1450b57cec5SDimitry Andric     case Mips::BeqzRxImm16:
1460b57cec5SDimitry Andric       Bits = 8;
1470b57cec5SDimitry Andric       Scale = 2;
1480b57cec5SDimitry Andric       break;
1490b57cec5SDimitry Andric     case Mips::BeqzRxImmX16:
1500b57cec5SDimitry Andric       Bits = 16;
1510b57cec5SDimitry Andric       Scale = 2;
1520b57cec5SDimitry Andric       break;
1530b57cec5SDimitry Andric     case Mips::BnezRxImm16:
1540b57cec5SDimitry Andric       Bits = 8;
1550b57cec5SDimitry Andric       Scale = 2;
1560b57cec5SDimitry Andric       break;
1570b57cec5SDimitry Andric     case Mips::BnezRxImmX16:
1580b57cec5SDimitry Andric       Bits = 16;
1590b57cec5SDimitry Andric       Scale = 2;
1600b57cec5SDimitry Andric       break;
1610b57cec5SDimitry Andric     case Mips::Bteqz16:
1620b57cec5SDimitry Andric       Bits = 8;
1630b57cec5SDimitry Andric       Scale = 2;
1640b57cec5SDimitry Andric       break;
1650b57cec5SDimitry Andric     case Mips::BteqzX16:
1660b57cec5SDimitry Andric       Bits = 16;
1670b57cec5SDimitry Andric       Scale = 2;
1680b57cec5SDimitry Andric       break;
1690b57cec5SDimitry Andric     case Mips::Btnez16:
1700b57cec5SDimitry Andric       Bits = 8;
1710b57cec5SDimitry Andric       Scale = 2;
1720b57cec5SDimitry Andric       break;
1730b57cec5SDimitry Andric     case Mips::BtnezX16:
1740b57cec5SDimitry Andric       Bits = 16;
1750b57cec5SDimitry Andric       Scale = 2;
1760b57cec5SDimitry Andric       break;
1770b57cec5SDimitry Andric     default:
1780b57cec5SDimitry Andric       llvm_unreachable("Unknown branch type");
1790b57cec5SDimitry Andric   }
1800b57cec5SDimitry Andric   unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
1810b57cec5SDimitry Andric   return MaxOffs;
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric namespace {
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric   using Iter = MachineBasicBlock::iterator;
1870b57cec5SDimitry Andric   using ReverseIter = MachineBasicBlock::reverse_iterator;
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric   /// MipsConstantIslands - Due to limited PC-relative displacements, Mips
1900b57cec5SDimitry Andric   /// requires constant pool entries to be scattered among the instructions
1910b57cec5SDimitry Andric   /// inside a function.  To do this, it completely ignores the normal LLVM
1920b57cec5SDimitry Andric   /// constant pool; instead, it places constants wherever it feels like with
1930b57cec5SDimitry Andric   /// special instructions.
1940b57cec5SDimitry Andric   ///
1950b57cec5SDimitry Andric   /// The terminology used in this pass includes:
1960b57cec5SDimitry Andric   ///   Islands - Clumps of constants placed in the function.
1970b57cec5SDimitry Andric   ///   Water   - Potential places where an island could be formed.
1980b57cec5SDimitry Andric   ///   CPE     - A constant pool entry that has been placed somewhere, which
1990b57cec5SDimitry Andric   ///             tracks a list of users.
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   class MipsConstantIslands : public MachineFunctionPass {
2020b57cec5SDimitry Andric     /// BasicBlockInfo - Information about the offset and size of a single
2030b57cec5SDimitry Andric     /// basic block.
2040b57cec5SDimitry Andric     struct BasicBlockInfo {
2050b57cec5SDimitry Andric       /// Offset - Distance from the beginning of the function to the beginning
2060b57cec5SDimitry Andric       /// of this basic block.
2070b57cec5SDimitry Andric       ///
2080b57cec5SDimitry Andric       /// Offsets are computed assuming worst case padding before an aligned
2090b57cec5SDimitry Andric       /// block. This means that subtracting basic block offsets always gives a
2100b57cec5SDimitry Andric       /// conservative estimate of the real distance which may be smaller.
2110b57cec5SDimitry Andric       ///
2120b57cec5SDimitry Andric       /// Because worst case padding is used, the computed offset of an aligned
2130b57cec5SDimitry Andric       /// block may not actually be aligned.
2140b57cec5SDimitry Andric       unsigned Offset = 0;
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric       /// Size - Size of the basic block in bytes.  If the block contains
2170b57cec5SDimitry Andric       /// inline assembly, this is a worst case estimate.
2180b57cec5SDimitry Andric       ///
2190b57cec5SDimitry Andric       /// The size does not include any alignment padding whether from the
2200b57cec5SDimitry Andric       /// beginning of the block, or from an aligned jump table at the end.
2210b57cec5SDimitry Andric       unsigned Size = 0;
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric       BasicBlockInfo() = default;
2240b57cec5SDimitry Andric 
2258bcb0991SDimitry Andric       unsigned postOffset() const { return Offset + Size; }
2260b57cec5SDimitry Andric     };
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric     std::vector<BasicBlockInfo> BBInfo;
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric     /// WaterList - A sorted list of basic blocks where islands could be placed
2310b57cec5SDimitry Andric     /// (i.e. blocks that don't fall through to the following block, due
2320b57cec5SDimitry Andric     /// to a return, unreachable, or unconditional branch).
2330b57cec5SDimitry Andric     std::vector<MachineBasicBlock*> WaterList;
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric     /// NewWaterList - The subset of WaterList that was created since the
2360b57cec5SDimitry Andric     /// previous iteration by inserting unconditional branches.
2370b57cec5SDimitry Andric     SmallSet<MachineBasicBlock*, 4> NewWaterList;
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric     using water_iterator = std::vector<MachineBasicBlock *>::iterator;
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric     /// CPUser - One user of a constant pool, keeping the machine instruction
2420b57cec5SDimitry Andric     /// pointer, the constant pool being referenced, and the max displacement
2430b57cec5SDimitry Andric     /// allowed from the instruction to the CP.  The HighWaterMark records the
2440b57cec5SDimitry Andric     /// highest basic block where a new CPEntry can be placed.  To ensure this
2450b57cec5SDimitry Andric     /// pass terminates, the CP entries are initially placed at the end of the
2460b57cec5SDimitry Andric     /// function and then move monotonically to lower addresses.  The
2470b57cec5SDimitry Andric     /// exception to this rule is when the current CP entry for a particular
2480b57cec5SDimitry Andric     /// CPUser is out of range, but there is another CP entry for the same
2490b57cec5SDimitry Andric     /// constant value in range.  We want to use the existing in-range CP
2500b57cec5SDimitry Andric     /// entry, but if it later moves out of range, the search for new water
2510b57cec5SDimitry Andric     /// should resume where it left off.  The HighWaterMark is used to record
2520b57cec5SDimitry Andric     /// that point.
2530b57cec5SDimitry Andric     struct CPUser {
2540b57cec5SDimitry Andric       MachineInstr *MI;
2550b57cec5SDimitry Andric       MachineInstr *CPEMI;
2560b57cec5SDimitry Andric       MachineBasicBlock *HighWaterMark;
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric     private:
2590b57cec5SDimitry Andric       unsigned MaxDisp;
2600b57cec5SDimitry Andric       unsigned LongFormMaxDisp; // mips16 has 16/32 bit instructions
2610b57cec5SDimitry Andric                                 // with different displacements
2620b57cec5SDimitry Andric       unsigned LongFormOpcode;
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric     public:
2650b57cec5SDimitry Andric       bool NegOk;
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric       CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp,
2680b57cec5SDimitry Andric              bool neg,
2690b57cec5SDimitry Andric              unsigned longformmaxdisp, unsigned longformopcode)
2700b57cec5SDimitry Andric         : MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),
2710b57cec5SDimitry Andric           LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),
2720b57cec5SDimitry Andric           NegOk(neg){
2730b57cec5SDimitry Andric         HighWaterMark = CPEMI->getParent();
2740b57cec5SDimitry Andric       }
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric       /// getMaxDisp - Returns the maximum displacement supported by MI.
2770b57cec5SDimitry Andric       unsigned getMaxDisp() const {
2780b57cec5SDimitry Andric         unsigned xMaxDisp = ConstantIslandsSmallOffset?
2790b57cec5SDimitry Andric                             ConstantIslandsSmallOffset: MaxDisp;
2800b57cec5SDimitry Andric         return xMaxDisp;
2810b57cec5SDimitry Andric       }
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric       void setMaxDisp(unsigned val) {
2840b57cec5SDimitry Andric         MaxDisp = val;
2850b57cec5SDimitry Andric       }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric       unsigned getLongFormMaxDisp() const {
2880b57cec5SDimitry Andric         return LongFormMaxDisp;
2890b57cec5SDimitry Andric       }
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric       unsigned getLongFormOpcode() const {
2920b57cec5SDimitry Andric           return LongFormOpcode;
2930b57cec5SDimitry Andric       }
2940b57cec5SDimitry Andric     };
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric     /// CPUsers - Keep track of all of the machine instructions that use various
2970b57cec5SDimitry Andric     /// constant pools and their max displacement.
2980b57cec5SDimitry Andric     std::vector<CPUser> CPUsers;
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   /// CPEntry - One per constant pool entry, keeping the machine instruction
3010b57cec5SDimitry Andric   /// pointer, the constpool index, and the number of CPUser's which
3020b57cec5SDimitry Andric   /// reference this entry.
3030b57cec5SDimitry Andric   struct CPEntry {
3040b57cec5SDimitry Andric     MachineInstr *CPEMI;
3050b57cec5SDimitry Andric     unsigned CPI;
3060b57cec5SDimitry Andric     unsigned RefCount;
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric     CPEntry(MachineInstr *cpemi, unsigned cpi, unsigned rc = 0)
3090b57cec5SDimitry Andric       : CPEMI(cpemi), CPI(cpi), RefCount(rc) {}
3100b57cec5SDimitry Andric   };
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric   /// CPEntries - Keep track of all of the constant pool entry machine
3130b57cec5SDimitry Andric   /// instructions. For each original constpool index (i.e. those that
3140b57cec5SDimitry Andric   /// existed upon entry to this pass), it keeps a vector of entries.
3150b57cec5SDimitry Andric   /// Original elements are cloned as we go along; the clones are
3160b57cec5SDimitry Andric   /// put in the vector of the original element, but have distinct CPIs.
3170b57cec5SDimitry Andric   std::vector<std::vector<CPEntry>> CPEntries;
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric   /// ImmBranch - One per immediate branch, keeping the machine instruction
3200b57cec5SDimitry Andric   /// pointer, conditional or unconditional, the max displacement,
3210b57cec5SDimitry Andric   /// and (if isCond is true) the corresponding unconditional branch
3220b57cec5SDimitry Andric   /// opcode.
3230b57cec5SDimitry Andric   struct ImmBranch {
3240b57cec5SDimitry Andric     MachineInstr *MI;
3250b57cec5SDimitry Andric     unsigned MaxDisp : 31;
3260b57cec5SDimitry Andric     bool isCond : 1;
3270b57cec5SDimitry Andric     int UncondBr;
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric     ImmBranch(MachineInstr *mi, unsigned maxdisp, bool cond, int ubr)
3300b57cec5SDimitry Andric       : MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}
3310b57cec5SDimitry Andric   };
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric   /// ImmBranches - Keep track of all the immediate branch instructions.
3340b57cec5SDimitry Andric   ///
3350b57cec5SDimitry Andric   std::vector<ImmBranch> ImmBranches;
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric   /// HasFarJump - True if any far jump instruction has been emitted during
3380b57cec5SDimitry Andric   /// the branch fix up pass.
3390b57cec5SDimitry Andric   bool HasFarJump;
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric   const MipsSubtarget *STI = nullptr;
3420b57cec5SDimitry Andric   const Mips16InstrInfo *TII;
3430b57cec5SDimitry Andric   MipsFunctionInfo *MFI;
3440b57cec5SDimitry Andric   MachineFunction *MF = nullptr;
3450b57cec5SDimitry Andric   MachineConstantPool *MCP = nullptr;
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric   unsigned PICLabelUId;
3480b57cec5SDimitry Andric   bool PrescannedForConstants = false;
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric   void initPICLabelUId(unsigned UId) {
3510b57cec5SDimitry Andric     PICLabelUId = UId;
3520b57cec5SDimitry Andric   }
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric   unsigned createPICLabelUId() {
3550b57cec5SDimitry Andric     return PICLabelUId++;
3560b57cec5SDimitry Andric   }
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric   public:
3590b57cec5SDimitry Andric     static char ID;
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric     MipsConstantIslands() : MachineFunctionPass(ID) {}
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric     StringRef getPassName() const override { return "Mips Constant Islands"; }
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric     bool runOnMachineFunction(MachineFunction &F) override;
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric     MachineFunctionProperties getRequiredProperties() const override {
3680b57cec5SDimitry Andric       return MachineFunctionProperties().set(
3690b57cec5SDimitry Andric           MachineFunctionProperties::Property::NoVRegs);
3700b57cec5SDimitry Andric     }
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric     void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
3730b57cec5SDimitry Andric     CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI);
3748bcb0991SDimitry Andric     Align getCPEAlign(const MachineInstr &CPEMI);
3750b57cec5SDimitry Andric     void initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs);
3760b57cec5SDimitry Andric     unsigned getOffsetOf(MachineInstr *MI) const;
3770b57cec5SDimitry Andric     unsigned getUserOffset(CPUser&) const;
3780b57cec5SDimitry Andric     void dumpBBs();
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric     bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,
3810b57cec5SDimitry Andric                          unsigned Disp, bool NegativeOK);
3820b57cec5SDimitry Andric     bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,
3830b57cec5SDimitry Andric                          const CPUser &U);
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric     void computeBlockSize(MachineBasicBlock *MBB);
3860b57cec5SDimitry Andric     MachineBasicBlock *splitBlockBeforeInstr(MachineInstr &MI);
3870b57cec5SDimitry Andric     void updateForInsertedWaterBlock(MachineBasicBlock *NewBB);
3880b57cec5SDimitry Andric     void adjustBBOffsetsAfter(MachineBasicBlock *BB);
3890b57cec5SDimitry Andric     bool decrementCPEReferenceCount(unsigned CPI, MachineInstr* CPEMI);
3900b57cec5SDimitry Andric     int findInRangeCPEntry(CPUser& U, unsigned UserOffset);
3910b57cec5SDimitry Andric     int findLongFormInRangeCPEntry(CPUser& U, unsigned UserOffset);
3920b57cec5SDimitry Andric     bool findAvailableWater(CPUser&U, unsigned UserOffset,
3930b57cec5SDimitry Andric                             water_iterator &WaterIter);
3940b57cec5SDimitry Andric     void createNewWater(unsigned CPUserIndex, unsigned UserOffset,
3950b57cec5SDimitry Andric                         MachineBasicBlock *&NewMBB);
3960b57cec5SDimitry Andric     bool handleConstantPoolUser(unsigned CPUserIndex);
3970b57cec5SDimitry Andric     void removeDeadCPEMI(MachineInstr *CPEMI);
3980b57cec5SDimitry Andric     bool removeUnusedCPEntries();
3990b57cec5SDimitry Andric     bool isCPEntryInRange(MachineInstr *MI, unsigned UserOffset,
4000b57cec5SDimitry Andric                           MachineInstr *CPEMI, unsigned Disp, bool NegOk,
4010b57cec5SDimitry Andric                           bool DoDump = false);
4020b57cec5SDimitry Andric     bool isWaterInRange(unsigned UserOffset, MachineBasicBlock *Water,
4030b57cec5SDimitry Andric                         CPUser &U, unsigned &Growth);
4040b57cec5SDimitry Andric     bool isBBInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp);
4050b57cec5SDimitry Andric     bool fixupImmediateBr(ImmBranch &Br);
4060b57cec5SDimitry Andric     bool fixupConditionalBr(ImmBranch &Br);
4070b57cec5SDimitry Andric     bool fixupUnconditionalBr(ImmBranch &Br);
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric     void prescanForConstants();
4100b57cec5SDimitry Andric   };
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric } // end anonymous namespace
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric char MipsConstantIslands::ID = 0;
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric bool MipsConstantIslands::isOffsetInRange
4170b57cec5SDimitry Andric   (unsigned UserOffset, unsigned TrialOffset,
4180b57cec5SDimitry Andric    const CPUser &U) {
4190b57cec5SDimitry Andric   return isOffsetInRange(UserOffset, TrialOffset,
4200b57cec5SDimitry Andric                          U.getMaxDisp(), U.NegOk);
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4240b57cec5SDimitry Andric /// print block size and offset information - debugging
4250b57cec5SDimitry Andric LLVM_DUMP_METHOD void MipsConstantIslands::dumpBBs() {
4260b57cec5SDimitry Andric   for (unsigned J = 0, E = BBInfo.size(); J !=E; ++J) {
4270b57cec5SDimitry Andric     const BasicBlockInfo &BBI = BBInfo[J];
4280b57cec5SDimitry Andric     dbgs() << format("%08x %bb.%u\t", BBI.Offset, J)
4290b57cec5SDimitry Andric            << format(" size=%#x\n", BBInfo[J].Size);
4300b57cec5SDimitry Andric   }
4310b57cec5SDimitry Andric }
4320b57cec5SDimitry Andric #endif
4330b57cec5SDimitry Andric 
4340b57cec5SDimitry Andric bool MipsConstantIslands::runOnMachineFunction(MachineFunction &mf) {
4350b57cec5SDimitry Andric   // The intention is for this to be a mips16 only pass for now
4360b57cec5SDimitry Andric   // FIXME:
4370b57cec5SDimitry Andric   MF = &mf;
4380b57cec5SDimitry Andric   MCP = mf.getConstantPool();
4390b57cec5SDimitry Andric   STI = &static_cast<const MipsSubtarget &>(mf.getSubtarget());
4400b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "constant island machine function "
4410b57cec5SDimitry Andric                     << "\n");
4420b57cec5SDimitry Andric   if (!STI->inMips16Mode() || !MipsSubtarget::useConstantIslands()) {
4430b57cec5SDimitry Andric     return false;
4440b57cec5SDimitry Andric   }
4450b57cec5SDimitry Andric   TII = (const Mips16InstrInfo *)STI->getInstrInfo();
4460b57cec5SDimitry Andric   MFI = MF->getInfo<MipsFunctionInfo>();
4470b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "constant island processing "
4480b57cec5SDimitry Andric                     << "\n");
4490b57cec5SDimitry Andric   //
4500b57cec5SDimitry Andric   // will need to make predermination if there is any constants we need to
4510b57cec5SDimitry Andric   // put in constant islands. TBD.
4520b57cec5SDimitry Andric   //
4530b57cec5SDimitry Andric   if (!PrescannedForConstants) prescanForConstants();
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   HasFarJump = false;
4560b57cec5SDimitry Andric   // This pass invalidates liveness information when it splits basic blocks.
4570b57cec5SDimitry Andric   MF->getRegInfo().invalidateLiveness();
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric   // Renumber all of the machine basic blocks in the function, guaranteeing that
4600b57cec5SDimitry Andric   // the numbers agree with the position of the block in the function.
4610b57cec5SDimitry Andric   MF->RenumberBlocks();
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric   bool MadeChange = false;
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   // Perform the initial placement of the constant pool entries.  To start with,
4660b57cec5SDimitry Andric   // we put them all at the end of the function.
4670b57cec5SDimitry Andric   std::vector<MachineInstr*> CPEMIs;
4680b57cec5SDimitry Andric   if (!MCP->isEmpty())
4690b57cec5SDimitry Andric     doInitialPlacement(CPEMIs);
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric   /// The next UID to take is the first unused one.
4720b57cec5SDimitry Andric   initPICLabelUId(CPEMIs.size());
4730b57cec5SDimitry Andric 
4740b57cec5SDimitry Andric   // Do the initial scan of the function, building up information about the
4750b57cec5SDimitry Andric   // sizes of each block, the location of all the water, and finding all of the
4760b57cec5SDimitry Andric   // constant pool users.
4770b57cec5SDimitry Andric   initializeFunctionInfo(CPEMIs);
4780b57cec5SDimitry Andric   CPEMIs.clear();
4790b57cec5SDimitry Andric   LLVM_DEBUG(dumpBBs());
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric   /// Remove dead constant pool entries.
4820b57cec5SDimitry Andric   MadeChange |= removeUnusedCPEntries();
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   // Iteratively place constant pool entries and fix up branches until there
4850b57cec5SDimitry Andric   // is no change.
4860b57cec5SDimitry Andric   unsigned NoCPIters = 0, NoBRIters = 0;
4870b57cec5SDimitry Andric   (void)NoBRIters;
4880b57cec5SDimitry Andric   while (true) {
4890b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Beginning CP iteration #" << NoCPIters << '\n');
4900b57cec5SDimitry Andric     bool CPChange = false;
4910b57cec5SDimitry Andric     for (unsigned i = 0, e = CPUsers.size(); i != e; ++i)
4920b57cec5SDimitry Andric       CPChange |= handleConstantPoolUser(i);
4930b57cec5SDimitry Andric     if (CPChange && ++NoCPIters > 30)
4940b57cec5SDimitry Andric       report_fatal_error("Constant Island pass failed to converge!");
4950b57cec5SDimitry Andric     LLVM_DEBUG(dumpBBs());
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric     // Clear NewWaterList now.  If we split a block for branches, it should
4980b57cec5SDimitry Andric     // appear as "new water" for the next iteration of constant pool placement.
4990b57cec5SDimitry Andric     NewWaterList.clear();
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Beginning BR iteration #" << NoBRIters << '\n');
5020b57cec5SDimitry Andric     bool BRChange = false;
5030b57cec5SDimitry Andric     for (unsigned i = 0, e = ImmBranches.size(); i != e; ++i)
5040b57cec5SDimitry Andric       BRChange |= fixupImmediateBr(ImmBranches[i]);
5050b57cec5SDimitry Andric     if (BRChange && ++NoBRIters > 30)
5060b57cec5SDimitry Andric       report_fatal_error("Branch Fix Up pass failed to converge!");
5070b57cec5SDimitry Andric     LLVM_DEBUG(dumpBBs());
5080b57cec5SDimitry Andric     if (!CPChange && !BRChange)
5090b57cec5SDimitry Andric       break;
5100b57cec5SDimitry Andric     MadeChange = true;
5110b57cec5SDimitry Andric   }
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << '\n'; dumpBBs());
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric   BBInfo.clear();
5160b57cec5SDimitry Andric   WaterList.clear();
5170b57cec5SDimitry Andric   CPUsers.clear();
5180b57cec5SDimitry Andric   CPEntries.clear();
5190b57cec5SDimitry Andric   ImmBranches.clear();
5200b57cec5SDimitry Andric   return MadeChange;
5210b57cec5SDimitry Andric }
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric /// doInitialPlacement - Perform the initial placement of the constant pool
5240b57cec5SDimitry Andric /// entries.  To start with, we put them all at the end of the function.
5250b57cec5SDimitry Andric void
5260b57cec5SDimitry Andric MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
5270b57cec5SDimitry Andric   // Create the basic block to hold the CPE's.
5280b57cec5SDimitry Andric   MachineBasicBlock *BB = MF->CreateMachineBasicBlock();
5290b57cec5SDimitry Andric   MF->push_back(BB);
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric   // MachineConstantPool measures alignment in bytes. We measure in log2(bytes).
532*5ffd83dbSDimitry Andric   const Align MaxAlign = MCP->getConstantPoolAlign();
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric   // Mark the basic block as required by the const-pool.
5350b57cec5SDimitry Andric   // If AlignConstantIslands isn't set, use 4-byte alignment for everything.
5368bcb0991SDimitry Andric   BB->setAlignment(AlignConstantIslands ? MaxAlign : Align(4));
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric   // The function needs to be as aligned as the basic blocks. The linker may
5390b57cec5SDimitry Andric   // move functions around based on their alignment.
5400b57cec5SDimitry Andric   MF->ensureAlignment(BB->getAlignment());
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric   // Order the entries in BB by descending alignment.  That ensures correct
5430b57cec5SDimitry Andric   // alignment of all entries as long as BB is sufficiently aligned.  Keep
5440b57cec5SDimitry Andric   // track of the insertion point for each alignment.  We are going to bucket
5450b57cec5SDimitry Andric   // sort the entries as they are created.
5468bcb0991SDimitry Andric   SmallVector<MachineBasicBlock::iterator, 8> InsPoint(Log2(MaxAlign) + 1,
5478bcb0991SDimitry Andric                                                        BB->end());
5480b57cec5SDimitry Andric 
5490b57cec5SDimitry Andric   // Add all of the constants from the constant pool to the end block, use an
5500b57cec5SDimitry Andric   // identity mapping of CPI's to CPE's.
5510b57cec5SDimitry Andric   const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
5520b57cec5SDimitry Andric 
5530b57cec5SDimitry Andric   const DataLayout &TD = MF->getDataLayout();
5540b57cec5SDimitry Andric   for (unsigned i = 0, e = CPs.size(); i != e; ++i) {
5550b57cec5SDimitry Andric     unsigned Size = TD.getTypeAllocSize(CPs[i].getType());
5560b57cec5SDimitry Andric     assert(Size >= 4 && "Too small constant pool entry");
557*5ffd83dbSDimitry Andric     Align Alignment = CPs[i].getAlign();
5580b57cec5SDimitry Andric     // Verify that all constant pool entries are a multiple of their alignment.
5590b57cec5SDimitry Andric     // If not, we would have to pad them out so that instructions stay aligned.
560*5ffd83dbSDimitry Andric     assert(isAligned(Alignment, Size) && "CP Entry not multiple of 4 bytes!");
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric     // Insert CONSTPOOL_ENTRY before entries with a smaller alignment.
563*5ffd83dbSDimitry Andric     unsigned LogAlign = Log2(Alignment);
5640b57cec5SDimitry Andric     MachineBasicBlock::iterator InsAt = InsPoint[LogAlign];
5650b57cec5SDimitry Andric 
5660b57cec5SDimitry Andric     MachineInstr *CPEMI =
5670b57cec5SDimitry Andric       BuildMI(*BB, InsAt, DebugLoc(), TII->get(Mips::CONSTPOOL_ENTRY))
5680b57cec5SDimitry Andric         .addImm(i).addConstantPoolIndex(i).addImm(Size);
5690b57cec5SDimitry Andric 
5700b57cec5SDimitry Andric     CPEMIs.push_back(CPEMI);
5710b57cec5SDimitry Andric 
5720b57cec5SDimitry Andric     // Ensure that future entries with higher alignment get inserted before
5730b57cec5SDimitry Andric     // CPEMI. This is bucket sort with iterators.
5748bcb0991SDimitry Andric     for (unsigned a = LogAlign + 1; a <= Log2(MaxAlign); ++a)
5750b57cec5SDimitry Andric       if (InsPoint[a] == InsAt)
5760b57cec5SDimitry Andric         InsPoint[a] = CPEMI;
5770b57cec5SDimitry Andric     // Add a new CPEntry, but no corresponding CPUser yet.
5780b57cec5SDimitry Andric     CPEntries.emplace_back(1, CPEntry(CPEMI, i));
5790b57cec5SDimitry Andric     ++NumCPEs;
5800b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Moved CPI#" << i << " to end of function, size = "
581*5ffd83dbSDimitry Andric                       << Size << ", align = " << Alignment.value() << '\n');
5820b57cec5SDimitry Andric   }
5830b57cec5SDimitry Andric   LLVM_DEBUG(BB->dump());
5840b57cec5SDimitry Andric }
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric /// BBHasFallthrough - Return true if the specified basic block can fallthrough
5870b57cec5SDimitry Andric /// into the block immediately after it.
5880b57cec5SDimitry Andric static bool BBHasFallthrough(MachineBasicBlock *MBB) {
5890b57cec5SDimitry Andric   // Get the next machine basic block in the function.
5900b57cec5SDimitry Andric   MachineFunction::iterator MBBI = MBB->getIterator();
5910b57cec5SDimitry Andric   // Can't fall off end of function.
5920b57cec5SDimitry Andric   if (std::next(MBBI) == MBB->getParent()->end())
5930b57cec5SDimitry Andric     return false;
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric   MachineBasicBlock *NextBB = &*std::next(MBBI);
5960b57cec5SDimitry Andric   for (MachineBasicBlock::succ_iterator I = MBB->succ_begin(),
5970b57cec5SDimitry Andric        E = MBB->succ_end(); I != E; ++I)
5980b57cec5SDimitry Andric     if (*I == NextBB)
5990b57cec5SDimitry Andric       return true;
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric   return false;
6020b57cec5SDimitry Andric }
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric /// findConstPoolEntry - Given the constpool index and CONSTPOOL_ENTRY MI,
6050b57cec5SDimitry Andric /// look up the corresponding CPEntry.
6060b57cec5SDimitry Andric MipsConstantIslands::CPEntry
6070b57cec5SDimitry Andric *MipsConstantIslands::findConstPoolEntry(unsigned CPI,
6080b57cec5SDimitry Andric                                         const MachineInstr *CPEMI) {
6090b57cec5SDimitry Andric   std::vector<CPEntry> &CPEs = CPEntries[CPI];
6100b57cec5SDimitry Andric   // Number of entries per constpool index should be small, just do a
6110b57cec5SDimitry Andric   // linear search.
6120b57cec5SDimitry Andric   for (unsigned i = 0, e = CPEs.size(); i != e; ++i) {
6130b57cec5SDimitry Andric     if (CPEs[i].CPEMI == CPEMI)
6140b57cec5SDimitry Andric       return &CPEs[i];
6150b57cec5SDimitry Andric   }
6160b57cec5SDimitry Andric   return nullptr;
6170b57cec5SDimitry Andric }
6180b57cec5SDimitry Andric 
6198bcb0991SDimitry Andric /// getCPEAlign - Returns the required alignment of the constant pool entry
6200b57cec5SDimitry Andric /// represented by CPEMI.  Alignment is measured in log2(bytes) units.
6218bcb0991SDimitry Andric Align MipsConstantIslands::getCPEAlign(const MachineInstr &CPEMI) {
6220b57cec5SDimitry Andric   assert(CPEMI.getOpcode() == Mips::CONSTPOOL_ENTRY);
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric   // Everything is 4-byte aligned unless AlignConstantIslands is set.
6250b57cec5SDimitry Andric   if (!AlignConstantIslands)
6268bcb0991SDimitry Andric     return Align(4);
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric   unsigned CPI = CPEMI.getOperand(1).getIndex();
6290b57cec5SDimitry Andric   assert(CPI < MCP->getConstants().size() && "Invalid constant pool index.");
630*5ffd83dbSDimitry Andric   return MCP->getConstants()[CPI].getAlign();
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric /// initializeFunctionInfo - Do the initial scan of the function, building up
6340b57cec5SDimitry Andric /// information about the sizes of each block, the location of all the water,
6350b57cec5SDimitry Andric /// and finding all of the constant pool users.
6360b57cec5SDimitry Andric void MipsConstantIslands::
6370b57cec5SDimitry Andric initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
6380b57cec5SDimitry Andric   BBInfo.clear();
6390b57cec5SDimitry Andric   BBInfo.resize(MF->getNumBlockIDs());
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric   // First thing, compute the size of all basic blocks, and see if the function
6420b57cec5SDimitry Andric   // has any inline assembly in it. If so, we have to be conservative about
6430b57cec5SDimitry Andric   // alignment assumptions, as we don't know for sure the size of any
6440b57cec5SDimitry Andric   // instructions in the inline assembly.
6450b57cec5SDimitry Andric   for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I)
6460b57cec5SDimitry Andric     computeBlockSize(&*I);
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric   // Compute block offsets.
6490b57cec5SDimitry Andric   adjustBBOffsetsAfter(&MF->front());
6500b57cec5SDimitry Andric 
6510b57cec5SDimitry Andric   // Now go back through the instructions and build up our data structures.
6520b57cec5SDimitry Andric   for (MachineBasicBlock &MBB : *MF) {
6530b57cec5SDimitry Andric     // If this block doesn't fall through into the next MBB, then this is
6540b57cec5SDimitry Andric     // 'water' that a constant pool island could be placed.
6550b57cec5SDimitry Andric     if (!BBHasFallthrough(&MBB))
6560b57cec5SDimitry Andric       WaterList.push_back(&MBB);
6570b57cec5SDimitry Andric     for (MachineInstr &MI : MBB) {
6580b57cec5SDimitry Andric       if (MI.isDebugInstr())
6590b57cec5SDimitry Andric         continue;
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric       int Opc = MI.getOpcode();
6620b57cec5SDimitry Andric       if (MI.isBranch()) {
6630b57cec5SDimitry Andric         bool isCond = false;
6640b57cec5SDimitry Andric         unsigned Bits = 0;
6650b57cec5SDimitry Andric         unsigned Scale = 1;
6660b57cec5SDimitry Andric         int UOpc = Opc;
6670b57cec5SDimitry Andric         switch (Opc) {
6680b57cec5SDimitry Andric         default:
6690b57cec5SDimitry Andric           continue;  // Ignore other branches for now
6700b57cec5SDimitry Andric         case Mips::Bimm16:
6710b57cec5SDimitry Andric           Bits = 11;
6720b57cec5SDimitry Andric           Scale = 2;
6730b57cec5SDimitry Andric           isCond = false;
6740b57cec5SDimitry Andric           break;
6750b57cec5SDimitry Andric         case Mips::BimmX16:
6760b57cec5SDimitry Andric           Bits = 16;
6770b57cec5SDimitry Andric           Scale = 2;
6780b57cec5SDimitry Andric           isCond = false;
6790b57cec5SDimitry Andric           break;
6800b57cec5SDimitry Andric         case Mips::BeqzRxImm16:
6810b57cec5SDimitry Andric           UOpc=Mips::Bimm16;
6820b57cec5SDimitry Andric           Bits = 8;
6830b57cec5SDimitry Andric           Scale = 2;
6840b57cec5SDimitry Andric           isCond = true;
6850b57cec5SDimitry Andric           break;
6860b57cec5SDimitry Andric         case Mips::BeqzRxImmX16:
6870b57cec5SDimitry Andric           UOpc=Mips::Bimm16;
6880b57cec5SDimitry Andric           Bits = 16;
6890b57cec5SDimitry Andric           Scale = 2;
6900b57cec5SDimitry Andric           isCond = true;
6910b57cec5SDimitry Andric           break;
6920b57cec5SDimitry Andric         case Mips::BnezRxImm16:
6930b57cec5SDimitry Andric           UOpc=Mips::Bimm16;
6940b57cec5SDimitry Andric           Bits = 8;
6950b57cec5SDimitry Andric           Scale = 2;
6960b57cec5SDimitry Andric           isCond = true;
6970b57cec5SDimitry Andric           break;
6980b57cec5SDimitry Andric         case Mips::BnezRxImmX16:
6990b57cec5SDimitry Andric           UOpc=Mips::Bimm16;
7000b57cec5SDimitry Andric           Bits = 16;
7010b57cec5SDimitry Andric           Scale = 2;
7020b57cec5SDimitry Andric           isCond = true;
7030b57cec5SDimitry Andric           break;
7040b57cec5SDimitry Andric         case Mips::Bteqz16:
7050b57cec5SDimitry Andric           UOpc=Mips::Bimm16;
7060b57cec5SDimitry Andric           Bits = 8;
7070b57cec5SDimitry Andric           Scale = 2;
7080b57cec5SDimitry Andric           isCond = true;
7090b57cec5SDimitry Andric           break;
7100b57cec5SDimitry Andric         case Mips::BteqzX16:
7110b57cec5SDimitry Andric           UOpc=Mips::Bimm16;
7120b57cec5SDimitry Andric           Bits = 16;
7130b57cec5SDimitry Andric           Scale = 2;
7140b57cec5SDimitry Andric           isCond = true;
7150b57cec5SDimitry Andric           break;
7160b57cec5SDimitry Andric         case Mips::Btnez16:
7170b57cec5SDimitry Andric           UOpc=Mips::Bimm16;
7180b57cec5SDimitry Andric           Bits = 8;
7190b57cec5SDimitry Andric           Scale = 2;
7200b57cec5SDimitry Andric           isCond = true;
7210b57cec5SDimitry Andric           break;
7220b57cec5SDimitry Andric         case Mips::BtnezX16:
7230b57cec5SDimitry Andric           UOpc=Mips::Bimm16;
7240b57cec5SDimitry Andric           Bits = 16;
7250b57cec5SDimitry Andric           Scale = 2;
7260b57cec5SDimitry Andric           isCond = true;
7270b57cec5SDimitry Andric           break;
7280b57cec5SDimitry Andric         }
7290b57cec5SDimitry Andric         // Record this immediate branch.
7300b57cec5SDimitry Andric         unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
7310b57cec5SDimitry Andric         ImmBranches.push_back(ImmBranch(&MI, MaxOffs, isCond, UOpc));
7320b57cec5SDimitry Andric       }
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric       if (Opc == Mips::CONSTPOOL_ENTRY)
7350b57cec5SDimitry Andric         continue;
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric       // Scan the instructions for constant pool operands.
7380b57cec5SDimitry Andric       for (unsigned op = 0, e = MI.getNumOperands(); op != e; ++op)
7390b57cec5SDimitry Andric         if (MI.getOperand(op).isCPI()) {
7400b57cec5SDimitry Andric           // We found one.  The addressing mode tells us the max displacement
7410b57cec5SDimitry Andric           // from the PC that this instruction permits.
7420b57cec5SDimitry Andric 
7430b57cec5SDimitry Andric           // Basic size info comes from the TSFlags field.
7440b57cec5SDimitry Andric           unsigned Bits = 0;
7450b57cec5SDimitry Andric           unsigned Scale = 1;
7460b57cec5SDimitry Andric           bool NegOk = false;
7470b57cec5SDimitry Andric           unsigned LongFormBits = 0;
7480b57cec5SDimitry Andric           unsigned LongFormScale = 0;
7490b57cec5SDimitry Andric           unsigned LongFormOpcode = 0;
7500b57cec5SDimitry Andric           switch (Opc) {
7510b57cec5SDimitry Andric           default:
7520b57cec5SDimitry Andric             llvm_unreachable("Unknown addressing mode for CP reference!");
7530b57cec5SDimitry Andric           case Mips::LwRxPcTcp16:
7540b57cec5SDimitry Andric             Bits = 8;
7550b57cec5SDimitry Andric             Scale = 4;
7560b57cec5SDimitry Andric             LongFormOpcode = Mips::LwRxPcTcpX16;
7570b57cec5SDimitry Andric             LongFormBits = 14;
7580b57cec5SDimitry Andric             LongFormScale = 1;
7590b57cec5SDimitry Andric             break;
7600b57cec5SDimitry Andric           case Mips::LwRxPcTcpX16:
7610b57cec5SDimitry Andric             Bits = 14;
7620b57cec5SDimitry Andric             Scale = 1;
7630b57cec5SDimitry Andric             NegOk = true;
7640b57cec5SDimitry Andric             break;
7650b57cec5SDimitry Andric           }
7660b57cec5SDimitry Andric           // Remember that this is a user of a CP entry.
7670b57cec5SDimitry Andric           unsigned CPI = MI.getOperand(op).getIndex();
7680b57cec5SDimitry Andric           MachineInstr *CPEMI = CPEMIs[CPI];
7690b57cec5SDimitry Andric           unsigned MaxOffs = ((1 << Bits)-1) * Scale;
7700b57cec5SDimitry Andric           unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;
7710b57cec5SDimitry Andric           CPUsers.push_back(CPUser(&MI, CPEMI, MaxOffs, NegOk, LongFormMaxOffs,
7720b57cec5SDimitry Andric                                    LongFormOpcode));
7730b57cec5SDimitry Andric 
7740b57cec5SDimitry Andric           // Increment corresponding CPEntry reference count.
7750b57cec5SDimitry Andric           CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
7760b57cec5SDimitry Andric           assert(CPE && "Cannot find a corresponding CPEntry!");
7770b57cec5SDimitry Andric           CPE->RefCount++;
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric           // Instructions can only use one CP entry, don't bother scanning the
7800b57cec5SDimitry Andric           // rest of the operands.
7810b57cec5SDimitry Andric           break;
7820b57cec5SDimitry Andric         }
7830b57cec5SDimitry Andric     }
7840b57cec5SDimitry Andric   }
7850b57cec5SDimitry Andric }
7860b57cec5SDimitry Andric 
7870b57cec5SDimitry Andric /// computeBlockSize - Compute the size and some alignment information for MBB.
7880b57cec5SDimitry Andric /// This function updates BBInfo directly.
7890b57cec5SDimitry Andric void MipsConstantIslands::computeBlockSize(MachineBasicBlock *MBB) {
7900b57cec5SDimitry Andric   BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];
7910b57cec5SDimitry Andric   BBI.Size = 0;
7920b57cec5SDimitry Andric 
7930b57cec5SDimitry Andric   for (const MachineInstr &MI : *MBB)
7940b57cec5SDimitry Andric     BBI.Size += TII->getInstSizeInBytes(MI);
7950b57cec5SDimitry Andric }
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric /// getOffsetOf - Return the current offset of the specified machine instruction
7980b57cec5SDimitry Andric /// from the start of the function.  This offset changes as stuff is moved
7990b57cec5SDimitry Andric /// around inside the function.
8000b57cec5SDimitry Andric unsigned MipsConstantIslands::getOffsetOf(MachineInstr *MI) const {
8010b57cec5SDimitry Andric   MachineBasicBlock *MBB = MI->getParent();
8020b57cec5SDimitry Andric 
8030b57cec5SDimitry Andric   // The offset is composed of two things: the sum of the sizes of all MBB's
8040b57cec5SDimitry Andric   // before this instruction's block, and the offset from the start of the block
8050b57cec5SDimitry Andric   // it is in.
8060b57cec5SDimitry Andric   unsigned Offset = BBInfo[MBB->getNumber()].Offset;
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric   // Sum instructions before MI in MBB.
8090b57cec5SDimitry Andric   for (MachineBasicBlock::iterator I = MBB->begin(); &*I != MI; ++I) {
8100b57cec5SDimitry Andric     assert(I != MBB->end() && "Didn't find MI in its own basic block?");
8110b57cec5SDimitry Andric     Offset += TII->getInstSizeInBytes(*I);
8120b57cec5SDimitry Andric   }
8130b57cec5SDimitry Andric   return Offset;
8140b57cec5SDimitry Andric }
8150b57cec5SDimitry Andric 
8160b57cec5SDimitry Andric /// CompareMBBNumbers - Little predicate function to sort the WaterList by MBB
8170b57cec5SDimitry Andric /// ID.
8180b57cec5SDimitry Andric static bool CompareMBBNumbers(const MachineBasicBlock *LHS,
8190b57cec5SDimitry Andric                               const MachineBasicBlock *RHS) {
8200b57cec5SDimitry Andric   return LHS->getNumber() < RHS->getNumber();
8210b57cec5SDimitry Andric }
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric /// updateForInsertedWaterBlock - When a block is newly inserted into the
8240b57cec5SDimitry Andric /// machine function, it upsets all of the block numbers.  Renumber the blocks
8250b57cec5SDimitry Andric /// and update the arrays that parallel this numbering.
8260b57cec5SDimitry Andric void MipsConstantIslands::updateForInsertedWaterBlock
8270b57cec5SDimitry Andric   (MachineBasicBlock *NewBB) {
8280b57cec5SDimitry Andric   // Renumber the MBB's to keep them consecutive.
8290b57cec5SDimitry Andric   NewBB->getParent()->RenumberBlocks(NewBB);
8300b57cec5SDimitry Andric 
8310b57cec5SDimitry Andric   // Insert an entry into BBInfo to align it properly with the (newly
8320b57cec5SDimitry Andric   // renumbered) block numbers.
8330b57cec5SDimitry Andric   BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
8340b57cec5SDimitry Andric 
8350b57cec5SDimitry Andric   // Next, update WaterList.  Specifically, we need to add NewMBB as having
8360b57cec5SDimitry Andric   // available water after it.
8370b57cec5SDimitry Andric   water_iterator IP = llvm::lower_bound(WaterList, NewBB, CompareMBBNumbers);
8380b57cec5SDimitry Andric   WaterList.insert(IP, NewBB);
8390b57cec5SDimitry Andric }
8400b57cec5SDimitry Andric 
8410b57cec5SDimitry Andric unsigned MipsConstantIslands::getUserOffset(CPUser &U) const {
8420b57cec5SDimitry Andric   return getOffsetOf(U.MI);
8430b57cec5SDimitry Andric }
8440b57cec5SDimitry Andric 
8450b57cec5SDimitry Andric /// Split the basic block containing MI into two blocks, which are joined by
8460b57cec5SDimitry Andric /// an unconditional branch.  Update data structures and renumber blocks to
8470b57cec5SDimitry Andric /// account for this change and returns the newly created block.
8480b57cec5SDimitry Andric MachineBasicBlock *
8490b57cec5SDimitry Andric MipsConstantIslands::splitBlockBeforeInstr(MachineInstr &MI) {
8500b57cec5SDimitry Andric   MachineBasicBlock *OrigBB = MI.getParent();
8510b57cec5SDimitry Andric 
8520b57cec5SDimitry Andric   // Create a new MBB for the code after the OrigBB.
8530b57cec5SDimitry Andric   MachineBasicBlock *NewBB =
8540b57cec5SDimitry Andric     MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());
8550b57cec5SDimitry Andric   MachineFunction::iterator MBBI = ++OrigBB->getIterator();
8560b57cec5SDimitry Andric   MF->insert(MBBI, NewBB);
8570b57cec5SDimitry Andric 
8580b57cec5SDimitry Andric   // Splice the instructions starting with MI over to NewBB.
8590b57cec5SDimitry Andric   NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end());
8600b57cec5SDimitry Andric 
8610b57cec5SDimitry Andric   // Add an unconditional branch from OrigBB to NewBB.
8620b57cec5SDimitry Andric   // Note the new unconditional branch is not being recorded.
8630b57cec5SDimitry Andric   // There doesn't seem to be meaningful DebugInfo available; this doesn't
8640b57cec5SDimitry Andric   // correspond to anything in the source.
8650b57cec5SDimitry Andric   BuildMI(OrigBB, DebugLoc(), TII->get(Mips::Bimm16)).addMBB(NewBB);
8660b57cec5SDimitry Andric   ++NumSplit;
8670b57cec5SDimitry Andric 
8680b57cec5SDimitry Andric   // Update the CFG.  All succs of OrigBB are now succs of NewBB.
8690b57cec5SDimitry Andric   NewBB->transferSuccessors(OrigBB);
8700b57cec5SDimitry Andric 
8710b57cec5SDimitry Andric   // OrigBB branches to NewBB.
8720b57cec5SDimitry Andric   OrigBB->addSuccessor(NewBB);
8730b57cec5SDimitry Andric 
8740b57cec5SDimitry Andric   // Update internal data structures to account for the newly inserted MBB.
8750b57cec5SDimitry Andric   // This is almost the same as updateForInsertedWaterBlock, except that
8760b57cec5SDimitry Andric   // the Water goes after OrigBB, not NewBB.
8770b57cec5SDimitry Andric   MF->RenumberBlocks(NewBB);
8780b57cec5SDimitry Andric 
8790b57cec5SDimitry Andric   // Insert an entry into BBInfo to align it properly with the (newly
8800b57cec5SDimitry Andric   // renumbered) block numbers.
8810b57cec5SDimitry Andric   BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
8820b57cec5SDimitry Andric 
8830b57cec5SDimitry Andric   // Next, update WaterList.  Specifically, we need to add OrigMBB as having
8840b57cec5SDimitry Andric   // available water after it (but not if it's already there, which happens
8850b57cec5SDimitry Andric   // when splitting before a conditional branch that is followed by an
8860b57cec5SDimitry Andric   // unconditional branch - in that case we want to insert NewBB).
8870b57cec5SDimitry Andric   water_iterator IP = llvm::lower_bound(WaterList, OrigBB, CompareMBBNumbers);
8880b57cec5SDimitry Andric   MachineBasicBlock* WaterBB = *IP;
8890b57cec5SDimitry Andric   if (WaterBB == OrigBB)
8900b57cec5SDimitry Andric     WaterList.insert(std::next(IP), NewBB);
8910b57cec5SDimitry Andric   else
8920b57cec5SDimitry Andric     WaterList.insert(IP, OrigBB);
8930b57cec5SDimitry Andric   NewWaterList.insert(OrigBB);
8940b57cec5SDimitry Andric 
8950b57cec5SDimitry Andric   // Figure out how large the OrigBB is.  As the first half of the original
8960b57cec5SDimitry Andric   // block, it cannot contain a tablejump.  The size includes
8970b57cec5SDimitry Andric   // the new jump we added.  (It should be possible to do this without
8980b57cec5SDimitry Andric   // recounting everything, but it's very confusing, and this is rarely
8990b57cec5SDimitry Andric   // executed.)
9000b57cec5SDimitry Andric   computeBlockSize(OrigBB);
9010b57cec5SDimitry Andric 
9020b57cec5SDimitry Andric   // Figure out how large the NewMBB is.  As the second half of the original
9030b57cec5SDimitry Andric   // block, it may contain a tablejump.
9040b57cec5SDimitry Andric   computeBlockSize(NewBB);
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric   // All BBOffsets following these blocks must be modified.
9070b57cec5SDimitry Andric   adjustBBOffsetsAfter(OrigBB);
9080b57cec5SDimitry Andric 
9090b57cec5SDimitry Andric   return NewBB;
9100b57cec5SDimitry Andric }
9110b57cec5SDimitry Andric 
9120b57cec5SDimitry Andric /// isOffsetInRange - Checks whether UserOffset (the location of a constant pool
9130b57cec5SDimitry Andric /// reference) is within MaxDisp of TrialOffset (a proposed location of a
9140b57cec5SDimitry Andric /// constant pool entry).
9150b57cec5SDimitry Andric bool MipsConstantIslands::isOffsetInRange(unsigned UserOffset,
9160b57cec5SDimitry Andric                                          unsigned TrialOffset, unsigned MaxDisp,
9170b57cec5SDimitry Andric                                          bool NegativeOK) {
9180b57cec5SDimitry Andric   if (UserOffset <= TrialOffset) {
9190b57cec5SDimitry Andric     // User before the Trial.
9200b57cec5SDimitry Andric     if (TrialOffset - UserOffset <= MaxDisp)
9210b57cec5SDimitry Andric       return true;
9220b57cec5SDimitry Andric   } else if (NegativeOK) {
9230b57cec5SDimitry Andric     if (UserOffset - TrialOffset <= MaxDisp)
9240b57cec5SDimitry Andric       return true;
9250b57cec5SDimitry Andric   }
9260b57cec5SDimitry Andric   return false;
9270b57cec5SDimitry Andric }
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric /// isWaterInRange - Returns true if a CPE placed after the specified
9300b57cec5SDimitry Andric /// Water (a basic block) will be in range for the specific MI.
9310b57cec5SDimitry Andric ///
9320b57cec5SDimitry Andric /// Compute how much the function will grow by inserting a CPE after Water.
9330b57cec5SDimitry Andric bool MipsConstantIslands::isWaterInRange(unsigned UserOffset,
9340b57cec5SDimitry Andric                                         MachineBasicBlock* Water, CPUser &U,
9350b57cec5SDimitry Andric                                         unsigned &Growth) {
9368bcb0991SDimitry Andric   unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset();
9378bcb0991SDimitry Andric   unsigned NextBlockOffset;
9388bcb0991SDimitry Andric   Align NextBlockAlignment;
9390b57cec5SDimitry Andric   MachineFunction::const_iterator NextBlock = ++Water->getIterator();
9400b57cec5SDimitry Andric   if (NextBlock == MF->end()) {
9410b57cec5SDimitry Andric     NextBlockOffset = BBInfo[Water->getNumber()].postOffset();
942*5ffd83dbSDimitry Andric     NextBlockAlignment = Align(1);
9430b57cec5SDimitry Andric   } else {
9440b57cec5SDimitry Andric     NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
9450b57cec5SDimitry Andric     NextBlockAlignment = NextBlock->getAlignment();
9460b57cec5SDimitry Andric   }
9470b57cec5SDimitry Andric   unsigned Size = U.CPEMI->getOperand(2).getImm();
9480b57cec5SDimitry Andric   unsigned CPEEnd = CPEOffset + Size;
9490b57cec5SDimitry Andric 
9500b57cec5SDimitry Andric   // The CPE may be able to hide in the alignment padding before the next
9510b57cec5SDimitry Andric   // block. It may also cause more padding to be required if it is more aligned
9520b57cec5SDimitry Andric   // that the next block.
9530b57cec5SDimitry Andric   if (CPEEnd > NextBlockOffset) {
9540b57cec5SDimitry Andric     Growth = CPEEnd - NextBlockOffset;
9550b57cec5SDimitry Andric     // Compute the padding that would go at the end of the CPE to align the next
9560b57cec5SDimitry Andric     // block.
9578bcb0991SDimitry Andric     Growth += offsetToAlignment(CPEEnd, NextBlockAlignment);
9580b57cec5SDimitry Andric 
9590b57cec5SDimitry Andric     // If the CPE is to be inserted before the instruction, that will raise
9600b57cec5SDimitry Andric     // the offset of the instruction. Also account for unknown alignment padding
9610b57cec5SDimitry Andric     // in blocks between CPE and the user.
9620b57cec5SDimitry Andric     if (CPEOffset < UserOffset)
9630b57cec5SDimitry Andric       UserOffset += Growth;
9640b57cec5SDimitry Andric   } else
9650b57cec5SDimitry Andric     // CPE fits in existing padding.
9660b57cec5SDimitry Andric     Growth = 0;
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric   return isOffsetInRange(UserOffset, CPEOffset, U);
9690b57cec5SDimitry Andric }
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric /// isCPEntryInRange - Returns true if the distance between specific MI and
9720b57cec5SDimitry Andric /// specific ConstPool entry instruction can fit in MI's displacement field.
9730b57cec5SDimitry Andric bool MipsConstantIslands::isCPEntryInRange
9740b57cec5SDimitry Andric   (MachineInstr *MI, unsigned UserOffset,
9750b57cec5SDimitry Andric    MachineInstr *CPEMI, unsigned MaxDisp,
9760b57cec5SDimitry Andric    bool NegOk, bool DoDump) {
9770b57cec5SDimitry Andric   unsigned CPEOffset  = getOffsetOf(CPEMI);
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric   if (DoDump) {
9800b57cec5SDimitry Andric     LLVM_DEBUG({
9810b57cec5SDimitry Andric       unsigned Block = MI->getParent()->getNumber();
9820b57cec5SDimitry Andric       const BasicBlockInfo &BBI = BBInfo[Block];
9830b57cec5SDimitry Andric       dbgs() << "User of CPE#" << CPEMI->getOperand(0).getImm()
9840b57cec5SDimitry Andric              << " max delta=" << MaxDisp
9850b57cec5SDimitry Andric              << format(" insn address=%#x", UserOffset) << " in "
9860b57cec5SDimitry Andric              << printMBBReference(*MI->getParent()) << ": "
9870b57cec5SDimitry Andric              << format("%#x-%x\t", BBI.Offset, BBI.postOffset()) << *MI
9880b57cec5SDimitry Andric              << format("CPE address=%#x offset=%+d: ", CPEOffset,
9890b57cec5SDimitry Andric                        int(CPEOffset - UserOffset));
9900b57cec5SDimitry Andric     });
9910b57cec5SDimitry Andric   }
9920b57cec5SDimitry Andric 
9930b57cec5SDimitry Andric   return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
9940b57cec5SDimitry Andric }
9950b57cec5SDimitry Andric 
9960b57cec5SDimitry Andric #ifndef NDEBUG
9970b57cec5SDimitry Andric /// BBIsJumpedOver - Return true of the specified basic block's only predecessor
9980b57cec5SDimitry Andric /// unconditionally branches to its only successor.
9990b57cec5SDimitry Andric static bool BBIsJumpedOver(MachineBasicBlock *MBB) {
10000b57cec5SDimitry Andric   if (MBB->pred_size() != 1 || MBB->succ_size() != 1)
10010b57cec5SDimitry Andric     return false;
10020b57cec5SDimitry Andric   MachineBasicBlock *Succ = *MBB->succ_begin();
10030b57cec5SDimitry Andric   MachineBasicBlock *Pred = *MBB->pred_begin();
10040b57cec5SDimitry Andric   MachineInstr *PredMI = &Pred->back();
10050b57cec5SDimitry Andric   if (PredMI->getOpcode() == Mips::Bimm16)
10060b57cec5SDimitry Andric     return PredMI->getOperand(0).getMBB() == Succ;
10070b57cec5SDimitry Andric   return false;
10080b57cec5SDimitry Andric }
10090b57cec5SDimitry Andric #endif
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric void MipsConstantIslands::adjustBBOffsetsAfter(MachineBasicBlock *BB) {
10120b57cec5SDimitry Andric   unsigned BBNum = BB->getNumber();
10130b57cec5SDimitry Andric   for(unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++i) {
10140b57cec5SDimitry Andric     // Get the offset and known bits at the end of the layout predecessor.
10150b57cec5SDimitry Andric     // Include the alignment of the current block.
10160b57cec5SDimitry Andric     unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;
10170b57cec5SDimitry Andric     BBInfo[i].Offset = Offset;
10180b57cec5SDimitry Andric   }
10190b57cec5SDimitry Andric }
10200b57cec5SDimitry Andric 
10210b57cec5SDimitry Andric /// decrementCPEReferenceCount - find the constant pool entry with index CPI
10220b57cec5SDimitry Andric /// and instruction CPEMI, and decrement its refcount.  If the refcount
10230b57cec5SDimitry Andric /// becomes 0 remove the entry and instruction.  Returns true if we removed
10240b57cec5SDimitry Andric /// the entry, false if we didn't.
10250b57cec5SDimitry Andric bool MipsConstantIslands::decrementCPEReferenceCount(unsigned CPI,
10260b57cec5SDimitry Andric                                                     MachineInstr *CPEMI) {
10270b57cec5SDimitry Andric   // Find the old entry. Eliminate it if it is no longer used.
10280b57cec5SDimitry Andric   CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
10290b57cec5SDimitry Andric   assert(CPE && "Unexpected!");
10300b57cec5SDimitry Andric   if (--CPE->RefCount == 0) {
10310b57cec5SDimitry Andric     removeDeadCPEMI(CPEMI);
10320b57cec5SDimitry Andric     CPE->CPEMI = nullptr;
10330b57cec5SDimitry Andric     --NumCPEs;
10340b57cec5SDimitry Andric     return true;
10350b57cec5SDimitry Andric   }
10360b57cec5SDimitry Andric   return false;
10370b57cec5SDimitry Andric }
10380b57cec5SDimitry Andric 
10390b57cec5SDimitry Andric /// LookForCPEntryInRange - see if the currently referenced CPE is in range;
10400b57cec5SDimitry Andric /// if not, see if an in-range clone of the CPE is in range, and if so,
10410b57cec5SDimitry Andric /// change the data structures so the user references the clone.  Returns:
10420b57cec5SDimitry Andric /// 0 = no existing entry found
10430b57cec5SDimitry Andric /// 1 = entry found, and there were no code insertions or deletions
10440b57cec5SDimitry Andric /// 2 = entry found, and there were code insertions or deletions
10450b57cec5SDimitry Andric int MipsConstantIslands::findInRangeCPEntry(CPUser& U, unsigned UserOffset)
10460b57cec5SDimitry Andric {
10470b57cec5SDimitry Andric   MachineInstr *UserMI = U.MI;
10480b57cec5SDimitry Andric   MachineInstr *CPEMI  = U.CPEMI;
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric   // Check to see if the CPE is already in-range.
10510b57cec5SDimitry Andric   if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk,
10520b57cec5SDimitry Andric                        true)) {
10530b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "In range\n");
10540b57cec5SDimitry Andric     return 1;
10550b57cec5SDimitry Andric   }
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric   // No.  Look for previously created clones of the CPE that are in range.
10580b57cec5SDimitry Andric   unsigned CPI = CPEMI->getOperand(1).getIndex();
10590b57cec5SDimitry Andric   std::vector<CPEntry> &CPEs = CPEntries[CPI];
10600b57cec5SDimitry Andric   for (unsigned i = 0, e = CPEs.size(); i != e; ++i) {
10610b57cec5SDimitry Andric     // We already tried this one
10620b57cec5SDimitry Andric     if (CPEs[i].CPEMI == CPEMI)
10630b57cec5SDimitry Andric       continue;
10640b57cec5SDimitry Andric     // Removing CPEs can leave empty entries, skip
10650b57cec5SDimitry Andric     if (CPEs[i].CPEMI == nullptr)
10660b57cec5SDimitry Andric       continue;
10670b57cec5SDimitry Andric     if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI, U.getMaxDisp(),
10680b57cec5SDimitry Andric                      U.NegOk)) {
10690b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#"
10700b57cec5SDimitry Andric                         << CPEs[i].CPI << "\n");
10710b57cec5SDimitry Andric       // Point the CPUser node to the replacement
10720b57cec5SDimitry Andric       U.CPEMI = CPEs[i].CPEMI;
10730b57cec5SDimitry Andric       // Change the CPI in the instruction operand to refer to the clone.
10740b57cec5SDimitry Andric       for (unsigned j = 0, e = UserMI->getNumOperands(); j != e; ++j)
10750b57cec5SDimitry Andric         if (UserMI->getOperand(j).isCPI()) {
10760b57cec5SDimitry Andric           UserMI->getOperand(j).setIndex(CPEs[i].CPI);
10770b57cec5SDimitry Andric           break;
10780b57cec5SDimitry Andric         }
10790b57cec5SDimitry Andric       // Adjust the refcount of the clone...
10800b57cec5SDimitry Andric       CPEs[i].RefCount++;
10810b57cec5SDimitry Andric       // ...and the original.  If we didn't remove the old entry, none of the
10820b57cec5SDimitry Andric       // addresses changed, so we don't need another pass.
10830b57cec5SDimitry Andric       return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
10840b57cec5SDimitry Andric     }
10850b57cec5SDimitry Andric   }
10860b57cec5SDimitry Andric   return 0;
10870b57cec5SDimitry Andric }
10880b57cec5SDimitry Andric 
10890b57cec5SDimitry Andric /// LookForCPEntryInRange - see if the currently referenced CPE is in range;
10900b57cec5SDimitry Andric /// This version checks if the longer form of the instruction can be used to
10910b57cec5SDimitry Andric /// to satisfy things.
10920b57cec5SDimitry Andric /// if not, see if an in-range clone of the CPE is in range, and if so,
10930b57cec5SDimitry Andric /// change the data structures so the user references the clone.  Returns:
10940b57cec5SDimitry Andric /// 0 = no existing entry found
10950b57cec5SDimitry Andric /// 1 = entry found, and there were no code insertions or deletions
10960b57cec5SDimitry Andric /// 2 = entry found, and there were code insertions or deletions
10970b57cec5SDimitry Andric int MipsConstantIslands::findLongFormInRangeCPEntry
10980b57cec5SDimitry Andric   (CPUser& U, unsigned UserOffset)
10990b57cec5SDimitry Andric {
11000b57cec5SDimitry Andric   MachineInstr *UserMI = U.MI;
11010b57cec5SDimitry Andric   MachineInstr *CPEMI  = U.CPEMI;
11020b57cec5SDimitry Andric 
11030b57cec5SDimitry Andric   // Check to see if the CPE is already in-range.
11040b57cec5SDimitry Andric   if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
11050b57cec5SDimitry Andric                        U.getLongFormMaxDisp(), U.NegOk,
11060b57cec5SDimitry Andric                        true)) {
11070b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "In range\n");
11080b57cec5SDimitry Andric     UserMI->setDesc(TII->get(U.getLongFormOpcode()));
11090b57cec5SDimitry Andric     U.setMaxDisp(U.getLongFormMaxDisp());
11100b57cec5SDimitry Andric     return 2;  // instruction is longer length now
11110b57cec5SDimitry Andric   }
11120b57cec5SDimitry Andric 
11130b57cec5SDimitry Andric   // No.  Look for previously created clones of the CPE that are in range.
11140b57cec5SDimitry Andric   unsigned CPI = CPEMI->getOperand(1).getIndex();
11150b57cec5SDimitry Andric   std::vector<CPEntry> &CPEs = CPEntries[CPI];
11160b57cec5SDimitry Andric   for (unsigned i = 0, e = CPEs.size(); i != e; ++i) {
11170b57cec5SDimitry Andric     // We already tried this one
11180b57cec5SDimitry Andric     if (CPEs[i].CPEMI == CPEMI)
11190b57cec5SDimitry Andric       continue;
11200b57cec5SDimitry Andric     // Removing CPEs can leave empty entries, skip
11210b57cec5SDimitry Andric     if (CPEs[i].CPEMI == nullptr)
11220b57cec5SDimitry Andric       continue;
11230b57cec5SDimitry Andric     if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI,
11240b57cec5SDimitry Andric                          U.getLongFormMaxDisp(), U.NegOk)) {
11250b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#"
11260b57cec5SDimitry Andric                         << CPEs[i].CPI << "\n");
11270b57cec5SDimitry Andric       // Point the CPUser node to the replacement
11280b57cec5SDimitry Andric       U.CPEMI = CPEs[i].CPEMI;
11290b57cec5SDimitry Andric       // Change the CPI in the instruction operand to refer to the clone.
11300b57cec5SDimitry Andric       for (unsigned j = 0, e = UserMI->getNumOperands(); j != e; ++j)
11310b57cec5SDimitry Andric         if (UserMI->getOperand(j).isCPI()) {
11320b57cec5SDimitry Andric           UserMI->getOperand(j).setIndex(CPEs[i].CPI);
11330b57cec5SDimitry Andric           break;
11340b57cec5SDimitry Andric         }
11350b57cec5SDimitry Andric       // Adjust the refcount of the clone...
11360b57cec5SDimitry Andric       CPEs[i].RefCount++;
11370b57cec5SDimitry Andric       // ...and the original.  If we didn't remove the old entry, none of the
11380b57cec5SDimitry Andric       // addresses changed, so we don't need another pass.
11390b57cec5SDimitry Andric       return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
11400b57cec5SDimitry Andric     }
11410b57cec5SDimitry Andric   }
11420b57cec5SDimitry Andric   return 0;
11430b57cec5SDimitry Andric }
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric /// getUnconditionalBrDisp - Returns the maximum displacement that can fit in
11460b57cec5SDimitry Andric /// the specific unconditional branch instruction.
11470b57cec5SDimitry Andric static inline unsigned getUnconditionalBrDisp(int Opc) {
11480b57cec5SDimitry Andric   switch (Opc) {
11490b57cec5SDimitry Andric   case Mips::Bimm16:
11500b57cec5SDimitry Andric     return ((1<<10)-1)*2;
11510b57cec5SDimitry Andric   case Mips::BimmX16:
11520b57cec5SDimitry Andric     return ((1<<16)-1)*2;
11530b57cec5SDimitry Andric   default:
11540b57cec5SDimitry Andric     break;
11550b57cec5SDimitry Andric   }
11560b57cec5SDimitry Andric   return ((1<<16)-1)*2;
11570b57cec5SDimitry Andric }
11580b57cec5SDimitry Andric 
11590b57cec5SDimitry Andric /// findAvailableWater - Look for an existing entry in the WaterList in which
11600b57cec5SDimitry Andric /// we can place the CPE referenced from U so it's within range of U's MI.
11610b57cec5SDimitry Andric /// Returns true if found, false if not.  If it returns true, WaterIter
11620b57cec5SDimitry Andric /// is set to the WaterList entry.
11630b57cec5SDimitry Andric /// To ensure that this pass
11640b57cec5SDimitry Andric /// terminates, the CPE location for a particular CPUser is only allowed to
11650b57cec5SDimitry Andric /// move to a lower address, so search backward from the end of the list and
11660b57cec5SDimitry Andric /// prefer the first water that is in range.
11670b57cec5SDimitry Andric bool MipsConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset,
11680b57cec5SDimitry Andric                                       water_iterator &WaterIter) {
11690b57cec5SDimitry Andric   if (WaterList.empty())
11700b57cec5SDimitry Andric     return false;
11710b57cec5SDimitry Andric 
11720b57cec5SDimitry Andric   unsigned BestGrowth = ~0u;
11730b57cec5SDimitry Andric   for (water_iterator IP = std::prev(WaterList.end()), B = WaterList.begin();;
11740b57cec5SDimitry Andric        --IP) {
11750b57cec5SDimitry Andric     MachineBasicBlock* WaterBB = *IP;
11760b57cec5SDimitry Andric     // Check if water is in range and is either at a lower address than the
11770b57cec5SDimitry Andric     // current "high water mark" or a new water block that was created since
11780b57cec5SDimitry Andric     // the previous iteration by inserting an unconditional branch.  In the
11790b57cec5SDimitry Andric     // latter case, we want to allow resetting the high water mark back to
11800b57cec5SDimitry Andric     // this new water since we haven't seen it before.  Inserting branches
11810b57cec5SDimitry Andric     // should be relatively uncommon and when it does happen, we want to be
11820b57cec5SDimitry Andric     // sure to take advantage of it for all the CPEs near that block, so that
11830b57cec5SDimitry Andric     // we don't insert more branches than necessary.
11840b57cec5SDimitry Andric     unsigned Growth;
11850b57cec5SDimitry Andric     if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
11860b57cec5SDimitry Andric         (WaterBB->getNumber() < U.HighWaterMark->getNumber() ||
11870b57cec5SDimitry Andric          NewWaterList.count(WaterBB)) && Growth < BestGrowth) {
11880b57cec5SDimitry Andric       // This is the least amount of required padding seen so far.
11890b57cec5SDimitry Andric       BestGrowth = Growth;
11900b57cec5SDimitry Andric       WaterIter = IP;
11910b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Found water after " << printMBBReference(*WaterBB)
11920b57cec5SDimitry Andric                         << " Growth=" << Growth << '\n');
11930b57cec5SDimitry Andric 
11940b57cec5SDimitry Andric       // Keep looking unless it is perfect.
11950b57cec5SDimitry Andric       if (BestGrowth == 0)
11960b57cec5SDimitry Andric         return true;
11970b57cec5SDimitry Andric     }
11980b57cec5SDimitry Andric     if (IP == B)
11990b57cec5SDimitry Andric       break;
12000b57cec5SDimitry Andric   }
12010b57cec5SDimitry Andric   return BestGrowth != ~0u;
12020b57cec5SDimitry Andric }
12030b57cec5SDimitry Andric 
12040b57cec5SDimitry Andric /// createNewWater - No existing WaterList entry will work for
12050b57cec5SDimitry Andric /// CPUsers[CPUserIndex], so create a place to put the CPE.  The end of the
12060b57cec5SDimitry Andric /// block is used if in range, and the conditional branch munged so control
12070b57cec5SDimitry Andric /// flow is correct.  Otherwise the block is split to create a hole with an
12080b57cec5SDimitry Andric /// unconditional branch around it.  In either case NewMBB is set to a
12090b57cec5SDimitry Andric /// block following which the new island can be inserted (the WaterList
12100b57cec5SDimitry Andric /// is not adjusted).
12110b57cec5SDimitry Andric void MipsConstantIslands::createNewWater(unsigned CPUserIndex,
12120b57cec5SDimitry Andric                                         unsigned UserOffset,
12130b57cec5SDimitry Andric                                         MachineBasicBlock *&NewMBB) {
12140b57cec5SDimitry Andric   CPUser &U = CPUsers[CPUserIndex];
12150b57cec5SDimitry Andric   MachineInstr *UserMI = U.MI;
12160b57cec5SDimitry Andric   MachineInstr *CPEMI  = U.CPEMI;
12170b57cec5SDimitry Andric   MachineBasicBlock *UserMBB = UserMI->getParent();
12180b57cec5SDimitry Andric   const BasicBlockInfo &UserBBI = BBInfo[UserMBB->getNumber()];
12190b57cec5SDimitry Andric 
12200b57cec5SDimitry Andric   // If the block does not end in an unconditional branch already, and if the
12210b57cec5SDimitry Andric   // end of the block is within range, make new water there.
12220b57cec5SDimitry Andric   if (BBHasFallthrough(UserMBB)) {
12230b57cec5SDimitry Andric     // Size of branch to insert.
12240b57cec5SDimitry Andric     unsigned Delta = 2;
12250b57cec5SDimitry Andric     // Compute the offset where the CPE will begin.
12268bcb0991SDimitry Andric     unsigned CPEOffset = UserBBI.postOffset() + Delta;
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric     if (isOffsetInRange(UserOffset, CPEOffset, U)) {
12290b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Split at end of " << printMBBReference(*UserMBB)
12300b57cec5SDimitry Andric                         << format(", expected CPE offset %#x\n", CPEOffset));
12310b57cec5SDimitry Andric       NewMBB = &*++UserMBB->getIterator();
12320b57cec5SDimitry Andric       // Add an unconditional branch from UserMBB to fallthrough block.  Record
12330b57cec5SDimitry Andric       // it for branch lengthening; this new branch will not get out of range,
12340b57cec5SDimitry Andric       // but if the preceding conditional branch is out of range, the targets
12350b57cec5SDimitry Andric       // will be exchanged, and the altered branch may be out of range, so the
12360b57cec5SDimitry Andric       // machinery has to know about it.
12370b57cec5SDimitry Andric       int UncondBr = Mips::Bimm16;
12380b57cec5SDimitry Andric       BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB);
12390b57cec5SDimitry Andric       unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
12400b57cec5SDimitry Andric       ImmBranches.push_back(ImmBranch(&UserMBB->back(),
12410b57cec5SDimitry Andric                                       MaxDisp, false, UncondBr));
12420b57cec5SDimitry Andric       BBInfo[UserMBB->getNumber()].Size += Delta;
12430b57cec5SDimitry Andric       adjustBBOffsetsAfter(UserMBB);
12440b57cec5SDimitry Andric       return;
12450b57cec5SDimitry Andric     }
12460b57cec5SDimitry Andric   }
12470b57cec5SDimitry Andric 
12480b57cec5SDimitry Andric   // What a big block.  Find a place within the block to split it.
12490b57cec5SDimitry Andric 
12500b57cec5SDimitry Andric   // Try to split the block so it's fully aligned.  Compute the latest split
12510b57cec5SDimitry Andric   // point where we can add a 4-byte branch instruction, and then align to
12528bcb0991SDimitry Andric   // Align which is the largest possible alignment in the function.
12538bcb0991SDimitry Andric   const Align Align = MF->getAlignment();
12540b57cec5SDimitry Andric   unsigned BaseInsertOffset = UserOffset + U.getMaxDisp();
12550b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << format("Split in middle of big block before %#x",
12560b57cec5SDimitry Andric                               BaseInsertOffset));
12570b57cec5SDimitry Andric 
12580b57cec5SDimitry Andric   // The 4 in the following is for the unconditional branch we'll be inserting
12590b57cec5SDimitry Andric   // Alignment of the island is handled
12600b57cec5SDimitry Andric   // inside isOffsetInRange.
12610b57cec5SDimitry Andric   BaseInsertOffset -= 4;
12620b57cec5SDimitry Andric 
12630b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << format(", adjusted to %#x", BaseInsertOffset)
12648bcb0991SDimitry Andric                     << " la=" << Log2(Align) << '\n');
12650b57cec5SDimitry Andric 
12660b57cec5SDimitry Andric   // This could point off the end of the block if we've already got constant
12670b57cec5SDimitry Andric   // pool entries following this block; only the last one is in the water list.
12680b57cec5SDimitry Andric   // Back past any possible branches (allow for a conditional and a maximally
12690b57cec5SDimitry Andric   // long unconditional).
12700b57cec5SDimitry Andric   if (BaseInsertOffset + 8 >= UserBBI.postOffset()) {
12710b57cec5SDimitry Andric     BaseInsertOffset = UserBBI.postOffset() - 8;
12720b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << format("Move inside block: %#x\n", BaseInsertOffset));
12730b57cec5SDimitry Andric   }
12740b57cec5SDimitry Andric   unsigned EndInsertOffset = BaseInsertOffset + 4 +
12750b57cec5SDimitry Andric     CPEMI->getOperand(2).getImm();
12760b57cec5SDimitry Andric   MachineBasicBlock::iterator MI = UserMI;
12770b57cec5SDimitry Andric   ++MI;
12780b57cec5SDimitry Andric   unsigned CPUIndex = CPUserIndex+1;
12790b57cec5SDimitry Andric   unsigned NumCPUsers = CPUsers.size();
12800b57cec5SDimitry Andric   //MachineInstr *LastIT = 0;
12810b57cec5SDimitry Andric   for (unsigned Offset = UserOffset + TII->getInstSizeInBytes(*UserMI);
12820b57cec5SDimitry Andric        Offset < BaseInsertOffset;
12830b57cec5SDimitry Andric        Offset += TII->getInstSizeInBytes(*MI), MI = std::next(MI)) {
12840b57cec5SDimitry Andric     assert(MI != UserMBB->end() && "Fell off end of block");
12850b57cec5SDimitry Andric     if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {
12860b57cec5SDimitry Andric       CPUser &U = CPUsers[CPUIndex];
12870b57cec5SDimitry Andric       if (!isOffsetInRange(Offset, EndInsertOffset, U)) {
12880b57cec5SDimitry Andric         // Shift intertion point by one unit of alignment so it is within reach.
12898bcb0991SDimitry Andric         BaseInsertOffset -= Align.value();
12908bcb0991SDimitry Andric         EndInsertOffset -= Align.value();
12910b57cec5SDimitry Andric       }
12920b57cec5SDimitry Andric       // This is overly conservative, as we don't account for CPEMIs being
12930b57cec5SDimitry Andric       // reused within the block, but it doesn't matter much.  Also assume CPEs
12940b57cec5SDimitry Andric       // are added in order with alignment padding.  We may eventually be able
12950b57cec5SDimitry Andric       // to pack the aligned CPEs better.
12960b57cec5SDimitry Andric       EndInsertOffset += U.CPEMI->getOperand(2).getImm();
12970b57cec5SDimitry Andric       CPUIndex++;
12980b57cec5SDimitry Andric     }
12990b57cec5SDimitry Andric   }
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric   NewMBB = splitBlockBeforeInstr(*--MI);
13020b57cec5SDimitry Andric }
13030b57cec5SDimitry Andric 
13040b57cec5SDimitry Andric /// handleConstantPoolUser - Analyze the specified user, checking to see if it
13050b57cec5SDimitry Andric /// is out-of-range.  If so, pick up the constant pool value and move it some
13060b57cec5SDimitry Andric /// place in-range.  Return true if we changed any addresses (thus must run
13070b57cec5SDimitry Andric /// another pass of branch lengthening), false otherwise.
13080b57cec5SDimitry Andric bool MipsConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) {
13090b57cec5SDimitry Andric   CPUser &U = CPUsers[CPUserIndex];
13100b57cec5SDimitry Andric   MachineInstr *UserMI = U.MI;
13110b57cec5SDimitry Andric   MachineInstr *CPEMI  = U.CPEMI;
13120b57cec5SDimitry Andric   unsigned CPI = CPEMI->getOperand(1).getIndex();
13130b57cec5SDimitry Andric   unsigned Size = CPEMI->getOperand(2).getImm();
13140b57cec5SDimitry Andric   // Compute this only once, it's expensive.
13150b57cec5SDimitry Andric   unsigned UserOffset = getUserOffset(U);
13160b57cec5SDimitry Andric 
13170b57cec5SDimitry Andric   // See if the current entry is within range, or there is a clone of it
13180b57cec5SDimitry Andric   // in range.
13190b57cec5SDimitry Andric   int result = findInRangeCPEntry(U, UserOffset);
13200b57cec5SDimitry Andric   if (result==1) return false;
13210b57cec5SDimitry Andric   else if (result==2) return true;
13220b57cec5SDimitry Andric 
13230b57cec5SDimitry Andric   // Look for water where we can place this CPE.
13240b57cec5SDimitry Andric   MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock();
13250b57cec5SDimitry Andric   MachineBasicBlock *NewMBB;
13260b57cec5SDimitry Andric   water_iterator IP;
13270b57cec5SDimitry Andric   if (findAvailableWater(U, UserOffset, IP)) {
13280b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Found water in range\n");
13290b57cec5SDimitry Andric     MachineBasicBlock *WaterBB = *IP;
13300b57cec5SDimitry Andric 
13310b57cec5SDimitry Andric     // If the original WaterList entry was "new water" on this iteration,
13320b57cec5SDimitry Andric     // propagate that to the new island.  This is just keeping NewWaterList
13330b57cec5SDimitry Andric     // updated to match the WaterList, which will be updated below.
13340b57cec5SDimitry Andric     if (NewWaterList.erase(WaterBB))
13350b57cec5SDimitry Andric       NewWaterList.insert(NewIsland);
13360b57cec5SDimitry Andric 
13370b57cec5SDimitry Andric     // The new CPE goes before the following block (NewMBB).
13380b57cec5SDimitry Andric     NewMBB = &*++WaterBB->getIterator();
13390b57cec5SDimitry Andric   } else {
13400b57cec5SDimitry Andric     // No water found.
13410b57cec5SDimitry Andric     // we first see if a longer form of the instrucion could have reached
13420b57cec5SDimitry Andric     // the constant. in that case we won't bother to split
13430b57cec5SDimitry Andric     if (!NoLoadRelaxation) {
13440b57cec5SDimitry Andric       result = findLongFormInRangeCPEntry(U, UserOffset);
13450b57cec5SDimitry Andric       if (result != 0) return true;
13460b57cec5SDimitry Andric     }
13470b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "No water found\n");
13480b57cec5SDimitry Andric     createNewWater(CPUserIndex, UserOffset, NewMBB);
13490b57cec5SDimitry Andric 
13500b57cec5SDimitry Andric     // splitBlockBeforeInstr adds to WaterList, which is important when it is
13510b57cec5SDimitry Andric     // called while handling branches so that the water will be seen on the
13520b57cec5SDimitry Andric     // next iteration for constant pools, but in this context, we don't want
13530b57cec5SDimitry Andric     // it.  Check for this so it will be removed from the WaterList.
13540b57cec5SDimitry Andric     // Also remove any entry from NewWaterList.
13550b57cec5SDimitry Andric     MachineBasicBlock *WaterBB = &*--NewMBB->getIterator();
13560b57cec5SDimitry Andric     IP = llvm::find(WaterList, WaterBB);
13570b57cec5SDimitry Andric     if (IP != WaterList.end())
13580b57cec5SDimitry Andric       NewWaterList.erase(WaterBB);
13590b57cec5SDimitry Andric 
13600b57cec5SDimitry Andric     // We are adding new water.  Update NewWaterList.
13610b57cec5SDimitry Andric     NewWaterList.insert(NewIsland);
13620b57cec5SDimitry Andric   }
13630b57cec5SDimitry Andric 
13640b57cec5SDimitry Andric   // Remove the original WaterList entry; we want subsequent insertions in
13650b57cec5SDimitry Andric   // this vicinity to go after the one we're about to insert.  This
13660b57cec5SDimitry Andric   // considerably reduces the number of times we have to move the same CPE
13670b57cec5SDimitry Andric   // more than once and is also important to ensure the algorithm terminates.
13680b57cec5SDimitry Andric   if (IP != WaterList.end())
13690b57cec5SDimitry Andric     WaterList.erase(IP);
13700b57cec5SDimitry Andric 
13710b57cec5SDimitry Andric   // Okay, we know we can put an island before NewMBB now, do it!
13720b57cec5SDimitry Andric   MF->insert(NewMBB->getIterator(), NewIsland);
13730b57cec5SDimitry Andric 
13740b57cec5SDimitry Andric   // Update internal data structures to account for the newly inserted MBB.
13750b57cec5SDimitry Andric   updateForInsertedWaterBlock(NewIsland);
13760b57cec5SDimitry Andric 
13770b57cec5SDimitry Andric   // Decrement the old entry, and remove it if refcount becomes 0.
13780b57cec5SDimitry Andric   decrementCPEReferenceCount(CPI, CPEMI);
13790b57cec5SDimitry Andric 
13800b57cec5SDimitry Andric   // No existing clone of this CPE is within range.
13810b57cec5SDimitry Andric   // We will be generating a new clone.  Get a UID for it.
13820b57cec5SDimitry Andric   unsigned ID = createPICLabelUId();
13830b57cec5SDimitry Andric 
13840b57cec5SDimitry Andric   // Now that we have an island to add the CPE to, clone the original CPE and
13850b57cec5SDimitry Andric   // add it to the island.
13860b57cec5SDimitry Andric   U.HighWaterMark = NewIsland;
13870b57cec5SDimitry Andric   U.CPEMI = BuildMI(NewIsland, DebugLoc(), TII->get(Mips::CONSTPOOL_ENTRY))
13880b57cec5SDimitry Andric                 .addImm(ID).addConstantPoolIndex(CPI).addImm(Size);
13890b57cec5SDimitry Andric   CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));
13900b57cec5SDimitry Andric   ++NumCPEs;
13910b57cec5SDimitry Andric 
13920b57cec5SDimitry Andric   // Mark the basic block as aligned as required by the const-pool entry.
13938bcb0991SDimitry Andric   NewIsland->setAlignment(getCPEAlign(*U.CPEMI));
13940b57cec5SDimitry Andric 
13950b57cec5SDimitry Andric   // Increase the size of the island block to account for the new entry.
13960b57cec5SDimitry Andric   BBInfo[NewIsland->getNumber()].Size += Size;
13970b57cec5SDimitry Andric   adjustBBOffsetsAfter(&*--NewIsland->getIterator());
13980b57cec5SDimitry Andric 
13990b57cec5SDimitry Andric   // Finally, change the CPI in the instruction operand to be ID.
14000b57cec5SDimitry Andric   for (unsigned i = 0, e = UserMI->getNumOperands(); i != e; ++i)
14010b57cec5SDimitry Andric     if (UserMI->getOperand(i).isCPI()) {
14020b57cec5SDimitry Andric       UserMI->getOperand(i).setIndex(ID);
14030b57cec5SDimitry Andric       break;
14040b57cec5SDimitry Andric     }
14050b57cec5SDimitry Andric 
14060b57cec5SDimitry Andric   LLVM_DEBUG(
14070b57cec5SDimitry Andric       dbgs() << "  Moved CPE to #" << ID << " CPI=" << CPI
14080b57cec5SDimitry Andric              << format(" offset=%#x\n", BBInfo[NewIsland->getNumber()].Offset));
14090b57cec5SDimitry Andric 
14100b57cec5SDimitry Andric   return true;
14110b57cec5SDimitry Andric }
14120b57cec5SDimitry Andric 
14130b57cec5SDimitry Andric /// removeDeadCPEMI - Remove a dead constant pool entry instruction. Update
14140b57cec5SDimitry Andric /// sizes and offsets of impacted basic blocks.
14150b57cec5SDimitry Andric void MipsConstantIslands::removeDeadCPEMI(MachineInstr *CPEMI) {
14160b57cec5SDimitry Andric   MachineBasicBlock *CPEBB = CPEMI->getParent();
14170b57cec5SDimitry Andric   unsigned Size = CPEMI->getOperand(2).getImm();
14180b57cec5SDimitry Andric   CPEMI->eraseFromParent();
14190b57cec5SDimitry Andric   BBInfo[CPEBB->getNumber()].Size -= Size;
14200b57cec5SDimitry Andric   // All succeeding offsets have the current size value added in, fix this.
14210b57cec5SDimitry Andric   if (CPEBB->empty()) {
14220b57cec5SDimitry Andric     BBInfo[CPEBB->getNumber()].Size = 0;
14230b57cec5SDimitry Andric 
14240b57cec5SDimitry Andric     // This block no longer needs to be aligned.
14258bcb0991SDimitry Andric     CPEBB->setAlignment(Align(1));
14268bcb0991SDimitry Andric   } else {
14270b57cec5SDimitry Andric     // Entries are sorted by descending alignment, so realign from the front.
14288bcb0991SDimitry Andric     CPEBB->setAlignment(getCPEAlign(*CPEBB->begin()));
14298bcb0991SDimitry Andric   }
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric   adjustBBOffsetsAfter(CPEBB);
14320b57cec5SDimitry Andric   // An island has only one predecessor BB and one successor BB. Check if
14330b57cec5SDimitry Andric   // this BB's predecessor jumps directly to this BB's successor. This
14340b57cec5SDimitry Andric   // shouldn't happen currently.
14350b57cec5SDimitry Andric   assert(!BBIsJumpedOver(CPEBB) && "How did this happen?");
14360b57cec5SDimitry Andric   // FIXME: remove the empty blocks after all the work is done?
14370b57cec5SDimitry Andric }
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric /// removeUnusedCPEntries - Remove constant pool entries whose refcounts
14400b57cec5SDimitry Andric /// are zero.
14410b57cec5SDimitry Andric bool MipsConstantIslands::removeUnusedCPEntries() {
14420b57cec5SDimitry Andric   unsigned MadeChange = false;
14430b57cec5SDimitry Andric   for (unsigned i = 0, e = CPEntries.size(); i != e; ++i) {
14440b57cec5SDimitry Andric       std::vector<CPEntry> &CPEs = CPEntries[i];
14450b57cec5SDimitry Andric       for (unsigned j = 0, ee = CPEs.size(); j != ee; ++j) {
14460b57cec5SDimitry Andric         if (CPEs[j].RefCount == 0 && CPEs[j].CPEMI) {
14470b57cec5SDimitry Andric           removeDeadCPEMI(CPEs[j].CPEMI);
14480b57cec5SDimitry Andric           CPEs[j].CPEMI = nullptr;
14490b57cec5SDimitry Andric           MadeChange = true;
14500b57cec5SDimitry Andric         }
14510b57cec5SDimitry Andric       }
14520b57cec5SDimitry Andric   }
14530b57cec5SDimitry Andric   return MadeChange;
14540b57cec5SDimitry Andric }
14550b57cec5SDimitry Andric 
14560b57cec5SDimitry Andric /// isBBInRange - Returns true if the distance between specific MI and
14570b57cec5SDimitry Andric /// specific BB can fit in MI's displacement field.
14580b57cec5SDimitry Andric bool MipsConstantIslands::isBBInRange
14590b57cec5SDimitry Andric   (MachineInstr *MI,MachineBasicBlock *DestBB, unsigned MaxDisp) {
14600b57cec5SDimitry Andric   unsigned PCAdj = 4;
14610b57cec5SDimitry Andric   unsigned BrOffset   = getOffsetOf(MI) + PCAdj;
14620b57cec5SDimitry Andric   unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
14630b57cec5SDimitry Andric 
14640b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Branch of destination " << printMBBReference(*DestBB)
14650b57cec5SDimitry Andric                     << " from " << printMBBReference(*MI->getParent())
14660b57cec5SDimitry Andric                     << " max delta=" << MaxDisp << " from " << getOffsetOf(MI)
14670b57cec5SDimitry Andric                     << " to " << DestOffset << " offset "
14680b57cec5SDimitry Andric                     << int(DestOffset - BrOffset) << "\t" << *MI);
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric   if (BrOffset <= DestOffset) {
14710b57cec5SDimitry Andric     // Branch before the Dest.
14720b57cec5SDimitry Andric     if (DestOffset-BrOffset <= MaxDisp)
14730b57cec5SDimitry Andric       return true;
14740b57cec5SDimitry Andric   } else {
14750b57cec5SDimitry Andric     if (BrOffset-DestOffset <= MaxDisp)
14760b57cec5SDimitry Andric       return true;
14770b57cec5SDimitry Andric   }
14780b57cec5SDimitry Andric   return false;
14790b57cec5SDimitry Andric }
14800b57cec5SDimitry Andric 
14810b57cec5SDimitry Andric /// fixupImmediateBr - Fix up an immediate branch whose destination is too far
14820b57cec5SDimitry Andric /// away to fit in its displacement field.
14830b57cec5SDimitry Andric bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {
14840b57cec5SDimitry Andric   MachineInstr *MI = Br.MI;
14850b57cec5SDimitry Andric   unsigned TargetOperand = branchTargetOperand(MI);
14860b57cec5SDimitry Andric   MachineBasicBlock *DestBB = MI->getOperand(TargetOperand).getMBB();
14870b57cec5SDimitry Andric 
14880b57cec5SDimitry Andric   // Check to see if the DestBB is already in-range.
14890b57cec5SDimitry Andric   if (isBBInRange(MI, DestBB, Br.MaxDisp))
14900b57cec5SDimitry Andric     return false;
14910b57cec5SDimitry Andric 
14920b57cec5SDimitry Andric   if (!Br.isCond)
14930b57cec5SDimitry Andric     return fixupUnconditionalBr(Br);
14940b57cec5SDimitry Andric   return fixupConditionalBr(Br);
14950b57cec5SDimitry Andric }
14960b57cec5SDimitry Andric 
14970b57cec5SDimitry Andric /// fixupUnconditionalBr - Fix up an unconditional branch whose destination is
14980b57cec5SDimitry Andric /// too far away to fit in its displacement field. If the LR register has been
14990b57cec5SDimitry Andric /// spilled in the epilogue, then we can use BL to implement a far jump.
15000b57cec5SDimitry Andric /// Otherwise, add an intermediate branch instruction to a branch.
15010b57cec5SDimitry Andric bool
15020b57cec5SDimitry Andric MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
15030b57cec5SDimitry Andric   MachineInstr *MI = Br.MI;
15040b57cec5SDimitry Andric   MachineBasicBlock *MBB = MI->getParent();
15050b57cec5SDimitry Andric   MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();
15060b57cec5SDimitry Andric   // Use BL to implement far jump.
15070b57cec5SDimitry Andric   unsigned BimmX16MaxDisp = ((1 << 16)-1) * 2;
15080b57cec5SDimitry Andric   if (isBBInRange(MI, DestBB, BimmX16MaxDisp)) {
15090b57cec5SDimitry Andric     Br.MaxDisp = BimmX16MaxDisp;
15100b57cec5SDimitry Andric     MI->setDesc(TII->get(Mips::BimmX16));
15110b57cec5SDimitry Andric   }
15120b57cec5SDimitry Andric   else {
15130b57cec5SDimitry Andric     // need to give the math a more careful look here
15140b57cec5SDimitry Andric     // this is really a segment address and not
15150b57cec5SDimitry Andric     // a PC relative address. FIXME. But I think that
15160b57cec5SDimitry Andric     // just reducing the bits by 1 as I've done is correct.
15170b57cec5SDimitry Andric     // The basic block we are branching too much be longword aligned.
15180b57cec5SDimitry Andric     // we know that RA is saved because we always save it right now.
15190b57cec5SDimitry Andric     // this requirement will be relaxed later but we also have an alternate
15200b57cec5SDimitry Andric     // way to implement this that I will implement that does not need jal.
1521480093f4SDimitry Andric     // We should have a way to back out this alignment restriction
1522480093f4SDimitry Andric     // if we "can" later. but it is not harmful.
15230b57cec5SDimitry Andric     //
15248bcb0991SDimitry Andric     DestBB->setAlignment(Align(4));
15250b57cec5SDimitry Andric     Br.MaxDisp = ((1<<24)-1) * 2;
15260b57cec5SDimitry Andric     MI->setDesc(TII->get(Mips::JalB16));
15270b57cec5SDimitry Andric   }
15280b57cec5SDimitry Andric   BBInfo[MBB->getNumber()].Size += 2;
15290b57cec5SDimitry Andric   adjustBBOffsetsAfter(MBB);
15300b57cec5SDimitry Andric   HasFarJump = true;
15310b57cec5SDimitry Andric   ++NumUBrFixed;
15320b57cec5SDimitry Andric 
15330b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "  Changed B to long jump " << *MI);
15340b57cec5SDimitry Andric 
15350b57cec5SDimitry Andric   return true;
15360b57cec5SDimitry Andric }
15370b57cec5SDimitry Andric 
15380b57cec5SDimitry Andric /// fixupConditionalBr - Fix up a conditional branch whose destination is too
15390b57cec5SDimitry Andric /// far away to fit in its displacement field. It is converted to an inverse
15400b57cec5SDimitry Andric /// conditional branch + an unconditional branch to the destination.
15410b57cec5SDimitry Andric bool
15420b57cec5SDimitry Andric MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
15430b57cec5SDimitry Andric   MachineInstr *MI = Br.MI;
15440b57cec5SDimitry Andric   unsigned TargetOperand = branchTargetOperand(MI);
15450b57cec5SDimitry Andric   MachineBasicBlock *DestBB = MI->getOperand(TargetOperand).getMBB();
15460b57cec5SDimitry Andric   unsigned Opcode = MI->getOpcode();
15470b57cec5SDimitry Andric   unsigned LongFormOpcode = longformBranchOpcode(Opcode);
15480b57cec5SDimitry Andric   unsigned LongFormMaxOff = branchMaxOffsets(LongFormOpcode);
15490b57cec5SDimitry Andric 
15500b57cec5SDimitry Andric   // Check to see if the DestBB is already in-range.
15510b57cec5SDimitry Andric   if (isBBInRange(MI, DestBB, LongFormMaxOff)) {
15520b57cec5SDimitry Andric     Br.MaxDisp = LongFormMaxOff;
15530b57cec5SDimitry Andric     MI->setDesc(TII->get(LongFormOpcode));
15540b57cec5SDimitry Andric     return true;
15550b57cec5SDimitry Andric   }
15560b57cec5SDimitry Andric 
15570b57cec5SDimitry Andric   // Add an unconditional branch to the destination and invert the branch
15580b57cec5SDimitry Andric   // condition to jump over it:
15590b57cec5SDimitry Andric   // bteqz L1
15600b57cec5SDimitry Andric   // =>
15610b57cec5SDimitry Andric   // bnez L2
15620b57cec5SDimitry Andric   // b   L1
15630b57cec5SDimitry Andric   // L2:
15640b57cec5SDimitry Andric 
15650b57cec5SDimitry Andric   // If the branch is at the end of its MBB and that has a fall-through block,
15660b57cec5SDimitry Andric   // direct the updated conditional branch to the fall-through block. Otherwise,
15670b57cec5SDimitry Andric   // split the MBB before the next instruction.
15680b57cec5SDimitry Andric   MachineBasicBlock *MBB = MI->getParent();
15690b57cec5SDimitry Andric   MachineInstr *BMI = &MBB->back();
15700b57cec5SDimitry Andric   bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB);
15710b57cec5SDimitry Andric   unsigned OppositeBranchOpcode = TII->getOppositeBranchOpc(Opcode);
15720b57cec5SDimitry Andric 
15730b57cec5SDimitry Andric   ++NumCBrFixed;
15740b57cec5SDimitry Andric   if (BMI != MI) {
15750b57cec5SDimitry Andric     if (std::next(MachineBasicBlock::iterator(MI)) == std::prev(MBB->end()) &&
15760b57cec5SDimitry Andric         BMI->isUnconditionalBranch()) {
15770b57cec5SDimitry Andric       // Last MI in the BB is an unconditional branch. Can we simply invert the
15780b57cec5SDimitry Andric       // condition and swap destinations:
15790b57cec5SDimitry Andric       // beqz L1
15800b57cec5SDimitry Andric       // b   L2
15810b57cec5SDimitry Andric       // =>
15820b57cec5SDimitry Andric       // bnez L2
15830b57cec5SDimitry Andric       // b   L1
15840b57cec5SDimitry Andric       unsigned BMITargetOperand = branchTargetOperand(BMI);
15850b57cec5SDimitry Andric       MachineBasicBlock *NewDest =
15860b57cec5SDimitry Andric         BMI->getOperand(BMITargetOperand).getMBB();
15870b57cec5SDimitry Andric       if (isBBInRange(MI, NewDest, Br.MaxDisp)) {
15880b57cec5SDimitry Andric         LLVM_DEBUG(
15890b57cec5SDimitry Andric             dbgs() << "  Invert Bcc condition and swap its destination with "
15900b57cec5SDimitry Andric                    << *BMI);
15910b57cec5SDimitry Andric         MI->setDesc(TII->get(OppositeBranchOpcode));
15920b57cec5SDimitry Andric         BMI->getOperand(BMITargetOperand).setMBB(DestBB);
15930b57cec5SDimitry Andric         MI->getOperand(TargetOperand).setMBB(NewDest);
15940b57cec5SDimitry Andric         return true;
15950b57cec5SDimitry Andric       }
15960b57cec5SDimitry Andric     }
15970b57cec5SDimitry Andric   }
15980b57cec5SDimitry Andric 
15990b57cec5SDimitry Andric   if (NeedSplit) {
16000b57cec5SDimitry Andric     splitBlockBeforeInstr(*MI);
16010b57cec5SDimitry Andric     // No need for the branch to the next block. We're adding an unconditional
16020b57cec5SDimitry Andric     // branch to the destination.
16030b57cec5SDimitry Andric     int delta = TII->getInstSizeInBytes(MBB->back());
16040b57cec5SDimitry Andric     BBInfo[MBB->getNumber()].Size -= delta;
16050b57cec5SDimitry Andric     MBB->back().eraseFromParent();
16060b57cec5SDimitry Andric     // BBInfo[SplitBB].Offset is wrong temporarily, fixed below
16070b57cec5SDimitry Andric   }
16080b57cec5SDimitry Andric   MachineBasicBlock *NextBB = &*++MBB->getIterator();
16090b57cec5SDimitry Andric 
16100b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "  Insert B to " << printMBBReference(*DestBB)
16110b57cec5SDimitry Andric                     << " also invert condition and change dest. to "
16120b57cec5SDimitry Andric                     << printMBBReference(*NextBB) << "\n");
16130b57cec5SDimitry Andric 
16140b57cec5SDimitry Andric   // Insert a new conditional branch and a new unconditional branch.
16150b57cec5SDimitry Andric   // Also update the ImmBranch as well as adding a new entry for the new branch.
16160b57cec5SDimitry Andric   if (MI->getNumExplicitOperands() == 2) {
16170b57cec5SDimitry Andric     BuildMI(MBB, DebugLoc(), TII->get(OppositeBranchOpcode))
16180b57cec5SDimitry Andric            .addReg(MI->getOperand(0).getReg())
16190b57cec5SDimitry Andric            .addMBB(NextBB);
16200b57cec5SDimitry Andric   } else {
16210b57cec5SDimitry Andric     BuildMI(MBB, DebugLoc(), TII->get(OppositeBranchOpcode))
16220b57cec5SDimitry Andric            .addMBB(NextBB);
16230b57cec5SDimitry Andric   }
16240b57cec5SDimitry Andric   Br.MI = &MBB->back();
16250b57cec5SDimitry Andric   BBInfo[MBB->getNumber()].Size += TII->getInstSizeInBytes(MBB->back());
16260b57cec5SDimitry Andric   BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB);
16270b57cec5SDimitry Andric   BBInfo[MBB->getNumber()].Size += TII->getInstSizeInBytes(MBB->back());
16280b57cec5SDimitry Andric   unsigned MaxDisp = getUnconditionalBrDisp(Br.UncondBr);
16290b57cec5SDimitry Andric   ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr));
16300b57cec5SDimitry Andric 
16310b57cec5SDimitry Andric   // Remove the old conditional branch.  It may or may not still be in MBB.
16320b57cec5SDimitry Andric   BBInfo[MI->getParent()->getNumber()].Size -= TII->getInstSizeInBytes(*MI);
16330b57cec5SDimitry Andric   MI->eraseFromParent();
16340b57cec5SDimitry Andric   adjustBBOffsetsAfter(MBB);
16350b57cec5SDimitry Andric   return true;
16360b57cec5SDimitry Andric }
16370b57cec5SDimitry Andric 
16380b57cec5SDimitry Andric void MipsConstantIslands::prescanForConstants() {
16390b57cec5SDimitry Andric   unsigned J = 0;
16400b57cec5SDimitry Andric   (void)J;
16410b57cec5SDimitry Andric   for (MachineFunction::iterator B =
16420b57cec5SDimitry Andric          MF->begin(), E = MF->end(); B != E; ++B) {
16430b57cec5SDimitry Andric     for (MachineBasicBlock::instr_iterator I =
16440b57cec5SDimitry Andric         B->instr_begin(), EB = B->instr_end(); I != EB; ++I) {
16450b57cec5SDimitry Andric       switch(I->getDesc().getOpcode()) {
16460b57cec5SDimitry Andric         case Mips::LwConstant32: {
16470b57cec5SDimitry Andric           PrescannedForConstants = true;
16480b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << "constant island constant " << *I << "\n");
16490b57cec5SDimitry Andric           J = I->getNumOperands();
16500b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << "num operands " << J << "\n");
16510b57cec5SDimitry Andric           MachineOperand& Literal = I->getOperand(1);
16520b57cec5SDimitry Andric           if (Literal.isImm()) {
16530b57cec5SDimitry Andric             int64_t V = Literal.getImm();
16540b57cec5SDimitry Andric             LLVM_DEBUG(dbgs() << "literal " << V << "\n");
16550b57cec5SDimitry Andric             Type *Int32Ty =
16560b57cec5SDimitry Andric               Type::getInt32Ty(MF->getFunction().getContext());
16570b57cec5SDimitry Andric             const Constant *C = ConstantInt::get(Int32Ty, V);
1658*5ffd83dbSDimitry Andric             unsigned index = MCP->getConstantPoolIndex(C, Align(4));
16590b57cec5SDimitry Andric             I->getOperand(2).ChangeToImmediate(index);
16600b57cec5SDimitry Andric             LLVM_DEBUG(dbgs() << "constant island constant " << *I << "\n");
16610b57cec5SDimitry Andric             I->setDesc(TII->get(Mips::LwRxPcTcp16));
16620b57cec5SDimitry Andric             I->RemoveOperand(1);
16630b57cec5SDimitry Andric             I->RemoveOperand(1);
16640b57cec5SDimitry Andric             I->addOperand(MachineOperand::CreateCPI(index, 0));
16650b57cec5SDimitry Andric             I->addOperand(MachineOperand::CreateImm(4));
16660b57cec5SDimitry Andric           }
16670b57cec5SDimitry Andric           break;
16680b57cec5SDimitry Andric         }
16690b57cec5SDimitry Andric         default:
16700b57cec5SDimitry Andric           break;
16710b57cec5SDimitry Andric       }
16720b57cec5SDimitry Andric     }
16730b57cec5SDimitry Andric   }
16740b57cec5SDimitry Andric }
16750b57cec5SDimitry Andric 
16760b57cec5SDimitry Andric /// Returns a pass that converts branches to long branches.
16770b57cec5SDimitry Andric FunctionPass *llvm::createMipsConstantIslandPass() {
16780b57cec5SDimitry Andric   return new MipsConstantIslands();
16790b57cec5SDimitry Andric }
1680