<div dir="ltr">Please revert this and remove all of the arm/thumb references and before you reapply again. This is pretty sloppy work and unacceptable for inclusion in mainline. There's a big difference between incremental work and this.<div>
<br></div><div>-eric</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Nov 5, 2013 at 12:14 AM, Reed Kotler <span dir="ltr"><<a href="mailto:rkotler@mips.com" target="_blank">rkotler@mips.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rkotler<br>
Date: Tue Nov  5 02:14:14 2013<br>
New Revision: 194053<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=194053&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=194053&view=rev</a><br>
Log:<br>
Fix r194019 as requested by Eric Christopher.<br>
Submit the basic port of the rest of ARM constant islands code to Mips.<br>
Two test cases are added which reflect the next level of functionality:<br>
constants getting moved to water areas that are out of range from the<br>
initial placement at the end of the function and basic blocks being split to<br>
create water when none exists that can be used. There is a bunch of this<br>
code that is not complete and has been marked with IN_PROGRESS. I will<br>
finish cleaning this all up during the next week or two and submit the<br>
rest of the test cases. I have elminated some code for dealing with<br>
inline assembly because to me it unecessarily complicates things and<br>
some of the newer features of llvm like function attributies and builtin<br>
assembler give me better tools to solve the alignment issues created<br>
there. Also, for Mips16 I even have the option of not doing constant<br>
islands in the present of inline assembler if I chose. When everything<br>
has been completed I will summarize the port and notify people that<br>
are knowledgable regarding the ARM Constant Islands code so they can<br>
review it in it's entirety if they wish.<br>
<br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/Mips/const4.ll<br>
Modified:<br>
    llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td<br>
    llvm/trunk/lib/Target/Mips/MipsConstantIslandPass.cpp<br>
<br>
Modified: llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td?rev=194053&r1=194052&r2=194053&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td?rev=194053&r1=194052&r2=194053&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td (original)<br>
+++ llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td Tue Nov  5 02:14:14 2013<br>
@@ -60,6 +60,11 @@ class FRI16_ins<bits<5> op, string asmst<br>
                 InstrItinClass itin>:<br>
   FRI16_ins_base<op, asmstr, "\t$rx, $imm \t# 16 bit inst", itin>;<br>
<br>
+class FRI16_TCP_ins<bits<5> _op, string asmstr,<br>
+                    InstrItinClass itin>:<br>
+  FRI16<_op, (outs CPU16Regs:$rx), (ins pcrel16:$imm, i32imm:$size),<br>
+            !strconcat(asmstr, "\t$rx, $imm\t# 16 bit inst"), [], itin>;<br>
+<br>
 class FRI16R_ins_base<bits<5> op, string asmstr, string asmstr2,<br>
                      InstrItinClass itin>:<br>
   FRI16<op, (outs), (ins CPU16Regs:$rx, simm16:$imm),<br>
@@ -174,7 +179,7 @@ class FEXT_RI16_B_ins<bits<5> _op, strin<br>
<br>
 class FEXT_RI16_TCP_ins<bits<5> _op, string asmstr,<br>
                         InstrItinClass itin>:<br>
-  FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins pcrel16:$imm),<br>
+  FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins pcrel16:$imm, i32imm:$size),<br>
             !strconcat(asmstr, "\t$rx, $imm"), [], itin>;<br>
<br>
 class FEXT_2RI16_ins<bits<5> _op, string asmstr,<br>
@@ -802,6 +807,8 @@ def LwRxSpImmX16: FEXT_RI16_SP_explicit_<br>
   let Uses = [SP];<br>
 }<br>
<br>
+def LwRxPcTcp16: FRI16_TCP_ins<0b10110, "lw", IILoad>, MayLoad;<br>
+<br>
 def LwRxPcTcpX16: FEXT_RI16_TCP_ins<0b10110, "lw", IILoad>, MayLoad;<br>
 //<br>
 // Format: MOVE r32, rz MIPS16e<br>
@@ -1869,3 +1876,4 @@ let neverHasSideEffects = 1, isNotDuplic<br>
 def CONSTPOOL_ENTRY :<br>
 MipsPseudo16<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,<br>
                       i32imm:$size), "foo", []>;<br>
+<br>
<br>
Modified: llvm/trunk/lib/Target/Mips/MipsConstantIslandPass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsConstantIslandPass.cpp?rev=194053&r1=194052&r2=194053&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsConstantIslandPass.cpp?rev=194053&r1=194052&r2=194053&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Target/Mips/MipsConstantIslandPass.cpp (original)<br>
+++ llvm/trunk/lib/Target/Mips/MipsConstantIslandPass.cpp Tue Nov  5 02:14:14 2013<br>
@@ -27,6 +27,7 @@<br>
<br>
 #include "Mips.h"<br>
 #include "MCTargetDesc/MipsBaseInfo.h"<br>
+#include "MipsMachineFunction.h"<br>
 #include "MipsTargetMachine.h"<br>
 #include "llvm/ADT/Statistic.h"<br>
 #include "llvm/CodeGen/MachineBasicBlock.h"<br>
@@ -42,30 +43,197 @@<br>
 #include "llvm/Target/TargetInstrInfo.h"<br>
 #include "llvm/Target/TargetMachine.h"<br>
 #include "llvm/Target/TargetRegisterInfo.h"<br>
+#include "llvm/Support/Format.h"<br>
 #include <algorithm><br>
<br>
 using namespace llvm;<br>
<br>
 STATISTIC(NumCPEs,       "Number of constpool entries");<br>
+STATISTIC(NumSplit,      "Number of uncond branches inserted");<br>
+STATISTIC(NumCBrFixed,   "Number of cond branches fixed");<br>
+STATISTIC(NumUBrFixed,   "Number of uncond branches fixed");<br>
<br>
 // FIXME: This option should be removed once it has received sufficient testing.<br>
 static cl::opt<bool><br>
 AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true),<br>
           cl::desc("Align constant islands in code"));<br>
