<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 11/05/2013 01:00 AM, Eric
      Christopher wrote:<br>
    </div>
    <blockquote
cite="mid:CALehDX7oAA4rfVhNij8uOmkqZKdr4z8izHrbPwCz98njLz3mfQ@mail.gmail.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=ISO-8859-1">
      <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>
    </blockquote>
    <br>
    [llvm] r194066 - Remove the word "thumb" from a few remaining
    comments. <br>
    <br>
    The word ARM and thumb no longer appear.<br>
    <br>
    Everything else is in progress. I will be sure to add you to the
    email when I consider this<br>
    port to be done and you can review it in detail.<br>
    <br>
    <blockquote
cite="mid:CALehDX7oAA4rfVhNij8uOmkqZKdr4z8izHrbPwCz98njLz3mfQ@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <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 moz-do-not-send="true"
              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 moz-do-not-send="true"
              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 moz-do-not-send="true"
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 moz-do-not-send="true"
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 moz-do-not-send="true"
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
            (<a class="moz-txt-link-abbreviated" href="mailto:gitosis@dmz-portal.mips.com:clang.git">gitosis@dmz-portal.mips.com:clang.git</a>
            3a50d847e098f36e3bf8bc14eea07a6cc35f7803)
            (<a class="moz-txt-link-abbreviated" href="mailto:gitosis@dmz-portal.mips.com:llvm.git">gitosis@dmz-portal.mips.com:llvm.git</a>
            f52db0b69f0c888bdc98bb2f13aaecc1e83288a9)"}<br>
            <br>
            <br>
            _______________________________________________<br>
            llvm-commits mailing list<br>
            <a moz-do-not-send="true"
              href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
            <a moz-do-not-send="true"
              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>
    </blockquote>
    <br>
  </body>
</html>