<br>
+<br>
+// Rather than do make check tests with huge amounts of code, we force<br>
+// the test to use this amount.<br>
+//<br>
+static cl::opt<int> ConstantIslandsSmallOffset(<br>
+  "mips-constant-islands-small-offset",<br>
+  cl::init(0),<br>
+  cl::desc("Make small offsets be this amount for testing purposes"),<br>
+  cl::Hidden);<br>
+<br>
+/// UnknownPadding - Return the worst case padding that could result from<br>
+/// unknown offset bits.  This does not include alignment padding caused by<br>
+/// known offset bits.<br>
+///<br>
+/// @param LogAlign log2(alignment)<br>
+/// @param KnownBits Number of known low offset bits.<br>
+static inline unsigned UnknownPadding(unsigned LogAlign, unsigned KnownBits) {<br>
+  if (KnownBits < LogAlign)<br>
+    return (1u << LogAlign) - (1u << KnownBits);<br>
+  return 0;<br>
+}<br>
+<br>
 namespace {<br>
+<br>
+<br>
   typedef MachineBasicBlock::iterator Iter;<br>
   typedef MachineBasicBlock::reverse_iterator ReverseIter;<br>
<br>
+  /// MipsConstantIslands - Due to limited PC-relative displacements, Mips<br>
+  /// requires constant pool entries to be scattered among the instructions<br>
+  /// inside a function.  To do this, it completely ignores the normal LLVM<br>
+  /// constant pool; instead, it places constants wherever it feels like with<br>
+  /// special instructions.<br>
+  ///<br>
+  /// The terminology used in this pass includes:<br>
+  ///   Islands - Clumps of constants placed in the function.<br>
+  ///   Water   - Potential places where an island could be formed.<br>
+  ///   CPE     - A constant pool entry that has been placed somewhere, which<br>
+  ///             tracks a list of users.<br>
+<br>
   class MipsConstantIslands : public MachineFunctionPass {<br>
<br>
-  const TargetMachine &TM;<br>
-  bool IsPIC;<br>
-  unsigned ABI;<br>
-  const MipsSubtarget *STI;<br>
-  const MipsInstrInfo *TII;<br>
-  MachineFunction *MF;<br>
-  MachineConstantPool *MCP;<br>
+    /// BasicBlockInfo - Information about the offset and size of a single<br>
+    /// basic block.<br>
+    struct BasicBlockInfo {<br>
+      /// Offset - Distance from the beginning of the function to the beginning<br>
+      /// of this basic block.<br>
+      ///<br>
+      /// Offsets are computed assuming worst case padding before an aligned<br>
+      /// block. This means that subtracting basic block offsets always gives a<br>
+      /// conservative estimate of the real distance which may be smaller.<br>
+      ///<br>
+      /// Because worst case padding is used, the computed offset of an aligned<br>
+      /// block may not actually be aligned.<br>
+      unsigned Offset;<br>
+<br>
+      /// Size - Size of the basic block in bytes.  If the block contains<br>
+      /// inline assembly, this is a worst case estimate.<br>
+      ///<br>
+      /// The size does not include any alignment padding whether from the<br>
+      /// beginning of the block, or from an aligned jump table at the end.<br>
+      unsigned Size;<br>
+<br>
+      /// KnownBits - The number of low bits in Offset that are known to be<br>
+      /// exact.  The remaining bits of Offset are an upper bound.<br>
+      uint8_t KnownBits;<br>
+<br>
+      /// Unalign - When non-zero, the block contains instructions (inline asm)<br>
+      /// of unknown size.  The real size may be smaller than Size bytes by a<br>
+      /// multiple of 1 << Unalign.<br>
+      uint8_t Unalign;<br>
+<br>
+      /// PostAlign - When non-zero, the block terminator contains a .align<br>
+      /// directive, so the end of the block is aligned to 1 << PostAlign<br>
+      /// bytes.<br>
+      uint8_t PostAlign;<br>
+<br>
+      BasicBlockInfo() : Offset(0), Size(0), KnownBits(0), Unalign(0),<br>
+        PostAlign(0) {}<br>
+<br>
+      /// Compute the number of known offset bits internally to this block.<br>
+      /// This number should be used to predict worst case padding when<br>
+      /// splitting the block.<br>
+      unsigned internalKnownBits() const {<br>
+        unsigned Bits = Unalign ? Unalign : KnownBits;<br>
+        // If the block size isn't a multiple of the known bits, assume the<br>
+        // worst case padding.<br>
+        if (Size & ((1u << Bits) - 1))<br>
+          Bits = countTrailingZeros(Size);<br>
+        return Bits;<br>
+      }<br>
+<br>
+      /// Compute the offset immediately following this block.  If LogAlign is<br>
+      /// specified, return the offset the successor block will get if it has<br>
+      /// this alignment.<br>
+      unsigned postOffset(unsigned LogAlign = 0) const {<br>
+        unsigned PO = Offset + Size;<br>
+        return PO;<br>
+      }<br>
+<br>
+      /// Compute the number of known low bits of postOffset.  If this block<br>
+      /// contains inline asm, the number of known bits drops to the<br>
+      /// instruction alignment.  An aligned terminator may increase the number<br>
+      /// of know bits.<br>
+      /// If LogAlign is given, also consider the alignment of the next block.<br>
+      unsigned postKnownBits(unsigned LogAlign = 0) const {<br>
+        return std::max(std::max(unsigned(PostAlign), LogAlign),<br>
+                        internalKnownBits());<br>
+      }<br>
+    };<br>
+<br>
+    std::vector<BasicBlockInfo> BBInfo;<br>
+<br>
+    /// WaterList - A sorted list of basic blocks where islands could be placed<br>
+    /// (i.e. blocks that don't fall through to the following block, due<br>
+    /// to a return, unreachable, or unconditional branch).<br>
+    std::vector<MachineBasicBlock*> WaterList;<br>
+<br>
+    /// NewWaterList - The subset of WaterList that was created since the<br>
+    /// previous iteration by inserting unconditional branches.<br>
+    SmallSet<MachineBasicBlock*, 4> NewWaterList;<br>
+<br>
+    typedef std::vector<MachineBasicBlock*>::iterator water_iterator;<br>
+<br>
+    /// CPUser - One user of a constant pool, keeping the machine instruction<br>
+    /// pointer, the constant pool being referenced, and the max displacement<br>
+    /// allowed from the instruction to the CP.  The HighWaterMark records the<br>
+    /// highest basic block where a new CPEntry can be placed.  To ensure this<br>
+    /// pass terminates, the CP entries are initially placed at the end of the<br>
+    /// function and then move monotonically to lower addresses.  The<br>
+    /// exception to this rule is when the current CP entry for a particular<br>
+    /// CPUser is out of range, but there is another CP entry for the same<br>
+    /// constant value in range.  We want to use the existing in-range CP<br>
+    /// entry, but if it later moves out of range, the search for new water<br>
+    /// should resume where it left off.  The HighWaterMark is used to record<br>
+    /// that point.<br>
+    struct CPUser {<br>
+      MachineInstr *MI;<br>
+      MachineInstr *CPEMI;<br>
+      MachineBasicBlock *HighWaterMark;<br>
+    private:<br>
+      unsigned MaxDisp;<br>
+      unsigned LongFormMaxDisp; // mips16 has 16/32 bit instructions<br>
+                                // with different displacements<br>
+      unsigned LongFormOpcode;<br>
+    public:<br>
+      bool NegOk;<br>
+      bool IsSoImm;<br>
+      bool KnownAlignment;<br>
+      CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp,<br>
+             bool neg, bool soimm,<br>
+             unsigned longformmaxdisp, unsigned longformopcode)<br>
+        : MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),<br>
+          LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),<br>
+          NegOk(neg), IsSoImm(soimm), KnownAlignment(false)  {<br>
+        HighWaterMark = CPEMI->getParent();<br>
+      }<br>
+      /// getMaxDisp - Returns the maximum displacement supported by MI.<br>
+      /// Correct for unknown alignment.<br>
+      /// Conservatively subtract 2 bytes to handle weird alignment effects.<br>
+      unsigned getMaxDisp() const {<br>
+        unsigned xMaxDisp = ConstantIslandsSmallOffset?<br>
+                            ConstantIslandsSmallOffset: MaxDisp;<br>
+        return (KnownAlignment ? xMaxDisp : xMaxDisp - 2) - 2;<br>
+      }<br>
+      unsigned getLongFormMaxDisp() const {<br>
+        return (KnownAlignment ? LongFormMaxDisp : LongFormMaxDisp - 2) - 2;<br>
+      }<br>
+      unsigned getLongFormOpcode() const {<br>
+          return LongFormOpcode;<br>
+      }<br>
+    };<br>
+<br>
+    /// CPUsers - Keep track of all of the machine instructions that use various<br>
+    /// constant pools and their max displacement.<br>
+    std::vector<CPUser> CPUsers;<br>
<br>
   /// CPEntry - One per constant pool entry, keeping the machine instruction<br>
   /// pointer, the constpool index, and the number of CPUser's which<br>
@@ -85,13 +253,56 @@ namespace {<br>
   /// put in the vector of the original element, but have distinct CPIs.<br>
   std::vector<std::vector<CPEntry> > CPEntries;<br>
<br>
+  /// ImmBranch - One per immediate branch, keeping the machine instruction<br>
+  /// pointer, conditional or unconditional, the max displacement,<br>
+  /// and (if isCond is true) the corresponding unconditional branch<br>
+  /// opcode.<br>
+  struct ImmBranch {<br>
+    MachineInstr *MI;<br>
+    unsigned MaxDisp : 31;<br>
+    bool isCond : 1;<br>
+    int UncondBr;<br>
+    ImmBranch(MachineInstr *mi, unsigned maxdisp, bool cond, int ubr)<br>
+      : MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}<br>
+  };<br>
+<br>
+  /// ImmBranches - Keep track of all the immediate branch instructions.<br>
+  ///<br>
+  std::vector<ImmBranch> ImmBranches;<br>
+<br>
+  /// HasFarJump - True if any far jump instruction has been emitted during<br>
+  /// the branch fix up pass.<br>
+  bool HasFarJump;<br>
+<br>
+  const TargetMachine &TM;<br>
+  bool IsPIC;<br>
+  unsigned ABI;<br>
+  const MipsSubtarget *STI;<br>
+  const MipsInstrInfo *TII;<br>
+  MipsFunctionInfo *MFI;<br>
+  MachineFunction *MF;<br>
+  MachineConstantPool *MCP;<br>
+<br>
+  unsigned PICLabelUId;<br>
+  bool PrescannedForConstants;<br>
+<br>
+  void initPICLabelUId(unsigned UId) {<br>
+    PICLabelUId = UId;<br>
+  }<br>
+<br>
+<br>
+  unsigned createPICLabelUId() {<br>
+    return PICLabelUId++;<br>
+  }<br>
+<br>
   public:<br>
     static char ID;<br>
     MipsConstantIslands(TargetMachine &tm)<br>
       : MachineFunctionPass(ID), TM(tm),<br>
         IsPIC(TM.getRelocationModel() == Reloc::PIC_),<br>
         ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()),<br>
-        STI(&TM.getSubtarget<MipsSubtarget>()), MF(0), MCP(0){}<br>
+        STI(&TM.getSubtarget<MipsSubtarget>()), MF(0), MCP(0),<br>
+        PrescannedForConstants(false){}<br>
<br>
     virtual const char *getPassName() const {<br>
       return "Mips Constant Islands";<br>
@@ -100,6 +311,45 @@ namespace {<br>
     bool runOnMachineFunction(MachineFunction &F);<br>
<br>
     void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);<br>
+    CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI);<br>
+    unsigned getCPELogAlign(const MachineInstr *CPEMI);<br>
+    void initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs);<br>
+    unsigned getOffsetOf(MachineInstr *MI) const;<br>
+    unsigned getUserOffset(CPUser&) const;<br>
+    void dumpBBs();<br>
+    void verify();<br>
+<br>
+    bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,<br>
+                         unsigned Disp, bool NegativeOK, bool IsSoImm = false);<br>
+    bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,<br>
+                         const CPUser &U);<br>
+<br>
+    bool isLongFormOffsetInRange(unsigned UserOffset, unsigned TrialOffset,<br>
+                                const CPUser &U);<br>
+<br>
+    void computeBlockSize(MachineBasicBlock *MBB);<br>
+    MachineBasicBlock *splitBlockBeforeInstr(MachineInstr *MI);<br>
+    void updateForInsertedWaterBlock(MachineBasicBlock *NewBB);<br>
+    void adjustBBOffsetsAfter(MachineBasicBlock *BB);<br>
+    bool decrementCPEReferenceCount(unsigned CPI, MachineInstr* CPEMI);<br>
+    int findInRangeCPEntry(CPUser& U, unsigned UserOffset);<br>
+    int findLongFormInRangeCPEntry(CPUser& U, unsigned UserOffset);<br>
+    bool findAvailableWater(CPUser&U, unsigned UserOffset,<br>
+                            water_iterator &WaterIter);<br>
+    void createNewWater(unsigned CPUserIndex, unsigned UserOffset,<br>
+                        MachineBasicBlock *&NewMBB);<br>
+    bool handleConstantPoolUser(unsigned CPUserIndex);<br>
+    void removeDeadCPEMI(MachineInstr *CPEMI);<br>
+    bool removeUnusedCPEntries();<br>
+    bool isCPEntryInRange(MachineInstr *MI, unsigned UserOffset,<br>
+                          MachineInstr *CPEMI, unsigned Disp, bool NegOk,<br>
+                          bool DoDump = false);<br>
+    bool isWaterInRange(unsigned UserOffset, MachineBasicBlock *Water,<br>
+                        CPUser &U, unsigned &Growth);<br>
+    bool isBBInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp);<br>
+    bool fixupImmediateBr(ImmBranch &Br);<br>
+    bool fixupConditionalBr(ImmBranch &Br);<br>
+    bool fixupUnconditionalBr(ImmBranch &Br);<br>
<br>
     void prescanForConstants();<br>
<br>
@@ -110,6 +360,33 @@ namespace {<br>
   char MipsConstantIslands::ID = 0;<br>
 } // end of anonymous namespace<br>
<br>
+<br>
+bool MipsConstantIslands::isLongFormOffsetInRange<br>
+  (unsigned UserOffset, unsigned TrialOffset,<br>
+   const CPUser &U) {<br>
+  return isOffsetInRange(UserOffset, TrialOffset,<br>
+                         U.getLongFormMaxDisp(), U.NegOk, U.IsSoImm);<br>
+}<br>
+<br>
+bool MipsConstantIslands::isOffsetInRange<br>
+  (unsigned UserOffset, unsigned TrialOffset,<br>
+   const CPUser &U) {<br>
+  return isOffsetInRange(UserOffset, TrialOffset,<br>
+                         U.getMaxDisp(), U.NegOk, U.IsSoImm);<br>
+}<br>
+/// print block size and offset information - debugging<br>
+void MipsConstantIslands::dumpBBs() {<br>
+  DEBUG({<br>
+    for (unsigned J = 0, E = BBInfo.size(); J !=E; ++J) {<br>
+      const BasicBlockInfo &BBI = BBInfo[J];<br>
+      dbgs() << format("%08x BB#%u\t", BBI.Offset, J)<br>
+             << " kb=" << unsigned(BBI.KnownBits)<br>
+             << " ua=" << unsigned(BBI.Unalign)<br>
+             << " pa=" << unsigned(BBI.PostAlign)<br>
+             << format(" size=%#x\n", BBInfo[J].Size);<br>
+    }<br>
+  });<br>
+}<br>
 /// createMipsLongBranchPass - Returns a pass that converts branches to long<br>
 /// branches.<br>
 FunctionPass *llvm::createMipsConstantIslandPass(MipsTargetMachine &tm) {<br>
@@ -127,13 +404,15 @@ bool MipsConstantIslands::runOnMachineFu<br>
     return false;<br>
   }<br>
   TII = (const MipsInstrInfo*)MF->getTarget().getInstrInfo();<br>
+  MFI = MF->getInfo<MipsFunctionInfo>();<br>
   DEBUG(dbgs() << "constant island processing " << "\n");<br>
   //<br>
   // will need to make predermination if there is any constants we need to<br>
   // put in constant islands. TBD.<br>
   //<br>
-  prescanForConstants();<br>
+  if (!PrescannedForConstants) prescanForConstants();<br>
<br>
+  HasFarJump = false;<br>
   // This pass invalidates liveness information when it splits basic blocks.<br>
   MF->getRegInfo().invalidateLiveness();<br>
<br>
@@ -141,13 +420,66 @@ bool MipsConstantIslands::runOnMachineFu<br>
   // the numbers agree with the position of the block in the function.<br>
   MF->RenumberBlocks();<br>
<br>
+  bool MadeChange = false;<br>
+<br>
   // Perform the initial placement of the constant pool entries.  To start with,<br>
   // we put them all at the end of the function.<br>
   std::vector<MachineInstr*> CPEMIs;<br>
   if (!MCP->isEmpty())<br>
     doInitialPlacement(CPEMIs);<br>
<br>
-  return true;<br>
+  /// The next UID to take is the first unused one.<br>
+  initPICLabelUId(CPEMIs.size());<br>
+<br>
+  // Do the initial scan of the function, building up information about the<br>
+  // sizes of each block, the location of all the water, and finding all of the<br>
+  // constant pool users.<br>
+  initializeFunctionInfo(CPEMIs);<br>
+  CPEMIs.clear();<br>
+  DEBUG(dumpBBs());<br>
+<br>
+  /// Remove dead constant pool entries.<br>
+  MadeChange |= removeUnusedCPEntries();<br>
+<br>
+  // Iteratively place constant pool entries and fix up branches until there<br>
+  // is no change.<br>
+  unsigned NoCPIters = 0, NoBRIters = 0;<br>
+  (void)NoBRIters;<br>
+  while (true) {<br>
+    DEBUG(dbgs() << "Beginning CP iteration #" << NoCPIters << '\n');<br>
+    bool CPChange = false;<br>
+    for (unsigned i = 0, e = CPUsers.size(); i != e; ++i)<br>
+      CPChange |= handleConstantPoolUser(i);<br>
+    if (CPChange && ++NoCPIters > 30)<br>
+      report_fatal_error("Constant Island pass failed to converge!");<br>
+    DEBUG(dumpBBs());<br>
+<br>
+    // Clear NewWaterList now.  If we split a block for branches, it should<br>
+    // appear as "new water" for the next iteration of constant pool placement.<br>
+    NewWaterList.clear();<br>
+<br>
+    DEBUG(dbgs() << "Beginning BR iteration #" << NoBRIters << '\n');<br>
+    bool BRChange = false;<br>
+#ifdef IN_PROGRESS<br>
+    for (unsigned i = 0, e = ImmBranches.size(); i != e; ++i)<br>
+      BRChange |= fixupImmediateBr(ImmBranches[i]);<br>
+    if (BRChange && ++NoBRIters > 30)<br>
+      report_fatal_error("Branch Fix Up pass failed to converge!");<br>
+    DEBUG(dumpBBs());<br>
+#endif<br>
+    if (!CPChange && !BRChange)<br>
+      break;<br>
+    MadeChange = true;<br>
+  }<br>
+<br>
+  DEBUG(dbgs() << '\n'; dumpBBs());<br>
+<br>
+  BBInfo.clear();<br>
+  WaterList.clear();<br>
+  CPUsers.clear();<br>
+  CPEntries.clear();<br>
+  ImmBranches.clear();<br>
+  return MadeChange;<br>
 }<br>
<br>
 /// doInitialPlacement - Perform the initial placement of the constant pool<br>
@@ -216,9 +548,1034 @@ MipsConstantIslands::doInitialPlacement(<br>
   DEBUG(BB->dump());<br>
 }<br>
<br>
+/// BBHasFallthrough - Return true if the specified basic block can fallthrough<br>
+/// into the block immediately after it.<br>
+static bool BBHasFallthrough(MachineBasicBlock *MBB) {<br>
+  // Get the next machine basic block in the function.<br>
+  MachineFunction::iterator MBBI = MBB;<br>
+  // Can't fall off end of function.<br>
+  if (llvm::next(MBBI) == MBB->getParent()->end())<br>
+    return false;<br>
+<br>
+  MachineBasicBlock *NextBB = llvm::next(MBBI);<br>
+  for (MachineBasicBlock::succ_iterator I = MBB->succ_begin(),<br>
+       E = MBB->succ_end(); I != E; ++I)<br>
+    if (*I == NextBB)<br>
+      return true;<br>
+<br>
+  return false;<br>
+}<br>
+<br>
+/// findConstPoolEntry - Given the constpool index and CONSTPOOL_ENTRY MI,<br>
+/// look up the corresponding CPEntry.<br>
+MipsConstantIslands::CPEntry<br>
+*MipsConstantIslands::findConstPoolEntry(unsigned CPI,<br>
+                                        const MachineInstr *CPEMI) {<br>
+  std::vector<CPEntry> &CPEs = CPEntries[CPI];<br>
+  // Number of entries per constpool index should be small, just do a<br>
+  // linear search.<br>
+  for (unsigned i = 0, e = CPEs.size(); i != e; ++i) {<br>
+    if (CPEs[i].CPEMI == CPEMI)<br>
+      return &CPEs[i];<br>
+  }<br>
+  return NULL;<br>
+}<br>
+<br>
+/// getCPELogAlign - Returns the required alignment of the constant pool entry<br>
+/// represented by CPEMI.  Alignment is measured in log2(bytes) units.<br>
+unsigned MipsConstantIslands::getCPELogAlign(const MachineInstr *CPEMI) {<br>
+  assert(CPEMI && CPEMI->getOpcode() == Mips::CONSTPOOL_ENTRY);<br>
+<br>
+  // Everything is 4-byte aligned unless AlignConstantIslands is set.<br>
+  if (!AlignConstantIslands)<br>
+    return 2;<br>
+<br>
+  unsigned CPI = CPEMI->getOperand(1).getIndex();<br>
+  assert(CPI < MCP->getConstants().size() && "Invalid constant pool index.");<br>
+  unsigned Align = MCP->getConstants()[CPI].getAlignment();<br>
+  assert(isPowerOf2_32(Align) && "Invalid CPE alignment");<br>
+  return Log2_32(Align);<br>
+}<br>
+<br>
+/// initializeFunctionInfo - Do the initial scan of the function, building up<br>
+/// information about the sizes of each block, the location of all the water,<br>
+/// and finding all of the constant pool users.<br>
+void MipsConstantIslands::<br>
+initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {<br>
+  BBInfo.clear();<br>
+  BBInfo.resize(MF->getNumBlockIDs());<br>
+<br>
+  // First thing, compute the size of all basic blocks, and see if the function<br>
+  // has any inline assembly in it. If so, we have to be conservative about<br>
+  // alignment assumptions, as we don't know for sure the size of any<br>
+  // instructions in the inline assembly.<br>
+  for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I)<br>
+    computeBlockSize(I);<br>
+<br>
+  // The known bits of the entry block offset are determined by the function<br>
+  // alignment.<br>
+  BBInfo.front().KnownBits = MF->getAlignment();<br>
+<br>
+  // Compute block offsets.<br>
+  adjustBBOffsetsAfter(MF->begin());<br>
+<br>
+  // Now go back through the instructions and build up our data structures.<br>
+  for (MachineFunction::iterator MBBI = MF->begin(), E = MF->end();<br>
+       MBBI != E; ++MBBI) {<br>
+    MachineBasicBlock &MBB = *MBBI;<br>
+<br>
+    // If this block doesn't fall through into the next MBB, then this is<br>
+    // 'water' that a constant pool island could be placed.<br>
+    if (!BBHasFallthrough(&MBB))<br>
+      WaterList.push_back(&MBB);<br>
+    for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();<br>
+         I != E; ++I) {<br>
+      if (I->isDebugValue())<br>
+        continue;<br>
+<br>
+      int Opc = I->getOpcode();<br>
+      if (I->isBranch()) {<br>
+        bool isCond = false;<br>
+        unsigned Bits = 0;<br>
+        unsigned Scale = 1;<br>
+        int UOpc = Opc;<br>
+<br>
+        switch (Opc) {<br>
+        default:<br>
+          continue;  // Ignore other JT branches<br>
+        }<br>
+        // Record this immediate branch.<br>
+        unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;<br>
+        ImmBranches.push_back(ImmBranch(I, MaxOffs, isCond, UOpc));<br>
+<br>
+      }<br>
+<br>
+<br>
+      if (Opc == Mips::CONSTPOOL_ENTRY)<br>
+        continue;<br>
+<br>
+<br>
+      // Scan the instructions for constant pool operands.<br>
+      for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op)<br>
+        if (I->getOperand(op).isCPI()) {<br>
+<br>
+          // We found one.  The addressing mode tells us the max displacement<br>
+          // from the PC that this instruction permits.<br>
+<br>
+          // Basic size info comes from the TSFlags field.<br>
+          unsigned Bits = 0;<br>
+          unsigned Scale = 1;<br>
+          bool NegOk = false;<br>
+          bool IsSoImm = false;<br>
+          unsigned LongFormBits = 0;<br>
+          unsigned LongFormScale = 0;<br>
+          unsigned LongFormOpcode = 0;<br>
+          switch (Opc) {<br>
+          default:<br>
+            llvm_unreachable("Unknown addressing mode for CP reference!");<br>
+          case Mips::LwRxPcTcp16:<br>
+            Bits = 8;<br>
+            Scale = 2;<br>
+            LongFormOpcode = Mips::LwRxPcTcpX16;<br>
+            break;<br>
+          case Mips::LwRxPcTcpX16:<br>
+            Bits = 16;<br>
+            Scale = 2;<br>
+            break;<br>
+          }<br>
+          // Remember that this is a user of a CP entry.<br>
+          unsigned CPI = I->getOperand(op).getIndex();<br>
+          MachineInstr *CPEMI = CPEMIs[CPI];<br>
+          unsigned MaxOffs = ((1 << Bits)-1) * Scale;<br>
+          unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;<br>
+          CPUsers.push_back(CPUser(I, CPEMI, MaxOffs, NegOk,<br>
+                                   IsSoImm, LongFormMaxOffs,<br>
+                                   LongFormOpcode));<br>
+<br>
+          // Increment corresponding CPEntry reference count.<br>
+          CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);<br>
+          assert(CPE && "Cannot find a corresponding CPEntry!");<br>
+          CPE->RefCount++;<br>
+<br>
+          // Instructions can only use one CP entry, don't bother scanning the<br>
+          // rest of the operands.<br>
+          break;<br>
+<br>
+        }<br>
+<br>
+    }<br>
+  }<br>
+<br>
+}<br>
+<br>
+/// computeBlockSize - Compute the size and some alignment information for MBB.<br>
+/// This function updates BBInfo directly.<br>
+void MipsConstantIslands::computeBlockSize(MachineBasicBlock *MBB) {<br>
+  BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];<br>
+  BBI.Size = 0;<br>
+  BBI.Unalign = 0;<br>
+  BBI.PostAlign = 0;<br>
+<br>
+  for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;<br>
+       ++I)<br>
+    BBI.Size += TII->GetInstSizeInBytes(I);<br>
+<br>
+}<br>
+<br>
+/// getOffsetOf - Return the current offset of the specified machine instruction<br>
+/// from the start of the function.  This offset changes as stuff is moved<br>
+/// around inside the function.<br>
+unsigned MipsConstantIslands::getOffsetOf(MachineInstr *MI) const {<br>
+  MachineBasicBlock *MBB = MI->getParent();<br>
+<br>
+  // The offset is composed of two things: the sum of the sizes of all MBB's<br>
+  // before this instruction's block, and the offset from the start of the block<br>
+  // it is in.<br>
+  unsigned Offset = BBInfo[MBB->getNumber()].Offset;<br>
+<br>
+  // Sum instructions before MI in MBB.<br>
+  for (MachineBasicBlock::iterator I = MBB->begin(); &*I != MI; ++I) {<br>
+    assert(I != MBB->end() && "Didn't find MI in its own basic block?");<br>
+    Offset += TII->GetInstSizeInBytes(I);<br>
+  }<br>
+  return Offset;<br>
+}<br>
+<br>
+/// CompareMBBNumbers - Little predicate function to sort the WaterList by MBB<br>
+/// ID.<br>
+static bool CompareMBBNumbers(const MachineBasicBlock *LHS,<br>
+                              const MachineBasicBlock *RHS) {<br>
+  return LHS->getNumber() < RHS->getNumber();<br>
+}<br>
+<br>
+/// updateForInsertedWaterBlock - When a block is newly inserted into the<br>
+/// machine function, it upsets all of the block numbers.  Renumber the blocks<br>
+/// and update the arrays that parallel this numbering.<br>
+void MipsConstantIslands::updateForInsertedWaterBlock<br>
+  (MachineBasicBlock *NewBB) {<br>
+  // Renumber the MBB's to keep them consecutive.<br>
+  NewBB->getParent()->RenumberBlocks(NewBB);<br>
+<br>
+  // Insert an entry into BBInfo to align it properly with the (newly<br>
+  // renumbered) block numbers.<br>
+  BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());<br>
+<br>
+  // Next, update WaterList.  Specifically, we need to add NewMBB as having<br>
+  // available water after it.<br>
+  water_iterator IP =<br>
+    std::lower_bound(WaterList.begin(), WaterList.end(), NewBB,<br>
+                     CompareMBBNumbers);<br>
+  WaterList.insert(IP, NewBB);<br>
+}<br>
+<br>
+/// getUserOffset - Compute the offset of U.MI as seen by the hardware<br>
+/// displacement computation.  Update U.KnownAlignment to match its current<br>
+/// basic block location.<br>
+unsigned MipsConstantIslands::getUserOffset(CPUser &U) const {<br>
+  unsigned UserOffset = getOffsetOf(U.MI);<br>
+  const BasicBlockInfo &BBI = BBInfo[U.MI->getParent()->getNumber()];<br>
+  unsigned KnownBits = BBI.internalKnownBits();<br>
+<br>
+  // The value read from PC is offset from the actual instruction address.<br>
+<br>
+<br>
+  // Because of inline assembly, we may not know the alignment (mod 4) of U.MI.<br>
+  // Make sure U.getMaxDisp() returns a constrained range.<br>
+  U.KnownAlignment = (KnownBits >= 2);<br>
+<br>
+  // On Thumb, offsets==2 mod 4 are rounded down by the hardware for<br>
+  // purposes of the displacement computation; compensate for that here.<br>
+  // For unknown alignments, getMaxDisp() constrains the range instead.<br>
+<br>
+<br>
+  return UserOffset;<br>
+}<br>
+<br>
+/// Split the basic block containing MI into two blocks, which are joined by<br>
+/// an unconditional branch.  Update data structures and renumber blocks to<br>
+/// account for this change and returns the newly created block.<br>
+MachineBasicBlock *MipsConstantIslands::splitBlockBeforeInstr<br>
+  (MachineInstr *MI) {<br>
+  MachineBasicBlock *OrigBB = MI->getParent();<br>
+<br>
+  // Create a new MBB for the code after the OrigBB.<br>
+  MachineBasicBlock *NewBB =<br>
+    MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());<br>
+  MachineFunction::iterator MBBI = OrigBB; ++MBBI;<br>
+  MF->insert(MBBI, NewBB);<br>
+<br>
+  // Splice the instructions starting with MI over to NewBB.<br>
+  NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end());<br>
+<br>
+  // Add an unconditional branch from OrigBB to NewBB.<br>
+  // Note the new unconditional branch is not being recorded.<br>
+  // There doesn't seem to be meaningful DebugInfo available; this doesn't<br>
+  // correspond to anything in the source.<br>
+  BuildMI(OrigBB, DebugLoc(), TII->get(Mips::BimmX16)).addMBB(NewBB);<br>
+  ++NumSplit;<br>
+<br>
+  // Update the CFG.  All succs of OrigBB are now succs of NewBB.<br>
+  NewBB->transferSuccessors(OrigBB);<br>
+<br>
+  // OrigBB branches to NewBB.<br>
+  OrigBB->addSuccessor(NewBB);<br>
+<br>
+  // Update internal data structures to account for the newly inserted MBB.<br>
+  // This is almost the same as updateForInsertedWaterBlock, except that<br>
+  // the Water goes after OrigBB, not NewBB.<br>
+  MF->RenumberBlocks(NewBB);<br>
+<br>
+  // Insert an entry into BBInfo to align it properly with the (newly<br>
+  // renumbered) block numbers.<br>
+  BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());<br>
+<br>
+  // Next, update WaterList.  Specifically, we need to add OrigMBB as having<br>
+  // available water after it (but not if it's already there, which happens<br>
+  // when splitting before a conditional branch that is followed by an<br>
+  // unconditional branch - in that case we want to insert NewBB).<br>
+  water_iterator IP =<br>
+    std::lower_bound(WaterList.begin(), WaterList.end(), OrigBB,<br>
+                     CompareMBBNumbers);<br>
+  MachineBasicBlock* WaterBB = *IP;<br>
+  if (WaterBB == OrigBB)<br>
+    WaterList.insert(llvm::next(IP), NewBB);<br>
+  else<br>
+    WaterList.insert(IP, OrigBB);<br>
+  NewWaterList.insert(OrigBB);<br>
+<br>
+  // Figure out how large the OrigBB is.  As the first half of the original<br>
+  // block, it cannot contain a tablejump.  The size includes<br>
+  // the new jump we added.  (It should be possible to do this without<br>
+  // recounting everything, but it's very confusing, and this is rarely<br>
+  // executed.)<br>
+  computeBlockSize(OrigBB);<br>
+<br>
+  // Figure out how large the NewMBB is.  As the second half of the original<br>
+  // block, it may contain a tablejump.<br>
+  computeBlockSize(NewBB);<br>
+<br>
+  // All BBOffsets following these blocks must be modified.<br>
+  adjustBBOffsetsAfter(OrigBB);<br>
+<br>
+  return NewBB;<br>
+}<br>
+<br>
+<br>
+<br>
+/// isOffsetInRange - Checks whether UserOffset (the location of a constant pool<br>
+/// reference) is within MaxDisp of TrialOffset (a proposed location of a<br>
+/// constant pool entry).<br>
+/// UserOffset is computed by getUserOffset above to include PC adjustments. If<br>
+/// the mod 4 alignment of UserOffset is not known, the uncertainty must be<br>
+/// subtracted from MaxDisp instead. CPUser::getMaxDisp() does that.<br>
+bool MipsConstantIslands::isOffsetInRange(unsigned UserOffset,<br>
+                                         unsigned TrialOffset, unsigned MaxDisp,<br>
+                                         bool NegativeOK, bool IsSoImm) {<br>
+  if (UserOffset <= TrialOffset) {<br>
+    // User before the Trial.<br>
+    if (TrialOffset - UserOffset <= MaxDisp)<br>
+      return true;<br>
+    // FIXME: Make use full range of soimm values.<br>
+  } else if (NegativeOK) {<br>
+    if (UserOffset - TrialOffset <= MaxDisp)<br>
+      return true;<br>
+    // FIXME: Make use full range of soimm values.<br>
+  }<br>
+  return false;<br>
+}<br>
+<br>
+/// isWaterInRange - Returns true if a CPE placed after the specified<br>
+/// Water (a basic block) will be in range for the specific MI.<br>
+///<br>
+/// Compute how much the function will grow by inserting a CPE after Water.<br>
+bool MipsConstantIslands::isWaterInRange(unsigned UserOffset,<br>
+                                        MachineBasicBlock* Water, CPUser &U,<br>
+                                        unsigned &Growth) {<br>
+  unsigned CPELogAlign = getCPELogAlign(U.CPEMI);<br>
+  unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset(CPELogAlign);<br>
+  unsigned NextBlockOffset, NextBlockAlignment;<br>
+  MachineFunction::const_iterator NextBlock = Water;<br>
+  if (++NextBlock == MF->end()) {<br>
+    NextBlockOffset = BBInfo[Water->getNumber()].postOffset();<br>
+    NextBlockAlignment = 0;<br>
+  } else {<br>
+    NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;<br>
+    NextBlockAlignment = NextBlock->getAlignment();<br>
+  }<br>
+  unsigned Size = U.CPEMI->getOperand(2).getImm();<br>
+  unsigned CPEEnd = CPEOffset + Size;<br>
+<br>
+  // The CPE may be able to hide in the alignment padding before the next<br>
+  // block. It may also cause more padding to be required if it is more aligned<br>
+  // that the next block.<br>
+  if (CPEEnd > NextBlockOffset) {<br>
+    Growth = CPEEnd - NextBlockOffset;<br>
+    // Compute the padding that would go at the end of the CPE to align the next<br>
+    // block.<br>
+    Growth += OffsetToAlignment(CPEEnd, 1u << NextBlockAlignment);<br>
+<br>
+    // If the CPE is to be inserted before the instruction, that will raise<br>
+    // the offset of the instruction. Also account for unknown alignment padding<br>
+    // in blocks between CPE and the user.<br>
+    if (CPEOffset < UserOffset)<br>
+      UserOffset += Growth + UnknownPadding(MF->getAlignment(), CPELogAlign);<br>
+  } else<br>
+    // CPE fits in existing padding.<br>
+    Growth = 0;<br>
+<br>
+  return isOffsetInRange(UserOffset, CPEOffset, U);<br>
+}<br>
+<br>
+/// isCPEntryInRange - Returns true if the distance between specific MI and<br>
+/// specific ConstPool entry instruction can fit in MI's displacement field.<br>
+bool MipsConstantIslands::isCPEntryInRange<br>
+  (MachineInstr *MI, unsigned UserOffset,<br>
+   MachineInstr *CPEMI, unsigned MaxDisp,<br>
+   bool NegOk, bool DoDump) {<br>
+  unsigned CPEOffset  = getOffsetOf(CPEMI);<br>
+<br>
+  if (DoDump) {<br>
+    DEBUG({<br>
+      unsigned Block = MI->getParent()->getNumber();<br>
+      const BasicBlockInfo &BBI = BBInfo[Block];<br>
+      dbgs() << "User of CPE#" << CPEMI->getOperand(0).getImm()<br>
+             << " max delta=" << MaxDisp<br>
+             << format(" insn address=%#x", UserOffset)<br>
+             << " in BB#" << Block << ": "<br>
+             << format("%#x-%x\t", BBI.Offset, BBI.postOffset()) << *MI<br>
+             << format("CPE address=%#x offset=%+d: ", CPEOffset,<br>
+                       int(CPEOffset-UserOffset));<br>
+    });<br>
+  }<br>
+<br>
+  return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);<br>
+}<br>
+<br>
+#ifndef NDEBUG<br>
+/// BBIsJumpedOver - Return true of the specified basic block's only predecessor<br>
+/// unconditionally branches to its only successor.<br>
+static bool BBIsJumpedOver(MachineBasicBlock *MBB) {<br>
+  if (MBB->pred_size() != 1 || MBB->succ_size() != 1)<br>
+    return false;<br>
+  MachineBasicBlock *Succ = *MBB->succ_begin();<br>
+  MachineBasicBlock *Pred = *MBB->pred_begin();<br>
+  MachineInstr *PredMI = &Pred->back();<br>
+  if (PredMI->getOpcode() == Mips::BimmX16)<br>
+    return PredMI->getOperand(0).getMBB() == Succ;<br>
+  return false;<br>
+}<br>
+#endif<br>
+<br>
+void MipsConstantIslands::adjustBBOffsetsAfter(MachineBasicBlock *BB) {<br>
+  unsigned BBNum = BB->getNumber();<br>
+  for(unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++i) {<br>
+    // Get the offset and known bits at the end of the layout predecessor.<br>
+    // Include the alignment of the current block.<br>
+    unsigned Offset = BBInfo[i - 1].postOffset();<br>
+    BBInfo[i].Offset = Offset;<br>
+  }<br>
+}<br>
+<br>
+/// decrementCPEReferenceCount - find the constant pool entry with index CPI<br>
+/// and instruction CPEMI, and decrement its refcount.  If the refcount<br>
+/// becomes 0 remove the entry and instruction.  Returns true if we removed<br>
+/// the entry, false if we didn't.<br>
+<br>
+bool MipsConstantIslands::decrementCPEReferenceCount(unsigned CPI,<br>
+                                                    MachineInstr *CPEMI) {<br>
+  // Find the old entry. Eliminate it if it is no longer used.<br>
+  CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);<br>
+  assert(CPE && "Unexpected!");<br>
+  if (--CPE->RefCount == 0) {<br>
+    removeDeadCPEMI(CPEMI);<br>
+    CPE->CPEMI = NULL;<br>
+    --NumCPEs;<br>
+    return true;<br>
+  }<br>
+  return false;<br>
+}<br>
+<br>
+/// LookForCPEntryInRange - see if the currently referenced CPE is in range;<br>
+/// if not, see if an in-range clone of the CPE is in range, and if so,<br>
+/// change the data structures so the user references the clone.  Returns:<br>
+/// 0 = no existing entry found<br>
+/// 1 = entry found, and there were no code insertions or deletions<br>
+/// 2 = entry found, and there were code insertions or deletions<br>
+int MipsConstantIslands::findInRangeCPEntry(CPUser& U, unsigned UserOffset)<br>
+{<br>
+  MachineInstr *UserMI = U.MI;<br>
+  MachineInstr *CPEMI  = U.CPEMI;<br>
+<br>
+  // Check to see if the CPE is already in-range.<br>
+  if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk,<br>
+                       true)) {<br>
+    DEBUG(dbgs() << "In range\n");<br>
+    return 1;<br>
+  }<br>
+<br>
+  // No.  Look for previously created clones of the CPE that are in range.<br>
+  unsigned CPI = CPEMI->getOperand(1).getIndex();<br>
+  std::vector<CPEntry> &CPEs = CPEntries[CPI];<br>
+  for (unsigned i = 0, e = CPEs.size(); i != e; ++i) {<br>
+    // We already tried this one<br>
+    if (CPEs[i].CPEMI == CPEMI)<br>
+      continue;<br>
+    // Removing CPEs can leave empty entries, skip<br>
+    if (CPEs[i].CPEMI == NULL)<br>
+      continue;<br>
+    if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI, U.getMaxDisp(),<br>
+                     U.NegOk)) {<br>
+      DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#"<br>
+                   << CPEs[i].CPI << "\n");<br>
+      // Point the CPUser node to the replacement<br>
+      U.CPEMI = CPEs[i].CPEMI;<br>
+      // Change the CPI in the instruction operand to refer to the clone.<br>
+      for (unsigned j = 0, e = UserMI->getNumOperands(); j != e; ++j)<br>
+        if (UserMI->getOperand(j).isCPI()) {<br>
+          UserMI->getOperand(j).setIndex(CPEs[i].CPI);<br>
+          break;<br>
+        }<br>
+      // Adjust the refcount of the clone...<br>
+      CPEs[i].RefCount++;<br>
+      // ...and the original.  If we didn't remove the old entry, none of the<br>
+      // addresses changed, so we don't need another pass.<br>
+      return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;<br>
+    }<br>
+  }<br>
+  return 0;<br>
+}<br>
+<br>
+/// LookForCPEntryInRange - see if the currently referenced CPE is in range;<br>
+/// This version checks if the longer form of the instruction can be used to<br>
+/// to satisfy things.<br>
+/// if not, see if an in-range clone of the CPE is in range, and if so,<br>
+/// change the data structures so the user references the clone.  Returns:<br>
+/// 0 = no existing entry found<br>
+/// 1 = entry found, and there were no code insertions or deletions<br>
+/// 2 = entry found, and there were code insertions or deletions<br>
+int MipsConstantIslands::findLongFormInRangeCPEntry<br>
+  (CPUser& U, unsigned UserOffset)<br>
+{<br>
+  MachineInstr *UserMI = U.MI;<br>
+  MachineInstr *CPEMI  = U.CPEMI;<br>
+<br>
+  // Check to see if the CPE is already in-range.<br>
+  if (isCPEntryInRange(UserMI, UserOffset, CPEMI,<br>
+                       U.getLongFormMaxDisp(), U.NegOk,<br>
+                       true)) {<br>
+    DEBUG(dbgs() << "In range\n");<br>
+    UserMI->setDesc(TII->get(U.getLongFormOpcode()));<br>
+    return 2;  // instruction is longer length now<br>
+  }<br>
+<br>
+  // No.  Look for previously created clones of the CPE that are in range.<br>
+  unsigned CPI = CPEMI->getOperand(1).getIndex();<br>
+  std::vector<CPEntry> &CPEs = CPEntries[CPI];<br>
+  for (unsigned i = 0, e = CPEs.size(); i != e; ++i) {<br>
+    // We already tried this one<br>
+    if (CPEs[i].CPEMI == CPEMI)<br>
+      continue;<br>
+    // Removing CPEs can leave empty entries, skip<br>
+    if (CPEs[i].CPEMI == NULL)<br>
+      continue;<br>
+    if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI,<br>
+                         U.getLongFormMaxDisp(), U.NegOk)) {<br>
+      DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#"<br>
+                   << CPEs[i].CPI << "\n");<br>
+      // Point the CPUser node to the replacement<br>
+      U.CPEMI = CPEs[i].CPEMI;<br>
+      // Change the CPI in the instruction operand to refer to the clone.<br>
+      for (unsigned j = 0, e = UserMI->getNumOperands(); j != e; ++j)<br>
+        if (UserMI->getOperand(j).isCPI()) {<br>
+          UserMI->getOperand(j).setIndex(CPEs[i].CPI);<br>
+          break;<br>
+        }<br>
+      // Adjust the refcount of the clone...<br>
+      CPEs[i].RefCount++;<br>
+      // ...and the original.  If we didn't remove the old entry, none of the<br>
+      // addresses changed, so we don't need another pass.<br>
+      return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;<br>
+    }<br>
+  }<br>
+  return 0;<br>
+}<br>
+<br>
+/// getUnconditionalBrDisp - Returns the maximum displacement that can fit in<br>
+/// the specific unconditional branch instruction.<br>
+static inline unsigned getUnconditionalBrDisp(int Opc) {<br>
+  switch (Opc) {<br>
+  case Mips::BimmX16:<br>
+    return ((1<<16)-1)*2;<br>
+  default:<br>
+    break;<br>
+  }<br>
+  return ((1<<16)-1)*2;<br>
+}<br>
+<br>
+/// findAvailableWater - Look for an existing entry in the WaterList in which<br>
+/// we can place the CPE referenced from U so it's within range of U's MI.<br>
+/// Returns true if found, false if not.  If it returns true, WaterIter<br>
+/// is set to the WaterList entry.  For Thumb, prefer water that will not<br>
+/// introduce padding to water that will.  To ensure that this pass<br>
+/// terminates, the CPE location for a particular CPUser is only allowed to<br>
+/// move to a lower address, so search backward from the end of the list and<br>
+/// prefer the first water that is in range.<br>
+bool MipsConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset,<br>
+                                      water_iterator &WaterIter) {<br>
+  if (WaterList.empty())<br>
+    return false;<br>
+<br>
+  unsigned BestGrowth = ~0u;<br>
+  for (water_iterator IP = prior(WaterList.end()), B = WaterList.begin();;<br>
+       --IP) {<br>
+    MachineBasicBlock* WaterBB = *IP;<br>
+    // Check if water is in range and is either at a lower address than the<br>
+    // current "high water mark" or a new water block that was created since<br>
+    // the previous iteration by inserting an unconditional branch.  In the<br>
+    // latter case, we want to allow resetting the high water mark back to<br>
+    // this new water since we haven't seen it before.  Inserting branches<br>
+    // should be relatively uncommon and when it does happen, we want to be<br>
+    // sure to take advantage of it for all the CPEs near that block, so that<br>
+    // we don't insert more branches than necessary.<br>
+    unsigned Growth;<br>
+    if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&<br>
+        (WaterBB->getNumber() < U.HighWaterMark->getNumber() ||<br>
+         NewWaterList.count(WaterBB)) && Growth < BestGrowth) {<br>
+      // This is the least amount of required padding seen so far.<br>
+      BestGrowth = Growth;<br>
+      WaterIter = IP;<br>
+      DEBUG(dbgs() << "Found water after BB#" << WaterBB->getNumber()<br>
+                   << " Growth=" << Growth << '\n');<br>
+<br>
+      // Keep looking unless it is perfect.<br>
+      if (BestGrowth == 0)<br>
+        return true;<br>
+    }<br>
+    if (IP == B)<br>
+      break;<br>
+  }<br>
+  return BestGrowth != ~0u;<br>
+}<br>
+<br>
+/// createNewWater - No existing WaterList entry will work for<br>
+/// CPUsers[CPUserIndex], so create a place to put the CPE.  The end of the<br>
+/// block is used if in range, and the conditional branch munged so control<br>
+/// flow is correct.  Otherwise the block is split to create a hole with an<br>
+/// unconditional branch around it.  In either case NewMBB is set to a<br>
+/// block following which the new island can be inserted (the WaterList<br>
+/// is not adjusted).<br>
+void MipsConstantIslands::createNewWater(unsigned CPUserIndex,<br>
+                                        unsigned UserOffset,<br>
+                                        MachineBasicBlock *&NewMBB) {<br>
+  CPUser &U = CPUsers[CPUserIndex];<br>
+  MachineInstr *UserMI = U.MI;<br>
+  MachineInstr *CPEMI  = U.CPEMI;<br>
+  unsigned CPELogAlign = getCPELogAlign(CPEMI);<br>
+  MachineBasicBlock *UserMBB = UserMI->getParent();<br>
+  const BasicBlockInfo &UserBBI = BBInfo[UserMBB->getNumber()];<br>
+<br>
+  // If the block does not end in an unconditional branch already, and if the<br>
+  // end of the block is within range, make new water there.  (The addition<br>
+  // below is for the unconditional branch we will be adding: 4 bytes on ARM +<br>
+  // Thumb2, 2 on Thumb1.<br>
+  if (BBHasFallthrough(UserMBB)) {<br>
+    // Size of branch to insert.<br>
+    unsigned Delta = 2;<br>
+    // Compute the offset where the CPE will begin.<br>
+    unsigned CPEOffset = UserBBI.postOffset(CPELogAlign) + Delta;<br>
+<br>
+    if (isOffsetInRange(UserOffset, CPEOffset, U)) {<br>
+      DEBUG(dbgs() << "Split at end of BB#" << UserMBB->getNumber()<br>
+            << format(", expected CPE offset %#x\n", CPEOffset));<br>
+      NewMBB = llvm::next(MachineFunction::iterator(UserMBB));<br>
+      // Add an unconditional branch from UserMBB to fallthrough block.  Record<br>
+      // it for branch lengthening; this new branch will not get out of range,<br>
+      // but if the preceding conditional branch is out of range, the targets<br>
+      // will be exchanged, and the altered branch may be out of range, so the<br>
+      // machinery has to know about it.<br>
+      int UncondBr = Mips::BimmX16;<br>
+      BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB);<br>
+      unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);<br>
+      ImmBranches.push_back(ImmBranch(&UserMBB->back(),<br>
+                                      MaxDisp, false, UncondBr));<br>
+      BBInfo[UserMBB->getNumber()].Size += Delta;<br>
+      adjustBBOffsetsAfter(UserMBB);<br>
+      return;<br>
+    }<br>
+  }<br>
+<br>
+  // What a big block.  Find a place within the block to split it.  This is a<br>
+  // little tricky on Thumb1 since instructions are 2 bytes and constant pool<br>
+  // entries are 4 bytes: if instruction I references island CPE, and<br>
+  // instruction I+1 references CPE', it will not work well to put CPE as far<br>
+  // forward as possible, since then CPE' cannot immediately follow it (that<br>
+  // location is 2 bytes farther away from I+1 than CPE was from I) and we'd<br>
+  // need to create a new island.  So, we make a first guess, then walk through<br>
+  // the instructions between the one currently being looked at and the<br>
+  // possible insertion point, and make sure any other instructions that<br>
+  // reference CPEs will be able to use the same island area; if not, we back<br>
+  // up the insertion point.<br>
+<br>
+  // Try to split the block so it's fully aligned.  Compute the latest split<br>
+  // point where we can add a 4-byte branch instruction, and then align to<br>
+  // LogAlign which is the largest possible alignment in the function.<br>
+  unsigned LogAlign = MF->getAlignment();<br>
+  assert(LogAlign >= CPELogAlign && "Over-aligned constant pool entry");<br>
+  unsigned KnownBits = UserBBI.internalKnownBits();<br>
+  unsigned UPad = UnknownPadding(LogAlign, KnownBits);<br>
+  unsigned BaseInsertOffset = UserOffset + U.getMaxDisp() - UPad;<br>
+  DEBUG(dbgs() << format("Split in middle of big block before %#x",<br>
+                         BaseInsertOffset));<br>
+<br>
+  // The 4 in the following is for the unconditional branch we'll be inserting<br>
+  // (allows for long branch on Thumb1).  Alignment of the island is handled<br>
+  // inside isOffsetInRange.<br>
+  BaseInsertOffset -= 4;<br>
+<br>
+  DEBUG(dbgs() << format(", adjusted to %#x", BaseInsertOffset)<br>
+               << " la=" << LogAlign<br>
+               << " kb=" << KnownBits<br>
+               << " up=" << UPad << '\n');<br>
+<br>
+  // This could point off the end of the block if we've already got constant<br>
+  // pool entries following this block; only the last one is in the water list.<br>
+  // Back past any possible branches (allow for a conditional and a maximally<br>
+  // long unconditional).<br>
+  if (BaseInsertOffset + 8 >= UserBBI.postOffset()) {<br>
+    BaseInsertOffset = UserBBI.postOffset() - UPad - 8;<br>
+    DEBUG(dbgs() << format("Move inside block: %#x\n", BaseInsertOffset));<br>
+  }<br>
+  unsigned EndInsertOffset = BaseInsertOffset + 4 + UPad +<br>
+    CPEMI->getOperand(2).getImm();<br>
+  MachineBasicBlock::iterator MI = UserMI;<br>
+  ++MI;<br>
+  unsigned CPUIndex = CPUserIndex+1;<br>
+  unsigned NumCPUsers = CPUsers.size();<br>
+  //MachineInstr *LastIT = 0;<br>
+  for (unsigned Offset = UserOffset+TII->GetInstSizeInBytes(UserMI);<br>
+       Offset < BaseInsertOffset;<br>
+       Offset += TII->GetInstSizeInBytes(MI),<br>
+       MI = llvm::next(MI)) {<br>
+    assert(MI != UserMBB->end() && "Fell off end of block");<br>
+    if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {<br>
+      CPUser &U = CPUsers[CPUIndex];<br>
+      if (!isOffsetInRange(Offset, EndInsertOffset, U)) {<br>
+        // Shift intertion point by one unit of alignment so it is within reach.<br>
+        BaseInsertOffset -= 1u << LogAlign;<br>
+        EndInsertOffset  -= 1u << LogAlign;<br>
+      }<br>
+      // This is overly conservative, as we don't account for CPEMIs being<br>
+      // reused within the block, but it doesn't matter much.  Also assume CPEs<br>
+      // are added in order with alignment padding.  We may eventually be able<br>
+      // to pack the aligned CPEs better.<br>
+      EndInsertOffset += U.CPEMI->getOperand(2).getImm();<br>
+      CPUIndex++;<br>
+    }<br>
+  }<br>
+<br>
+  --MI;<br>
+  NewMBB = splitBlockBeforeInstr(MI);<br>
+}<br>
+<br>
+/// handleConstantPoolUser - Analyze the specified user, checking to see if it<br>
+/// is out-of-range.  If so, pick up the constant pool value and move it some<br>
+/// place in-range.  Return true if we changed any addresses (thus must run<br>
+/// another pass of branch lengthening), false otherwise.<br>
+bool MipsConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) {<br>
+  CPUser &U = CPUsers[CPUserIndex];<br>
+  MachineInstr *UserMI = U.MI;<br>
+  MachineInstr *CPEMI  = U.CPEMI;<br>
+  unsigned CPI = CPEMI->getOperand(1).getIndex();<br>
+  unsigned Size = CPEMI->getOperand(2).getImm();<br>
+  // Compute this only once, it's expensive.<br>
+  unsigned UserOffset = getUserOffset(U);<br>
+<br>
+  // See if the current entry is within range, or there is a clone of it<br>
+  // in range.<br>
+  int result = findInRangeCPEntry(U, UserOffset);<br>
+  if (result==1) return false;<br>
+  else if (result==2) return true;<br>
+<br>
+<br>
+  // Look for water where we can place this CPE.<br>
+  MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock();<br>
+  MachineBasicBlock *NewMBB;<br>
+  water_iterator IP;<br>
+  if (findAvailableWater(U, UserOffset, IP)) {<br>
+    DEBUG(dbgs() << "Found water in range\n");<br>
+    MachineBasicBlock *WaterBB = *IP;<br>
+<br>
+    // If the original WaterList entry was "new water" on this iteration,<br>
+    // propagate that to the new island.  This is just keeping NewWaterList<br>
+    // updated to match the WaterList, which will be updated below.<br>
+    if (NewWaterList.erase(WaterBB))<br>
+      NewWaterList.insert(NewIsland);<br>
+<br>
+    // The new CPE goes before the following block (NewMBB).<br>
+    NewMBB = llvm::next(MachineFunction::iterator(WaterBB));<br>
+<br>
+  } else {<br>
+    // No water found.<br>
+    // we first see if a longer form of the instrucion could have reached<br>
+    // the constant. in that case we won't bother to split<br>
+#ifdef IN_PROGRESS<br>
+    result = findLongFormInRangeCPEntry(U, UserOffset);<br>
+#endif<br>
+    DEBUG(dbgs() << "No water found\n");<br>
+    createNewWater(CPUserIndex, UserOffset, NewMBB);<br>
+<br>
+    // splitBlockBeforeInstr adds to WaterList, which is important when it is<br>
+    // called while handling branches so that the water will be seen on the<br>
+    // next iteration for constant pools, but in this context, we don't want<br>
+    // it.  Check for this so it will be removed from the WaterList.<br>
+    // Also remove any entry from NewWaterList.<br>
+    MachineBasicBlock *WaterBB = prior(MachineFunction::iterator(NewMBB));<br>
+    IP = std::find(WaterList.begin(), WaterList.end(), WaterBB);<br>
+    if (IP != WaterList.end())<br>
+      NewWaterList.erase(WaterBB);<br>
+<br>
+    // We are adding new water.  Update NewWaterList.<br>
+    NewWaterList.insert(NewIsland);<br>
+  }<br>
+<br>
+  // Remove the original WaterList entry; we want subsequent insertions in<br>
+  // this vicinity to go after the one we're about to insert.  This<br>
+  // considerably reduces the number of times we have to move the same CPE<br>
+  // more than once and is also important to ensure the algorithm terminates.<br>
+  if (IP != WaterList.end())<br>
+    WaterList.erase(IP);<br>
+<br>
+  // Okay, we know we can put an island before NewMBB now, do it!<br>
+  MF->insert(NewMBB, NewIsland);<br>
+<br>
+  // Update internal data structures to account for the newly inserted MBB.<br>
+  updateForInsertedWaterBlock(NewIsland);<br>
+<br>
+  // Decrement the old entry, and remove it if refcount becomes 0.<br>
+  decrementCPEReferenceCount(CPI, CPEMI);<br>
+<br>
+  // Now that we have an island to add the CPE to, clone the original CPE and<br>
+  // add it to the island.<br>
+  U.HighWaterMark = NewIsland;<br>
+  U.CPEMI = BuildMI(NewIsland, DebugLoc(), TII->get(Mips::CONSTPOOL_ENTRY))<br>
+                .addImm(ID).addConstantPoolIndex(CPI).addImm(Size);<br>
+  CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));<br>
+  ++NumCPEs;<br>
+<br>
+  // Mark the basic block as aligned as required by the const-pool entry.<br>
+  NewIsland->setAlignment(getCPELogAlign(U.CPEMI));<br>
+<br>
+  // Increase the size of the island block to account for the new entry.<br>
+  BBInfo[NewIsland->getNumber()].Size += Size;<br>
+  adjustBBOffsetsAfter(llvm::prior(MachineFunction::iterator(NewIsland)));<br>
+<br>
+  // No existing clone of this CPE is within range.<br>
+  // We will be generating a new clone.  Get a UID for it.<br>
+  unsigned ID = createPICLabelUId();<br>
+<br>
+  // Finally, change the CPI in the instruction operand to be ID.<br>
+  for (unsigned i = 0, e = UserMI->getNumOperands(); i != e; ++i)<br>
+    if (UserMI->getOperand(i).isCPI()) {<br>
+      UserMI->getOperand(i).setIndex(ID);<br>
+      break;<br>
+    }<br>
+<br>
+  DEBUG(dbgs() << "  Moved CPE to #" << ID << " CPI=" << CPI<br>
+        << format(" offset=%#x\n", BBInfo[NewIsland->getNumber()].Offset));<br>
+<br>
+  return true;<br>
+}<br>
+<br>
+/// removeDeadCPEMI - Remove a dead constant pool entry instruction. Update<br>
+/// sizes and offsets of impacted basic blocks.<br>
+void MipsConstantIslands::removeDeadCPEMI(MachineInstr *CPEMI) {<br>
+  MachineBasicBlock *CPEBB = CPEMI->getParent();<br>
+  unsigned Size = CPEMI->getOperand(2).getImm();<br>
+  CPEMI->eraseFromParent();<br>
+  BBInfo[CPEBB->getNumber()].Size -= Size;<br>
+  // All succeeding offsets have the current size value added in, fix this.<br>
+  if (CPEBB->empty()) {<br>
+    BBInfo[CPEBB->getNumber()].Size = 0;<br>
+<br>
+    // This block no longer needs to be aligned.<br>
+    CPEBB->setAlignment(0);<br>
+  } else<br>
+    // Entries are sorted by descending alignment, so realign from the front.<br>
+    CPEBB->setAlignment(getCPELogAlign(CPEBB->begin()));<br>
+<br>
+  adjustBBOffsetsAfter(CPEBB);<br>
+  // An island has only one predecessor BB and one successor BB. Check if<br>
+  // this BB's predecessor jumps directly to this BB's successor. This<br>
+  // shouldn't happen currently.<br>
+  assert(!BBIsJumpedOver(CPEBB) && "How did this happen?");<br>
+  // FIXME: remove the empty blocks after all the work is done?<br>
+}<br>
+<br>
+/// removeUnusedCPEntries - Remove constant pool entries whose refcounts<br>
+/// are zero.<br>
+bool MipsConstantIslands::removeUnusedCPEntries() {<br>
+  unsigned MadeChange = false;<br>
+  for (unsigned i = 0, e = CPEntries.size(); i != e; ++i) {<br>
+      std::vector<CPEntry> &CPEs = CPEntries[i];<br>
+      for (unsigned j = 0, ee = CPEs.size(); j != ee; ++j) {<br>
+        if (CPEs[j].RefCount == 0 && CPEs[j].CPEMI) {<br>
+          removeDeadCPEMI(CPEs[j].CPEMI);<br>
+          CPEs[j].CPEMI = NULL;<br>
+          MadeChange = true;<br>
+        }<br>
+      }<br>
+  }<br>
+  return MadeChange;<br>
+}<br>
+<br>
+/// isBBInRange - Returns true if the distance between specific MI and<br>
+/// specific BB can fit in MI's displacement field.<br>
+bool MipsConstantIslands::isBBInRange<br>
+  (MachineInstr *MI,MachineBasicBlock *DestBB, unsigned MaxDisp) {<br>
+<br>
+unsigned PCAdj = 4;<br>
+<br>
+  unsigned BrOffset   = getOffsetOf(MI) + PCAdj;<br>
+  unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;<br>
+<br>
+  DEBUG(dbgs() << "Branch of destination BB#" << DestBB->getNumber()<br>
+               << " from BB#" << MI->getParent()->getNumber()<br>
+               << " max delta=" << MaxDisp<br>
+               << " from " << getOffsetOf(MI) << " to " << DestOffset<br>
+               << " offset " << int(DestOffset-BrOffset) << "\t" << *MI);<br>
+<br>
+  if (BrOffset <= DestOffset) {<br>
+    // Branch before the Dest.<br>
+    if (DestOffset-BrOffset <= MaxDisp)<br>
+      return true;<br>
+  } else {<br>
+    if (BrOffset-DestOffset <= MaxDisp)<br>
+      return true;<br>
+  }<br>
+  return false;<br>
+}<br>
+<br>
+/// fixupImmediateBr - Fix up an immediate branch whose destination is too far<br>
+/// away to fit in its displacement field.<br>
+bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {<br>
+  MachineInstr *MI = Br.MI;<br>
+  MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();<br>
+<br>
+  // Check to see if the DestBB is already in-range.<br>
+  if (isBBInRange(MI, DestBB, Br.MaxDisp))<br>
+    return false;<br>
+<br>
+  if (!Br.isCond)<br>
+    return fixupUnconditionalBr(Br);<br>
+  return fixupConditionalBr(Br);<br>
+}<br>
+<br>
+/// fixupUnconditionalBr - Fix up an unconditional branch whose destination is<br>
+/// too far away to fit in its displacement field. If the LR register has been<br>
+/// spilled in the epilogue, then we can use BL to implement a far jump.<br>
+/// Otherwise, add an intermediate branch instruction to a branch.<br>
+bool<br>
+MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {<br>
+  MachineInstr *MI = Br.MI;<br>
+  MachineBasicBlock *MBB = MI->getParent();<br>
+  // Use BL to implement far jump.<br>
+  Br.MaxDisp = ((1 << 16)-1) * 2;<br>
+  MI->setDesc(TII->get(Mips::BimmX16));<br>
+  BBInfo[MBB->getNumber()].Size += 2;<br>
+  adjustBBOffsetsAfter(MBB);<br>
+  HasFarJump = true;<br>
+  ++NumUBrFixed;<br>
+<br>
+  DEBUG(dbgs() << "  Changed B to long jump " << *MI);<br>
+<br>
+  return true;<br>
+}<br>
+<br>
+/// fixupConditionalBr - Fix up a conditional branch whose destination is too<br>
+/// far away to fit in its displacement field. It is converted to an inverse<br>
+/// conditional branch + an unconditional branch to the destination.<br>
+bool<br>
+MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {<br>
+  MachineInstr *MI = Br.MI;<br>
+  MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();<br>
+<br>
+  // Add an unconditional branch to the destination and invert the branch<br>
+  // condition to jump over it:<br>
+  // blt L1<br>
+  // =><br>
+  // bge L2<br>
+  // b   L1<br>
+  // L2:<br>
+  unsigned CCReg = 0;  // FIXME<br>
+  unsigned CC=0; //FIXME<br>
+<br>
+  // If the branch is at the end of its MBB and that has a fall-through block,<br>
+  // direct the updated conditional branch to the fall-through block. Otherwise,<br>
+  // split the MBB before the next instruction.<br>
+  MachineBasicBlock *MBB = MI->getParent();<br>
+  MachineInstr *BMI = &MBB->back();<br>
+  bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB);<br>
+<br>
+  ++NumCBrFixed;<br>
+  if (BMI != MI) {<br>
+    if (llvm::next(MachineBasicBlock::iterator(MI)) == prior(MBB->end()) &&<br>
+        BMI->getOpcode() == Br.UncondBr) {<br>
+      // Last MI in the BB is an unconditional branch. Can we simply invert the<br>
+      // condition and swap destinations:<br>
+      // beq L1<br>
+      // b   L2<br>
+      // =><br>
+      // bne L2<br>
+      // b   L1<br>
+      MachineBasicBlock *NewDest = BMI->getOperand(0).getMBB();<br>
+      if (isBBInRange(MI, NewDest, Br.MaxDisp)) {<br>
+        DEBUG(dbgs() << "  Invert Bcc condition and swap its destination with "<br>
+                     << *BMI);<br>
+        BMI->getOperand(0).setMBB(DestBB);<br>
+        MI->getOperand(0).setMBB(NewDest);<br>
+        return true;<br>
+      }<br>
+    }<br>
+  }<br>
+<br>
+  if (NeedSplit) {<br>
+    splitBlockBeforeInstr(MI);<br>
+    // No need for the branch to the next block. We're adding an unconditional<br>
+    // branch to the destination.<br>
+    int delta = TII->GetInstSizeInBytes(&MBB->back());<br>
+    BBInfo[MBB->getNumber()].Size -= delta;<br>
+    MBB->back().eraseFromParent();<br>
+    // BBInfo[SplitBB].Offset is wrong temporarily, fixed below<br>
+  }<br>
+  MachineBasicBlock *NextBB = llvm::next(MachineFunction::iterator(MBB));<br>
+<br>
+  DEBUG(dbgs() << "  Insert B to BB#" << DestBB->getNumber()<br>
+               << " also invert condition and change dest. to BB#"<br>
+               << NextBB->getNumber() << "\n");<br>
+<br>
+  // Insert a new conditional branch and a new unconditional branch.<br>
+  // Also update the ImmBranch as well as adding a new entry for the new branch.<br>
+  BuildMI(MBB, DebugLoc(), TII->get(MI->getOpcode()))<br>
+    .addMBB(NextBB).addImm(CC).addReg(CCReg);<br>
+  Br.MI = &MBB->back();<br>
+  BBInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());<br>
+  BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB);<br>
+  BBInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());<br>
+  unsigned MaxDisp = getUnconditionalBrDisp(Br.UncondBr);<br>
+  ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr));<br>
+<br>
+  // Remove the old conditional branch.  It may or may not still be in MBB.<br>
+  BBInfo[MI->getParent()->getNumber()].Size -= TII->GetInstSizeInBytes(MI);<br>
+  MI->eraseFromParent();<br>
+  adjustBBOffsetsAfter(MBB);<br>
+  return true;<br>
+}<br>
+<br>
<br>
 void MipsConstantIslands::prescanForConstants() {<br>
-  unsigned int J;<br>
+  unsigned J = 0;<br>
+  (void)J;<br>
+  PrescannedForConstants = true;<br>
   for (MachineFunction::iterator B =<br>
          MF->begin(), E = MF->end(); B != E; ++B) {<br>
     for (MachineBasicBlock::instr_iterator I =<br>
@@ -238,10 +1595,11 @@ void MipsConstantIslands::prescanForCons<br>
             unsigned index = MCP->getConstantPoolIndex(C, 4);<br>
             I->getOperand(2).ChangeToImmediate(index);<br>
             DEBUG(dbgs() << "constant island constant " << *I << "\n");<br>
-            I->setDesc(TII->get(Mips::LwRxPcTcpX16));<br>
+            I->setDesc(TII->get(Mips::LwRxPcTcp16));<br>
             I->RemoveOperand(1);<br>
             I->RemoveOperand(1);<br>
             I->addOperand(MachineOperand::CreateCPI(index, 0));<br>
+            I->addOperand(MachineOperand::CreateImm(4));<br>
           }<br>
           break;<br>
         }<br>
@@ -251,3 +1609,4 @@ void MipsConstantIslands::prescanForCons<br>
     }<br>
   }<br>
 }<br>
+<br>
<br>
Added: llvm/trunk/test/CodeGen/Mips/const4.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/const4.ll?rev=194053&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/const4.ll?rev=194053&view=auto</a><br>

==============================================================================<br>
--- llvm/trunk/test/CodeGen/Mips/const4.ll (added)<br>
+++ llvm/trunk/test/CodeGen/Mips/const4.ll Tue Nov  5 02:14:14 2013<br>
@@ -0,0 +1,64 @@<br>
+; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=static -mips16-constant-islands -mips-constant-islands-small-offset=20  < %s | FileCheck %s -check-prefix=offset20<br>

+<br>
+; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=static -mips16-constant-islands -mips-constant-islands-small-offset=40  < %s | FileCheck %s -check-prefix=offset40<br>

+<br>
+<br>
+@i = common global i32 0, align 4<br>
+@b = common global i32 0, align 4<br>
+<br>
+; Function Attrs: nounwind<br>
+define void @t() #0 {<br>
+entry:<br>
+  store i32 -559023410, i32* @i, align 4<br>
+  %0 = load i32* @b, align 4<br>
+  %tobool = icmp ne i32 %0, 0<br>
+  br i1 %tobool, label %if.then, label %if.else<br>
+; offset20: lw ${{[0-9]+}}, $CPI0_1    # 16 bit inst<br>
+; offset20:    b       $BB0_2<br>
+; offset20:    .align  2<br>
+; offset20: $CPI0_0:<br>
+; offset20:    .4byte  3735943886<br>
+; offset20: $BB0_2:<br>
+<br>
+; offset40:    beqz    ${{[0-9]+}}, $BB0_3<br>
+; offset40:    jal     foo<br>
+; offset40:    nop<br>
+; offset40:    b       $BB0_4<br>
+; offset40:    .align  2<br>
+; offset40: $CPI0_0:<br>
+; offset40:    .4byte  3735943886<br>
+; offset40: $BB0_3:<br>
+; offset40:    jal     goo<br>
+<br>
+if.then:                                          ; preds = %entry<br>
+  call void bitcast (void (...)* @foo to void ()*)()<br>
+  br label %if.end<br>
+<br>
+if.else:                                          ; preds = %entry<br>
+  call void bitcast (void (...)* @goo to void ()*)()<br>
+  br label %if.end<br>
+<br>
+if.end:                                           ; preds = %if.else, %if.then<br>
+  call void bitcast (void (...)* @hoo to void ()*)()<br>
+  call void bitcast (void (...)* @hoo to void ()*)()<br>
+  call void bitcast (void (...)* @hoo to void ()*)()<br>
+  call void bitcast (void (...)* @hoo to void ()*)()<br>
+  call void bitcast (void (...)* @hoo to void ()*)()<br>
+  call void bitcast (void (...)* @hoo to void ()*)()<br>
+  call void bitcast (void (...)* @hoo to void ()*)()<br>
+  call void bitcast (void (...)* @hoo to void ()*)()<br>
+  ret void<br>
+}<br>
+<br>
+declare void @foo(...) #1<br>
+<br>
+declare void @goo(...) #1<br>
+<br>
+declare void @hoo(...) #1<br>
+<br>
+attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="true" }<br>

+attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="true" }<br>

+<br>
+!llvm.ident = !{!0}<br>
+<br>
+!0 = metadata !{metadata !"clang version 3.4 (gitosis@dmz-portal.mips.com:clang.git 3a50d847e098f36e3bf8bc14eea07a6cc35f7803) (gitosis@dmz-portal.mips.com:llvm.git f52db0b69f0c888bdc98bb2f13aaecc1e83288a9)"}<br>

<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>