<p dir="ltr">Seriously? You beat me by 2 minutes! :-) <br>
</p>
<div class="gmail_quote">On 22 May 2015 12:29 am, "Peter Collingbourne" <<a href="mailto:peter@pcc.me.uk">peter@pcc.me.uk</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Tim,<br>
<br>
I bisected a miscompile of the Android port of Chromium to this change. I've<br>
reverted it in r237972, and I will get you more details as soon as I can.<br>
<br>
Thanks,<br>
Peter<br>
<br>
On Mon, May 18, 2015 at 05:10:41PM -0000, Tim Northover wrote:<br>
> Author: tnorthover<br>
> Date: Mon May 18 12:10:40 2015<br>
> New Revision: 237590<br>
><br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D237590-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=e_eJyB9F9m5oUqyNWOm_ofXSSzTlkNAjbW0cKjcRYBE&e=" target="_blank">http://llvm.org/viewvc/llvm-project?rev=237590&view=rev</a><br>
> Log:<br>
> ARM: allow jump tables to be placed as constant islands.<br>
><br>
> Previously, they were forced to immediately follow the actual branch<br>
> instruction. This was usually OK (the LEAs actually accessing them got emitted<br>
> nearby, and weren't usually separated much afterwards). Unfortunately, a<br>
> sufficiently nasty phi elimination dumps many instructions right before the<br>
> basic block terminator, and this can increase the range too much.<br>
><br>
> This patch frees them up to be placed as usual by the constant islands pass,<br>
> and consequently has to slightly modify the form of TBB/TBH tables to refer to<br>
> a PC-relative label at the final jump. The other jump table formats were<br>
> already position-independent.<br>
><br>
> rdar://20813304<br>
><br>
> Added:<br>
>     llvm/trunk/test/CodeGen/ARM/jump-table-islands.ll<br>
> Modified:<br>
>     llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp<br>
>     llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h<br>
>     llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp<br>
>     llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp<br>
>     llvm/trunk/lib/Target/ARM/ARMInstrInfo.td<br>
>     llvm/trunk/lib/Target/ARM/ARMInstrThumb.td<br>
>     llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td<br>
>     llvm/trunk/test/CodeGen/ARM/jumptable-label.ll<br>
>     llvm/trunk/test/CodeGen/Thumb2/constant-islands-jump-table.ll<br>
>     llvm/trunk/test/CodeGen/Thumb2/thumb2-tbh.ll<br>
><br>
> Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_ARM_ARMAsmPrinter.cpp-3Frev-3D237590-26r1-3D237589-26r2-3D237590-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=fcweLq5U9dwlOFsw7qvc1vJVwWag0Huqs-uz9AuyNM4&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=237590&r1=237589&r2=237590&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)<br>
> +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Mon May 18 12:10:40 2015<br>
> @@ -922,17 +922,14 @@ EmitMachineConstantPoolValue(MachineCons<br>
>    OutStreamer->EmitValue(Expr, Size);<br>
>  }<br>
><br>
> -void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {<br>
> -  unsigned Opcode = MI->getOpcode();<br>
> -  int OpNum = 1;<br>
> -  if (Opcode == ARM::BR_JTadd)<br>
> -    OpNum = 2;<br>
> -  else if (Opcode == ARM::BR_JTm)<br>
> -    OpNum = 3;<br>
> -<br>
> -  const MachineOperand &MO1 = MI->getOperand(OpNum);<br>
> +void ARMAsmPrinter::EmitJumpTableAddrs(const MachineInstr *MI) {<br>
> +  const MachineOperand &MO1 = MI->getOperand(1);<br>
>    unsigned JTI = MO1.getIndex();<br>
><br>
> +  // Make sure the Thumb jump table is 4-byte aligned. This will be a nop for<br>
> +  // ARM mode tables.<br>
> +  EmitAlignment(2);<br>
> +<br>
>    // Emit a label for the jump table.<br>
>    MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);<br>
>    OutStreamer->EmitLabel(JTISymbol);<br>
> @@ -972,10 +969,8 @@ void ARMAsmPrinter::EmitJumpTable(const<br>
>    OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);<br>
>  }<br>
><br>
> -void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {<br>
> -  unsigned Opcode = MI->getOpcode();<br>
> -  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;<br>
> -  const MachineOperand &MO1 = MI->getOperand(OpNum);<br>
> +void ARMAsmPrinter::EmitJumpTableInsts(const MachineInstr *MI) {<br>
> +  const MachineOperand &MO1 = MI->getOperand(1);<br>
>    unsigned JTI = MO1.getIndex();<br>
><br>
>    MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);<br>
> @@ -985,42 +980,56 @@ void ARMAsmPrinter::EmitJump2Table(const<br>
>    const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();<br>
>    const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();<br>
>    const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;<br>
> -  unsigned OffsetWidth = 4;<br>
> -  if (MI->getOpcode() == ARM::t2TBB_JT) {<br>
> -    OffsetWidth = 1;<br>
> -    // Mark the jump table as data-in-code.<br>
> -    OutStreamer->EmitDataRegion(MCDR_DataRegionJT8);<br>
> -  } else if (MI->getOpcode() == ARM::t2TBH_JT) {<br>
> -    OffsetWidth = 2;<br>
> -    // Mark the jump table as data-in-code.<br>
> -    OutStreamer->EmitDataRegion(MCDR_DataRegionJT16);<br>
> -  }<br>
><br>
>    for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {<br>
>      MachineBasicBlock *MBB = JTBBs[i];<br>
>      const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),<br>
>                                                            OutContext);<br>
>      // If this isn't a TBB or TBH, the entries are direct branch instructions.<br>
> -    if (OffsetWidth == 4) {<br>
> -      EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2B)<br>
> +    EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2B)<br>
>          .addExpr(MBBSymbolExpr)<br>
>          .addImm(ARMCC::AL)<br>
>          .addReg(0));<br>
> -      continue;<br>
> -    }<br>
> +  }<br>
> +}<br>
> +<br>
> +void ARMAsmPrinter::EmitJumpTableTBInst(const MachineInstr *MI,<br>
> +                                        unsigned OffsetWidth) {<br>
> +  assert((OffsetWidth == 1 || OffsetWidth == 2) && "invalid tbb/tbh width");<br>
> +  const MachineOperand &MO1 = MI->getOperand(1);<br>
> +  unsigned JTI = MO1.getIndex();<br>
> +<br>
> +  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);<br>
> +  OutStreamer->EmitLabel(JTISymbol);<br>
> +<br>
> +  // Emit each entry of the table.<br>
> +  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();<br>
> +  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();<br>
> +  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;<br>
> +<br>
> +  // Mark the jump table as data-in-code.<br>
> +  OutStreamer->EmitDataRegion(OffsetWidth == 1 ? MCDR_DataRegionJT8<br>
> +                                               : MCDR_DataRegionJT16);<br>
> +<br>
> +  for (auto MBB : JTBBs) {<br>
> +    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),<br>
> +                                                          OutContext);<br>
>      // Otherwise it's an offset from the dispatch instruction. Construct an<br>
>      // MCExpr for the entry. We want a value of the form:<br>
> -    // (BasicBlockAddr - TableBeginAddr) / 2<br>
> +    // (BasicBlockAddr - TBBInstAddr + 4) / 2<br>
>      //<br>
>      // For example, a TBB table with entries jumping to basic blocks BB0 and BB1<br>
>      // would look like:<br>
>      // LJTI_0_0:<br>
> -    //    .byte (LBB0 - LJTI_0_0) / 2<br>
> -    //    .byte (LBB1 - LJTI_0_0) / 2<br>
> -    const MCExpr *Expr =<br>
> -      MCBinaryExpr::CreateSub(MBBSymbolExpr,<br>
> -                              MCSymbolRefExpr::Create(JTISymbol, OutContext),<br>
> -                              OutContext);<br>
> +    //    .byte (LBB0 - (LCPI0_0 + 4)) / 2<br>
> +    //    .byte (LBB1 - (LCPI0_0 + 4)) / 2<br>
> +    // where LCPI0_0 is a label defined just before the TBB instruction using<br>
> +    // this table.<br>
> +    MCSymbol *TBInstPC = GetCPISymbol(MI->getOperand(0).getImm());<br>
> +    const MCExpr *Expr = MCBinaryExpr::CreateAdd(<br>
> +        MCSymbolRefExpr::Create(TBInstPC, OutContext),<br>
> +        MCConstantExpr::Create(4, OutContext), OutContext);<br>
> +    Expr = MCBinaryExpr::CreateSub(MBBSymbolExpr, Expr, OutContext);<br>
>      Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),<br>
>                                     OutContext);<br>
>      OutStreamer->EmitValue(Expr, OffsetWidth);<br>
> @@ -1028,8 +1037,10 @@ void ARMAsmPrinter::EmitJump2Table(const<br>
>    // Mark the end of jump table data-in-code region. 32-bit offsets use<br>
>    // actual branch instructions here, so we don't mark those as a data-region<br>
>    // at all.<br>
> -  if (OffsetWidth != 4)<br>
> -    OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);<br>
> +  OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);<br>
> +<br>
> +  // Make sure the next instruction is 2-byte aligned.<br>
> +  EmitAlignment(1);<br>
>  }<br>
><br>
>  void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {<br>
> @@ -1501,6 +1512,16 @@ void ARMAsmPrinter::EmitInstruction(cons<br>
>        EmitGlobalConstant(MCPE.Val.ConstVal);<br>
>      return;<br>
>    }<br>
> +  case ARM::JUMPTABLE_ADDRS:<br>
> +    EmitJumpTableAddrs(MI);<br>
> +    return;<br>
> +  case ARM::JUMPTABLE_INSTS:<br>
> +    EmitJumpTableInsts(MI);<br>
> +    return;<br>
> +  case ARM::JUMPTABLE_TBB:<br>
> +  case ARM::JUMPTABLE_TBH:<br>
> +    EmitJumpTableTBInst(MI, MI->getOpcode() == ARM::JUMPTABLE_TBB ? 1 : 2);<br>
> +    return;<br>
>    case ARM::t2BR_JT: {<br>
>      // Lower and emit the instruction itself, then the jump table following it.<br>
>      EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVr)<br>
> @@ -1509,37 +1530,19 @@ void ARMAsmPrinter::EmitInstruction(cons<br>
>        // Add predicate operands.<br>
>        .addImm(ARMCC::AL)<br>
>        .addReg(0));<br>
> -<br>
> -    // Output the data for the jump table itself<br>
> -    EmitJump2Table(MI);<br>
> -    return;<br>
> -  }<br>
> -  case ARM::t2TBB_JT: {<br>
> -    // Lower and emit the instruction itself, then the jump table following it.<br>
> -    EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2TBB)<br>
> -      .addReg(ARM::PC)<br>
> -      .addReg(MI->getOperand(0).getReg())<br>
> -      // Add predicate operands.<br>
> -      .addImm(ARMCC::AL)<br>
> -      .addReg(0));<br>
> -<br>
> -    // Output the data for the jump table itself<br>
> -    EmitJump2Table(MI);<br>
> -    // Make sure the next instruction is 2-byte aligned.<br>
> -    EmitAlignment(1);<br>
>      return;<br>
>    }<br>
> +  case ARM::t2TBB_JT:<br>
>    case ARM::t2TBH_JT: {<br>
> -    // Lower and emit the instruction itself, then the jump table following it.<br>
> -    EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2TBH)<br>
> -      .addReg(ARM::PC)<br>
> -      .addReg(MI->getOperand(0).getReg())<br>
> -      // Add predicate operands.<br>
> -      .addImm(ARMCC::AL)<br>
> -      .addReg(0));<br>
> -<br>
> -    // Output the data for the jump table itself<br>
> -    EmitJump2Table(MI);<br>
> +    unsigned Opc = MI->getOpcode() == ARM::t2TBB_JT ? ARM::t2TBB : ARM::t2TBH;<br>
> +    // Lower and emit the PC label, then the instruction itself.<br>
> +    OutStreamer->EmitLabel(GetCPISymbol(MI->getOperand(3).getImm()));<br>
> +    EmitToStreamer(*OutStreamer, MCInstBuilder(Opc)<br>
> +                                     .addReg(MI->getOperand(0).getReg())<br>
> +                                     .addReg(MI->getOperand(1).getReg())<br>
> +                                     // Add predicate operands.<br>
> +                                     .addImm(ARMCC::AL)<br>
> +                                     .addReg(0));<br>
>      return;<br>
>    }<br>
>    case ARM::tBR_JTr:<br>
> @@ -1559,13 +1562,6 @@ void ARMAsmPrinter::EmitInstruction(cons<br>
>      if (Opc == ARM::MOVr)<br>
>        TmpInst.addOperand(MCOperand::createReg(0));<br>
>      EmitToStreamer(*OutStreamer, TmpInst);<br>
> -<br>
> -    // Make sure the Thumb jump table is 4-byte aligned.<br>
> -    if (Opc == ARM::tMOVr)<br>
> -      EmitAlignment(2);<br>
> -<br>
> -    // Output the data for the jump table itself<br>
> -    EmitJumpTable(MI);<br>
>      return;<br>
>    }<br>
>    case ARM::BR_JTm: {<br>
> @@ -1589,9 +1585,6 @@ void ARMAsmPrinter::EmitInstruction(cons<br>
>      TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));<br>
>      TmpInst.addOperand(MCOperand::createReg(0));<br>
>      EmitToStreamer(*OutStreamer, TmpInst);<br>
> -<br>
> -    // Output the data for the jump table itself<br>
> -    EmitJumpTable(MI);<br>
>      return;<br>
>    }<br>
>    case ARM::BR_JTadd: {<br>
> @@ -1606,9 +1599,6 @@ void ARMAsmPrinter::EmitInstruction(cons<br>
>        .addReg(0)<br>
>        // Add 's' bit operand (always reg0 for this)<br>
>        .addReg(0));<br>
> -<br>
> -    // Output the data for the jump table itself<br>
> -    EmitJumpTable(MI);<br>
>      return;<br>
>    }<br>
>    case ARM::SPACE:<br>
><br>
> Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_ARM_ARMAsmPrinter.h-3Frev-3D237590-26r1-3D237589-26r2-3D237590-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=IYnmYEE4KsP5h-EEJ1T6BX3lZ3oDzWPlHt_pVKOzMBs&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h?rev=237590&r1=237589&r2=237590&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h (original)<br>
> +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h Mon May 18 12:10:40 2015<br>
> @@ -71,8 +71,9 @@ public:<br>
>    void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,<br>
>                          const MCSubtargetInfo *EndInfo) const override;<br>
><br>
> -  void EmitJumpTable(const MachineInstr *MI);<br>
> -  void EmitJump2Table(const MachineInstr *MI);<br>
> +  void EmitJumpTableAddrs(const MachineInstr *MI);<br>
> +  void EmitJumpTableInsts(const MachineInstr *MI);<br>
> +  void EmitJumpTableTBInst(const MachineInstr *MI, unsigned OffsetWidth);<br>
>    void EmitInstruction(const MachineInstr *MI) override;<br>
>    bool runOnMachineFunction(MachineFunction &F) override;<br>
><br>
><br>
> Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_ARM_ARMBaseInstrInfo.cpp-3Frev-3D237590-26r1-3D237589-26r2-3D237590-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=4m1-djr6pyBOJma4e0Emqqac4W9X4cPlldtSD25ahMM&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=237590&r1=237589&r2=237590&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original)<br>
> +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Mon May 18 12:10:40 2015<br>
> @@ -627,6 +627,10 @@ unsigned ARMBaseInstrInfo::GetInstSizeIn<br>
>    case ARM::t2MOVi32imm:<br>
>      return 8;<br>
>    case ARM::CONSTPOOL_ENTRY:<br>
> +  case ARM::JUMPTABLE_INSTS:<br>
> +  case ARM::JUMPTABLE_ADDRS:<br>
> +  case ARM::JUMPTABLE_TBB:<br>
> +  case ARM::JUMPTABLE_TBH:<br>
>      // If this machine instr is a constant pool entry, its size is recorded as<br>
>      // operand #2.<br>
>      return MI->getOperand(2).getImm();<br>
> @@ -641,42 +645,6 @@ unsigned ARMBaseInstrInfo::GetInstSizeIn<br>
>    case ARM::t2Int_eh_sjlj_setjmp:<br>
>    case ARM::t2Int_eh_sjlj_setjmp_nofp:<br>
>      return 12;<br>
> -  case ARM::BR_JTr:<br>
> -  case ARM::BR_JTm:<br>
> -  case ARM::BR_JTadd:<br>
> -  case ARM::tBR_JTr:<br>
> -  case ARM::t2BR_JT:<br>
> -  case ARM::t2TBB_JT:<br>
> -  case ARM::t2TBH_JT: {<br>
> -    // These are jumptable branches, i.e. a branch followed by an inlined<br>
> -    // jumptable. The size is 4 + 4 * number of entries. For TBB, each<br>
> -    // entry is one byte; TBH two byte each.<br>
> -    unsigned EntrySize = (Opc == ARM::t2TBB_JT)<br>
> -      ? 1 : ((Opc == ARM::t2TBH_JT) ? 2 : 4);<br>
> -    unsigned NumOps = MCID.getNumOperands();<br>
> -    MachineOperand JTOP =<br>
> -      MI->getOperand(NumOps - (MI->isPredicable() ? 2 : 1));<br>
> -    unsigned JTI = JTOP.getIndex();<br>
> -    const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();<br>
> -    assert(MJTI != nullptr);<br>
> -    const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();<br>
> -    assert(JTI < JT.size());<br>
> -    // Thumb instructions are 2 byte aligned, but JT entries are 4 byte<br>
> -    // 4 aligned. The assembler / linker may add 2 byte padding just before<br>
> -    // the JT entries.  The size does not include this padding; the<br>
> -    // constant islands pass does separate bookkeeping for it.<br>
> -    // FIXME: If we know the size of the function is less than (1 << 16) *2<br>
> -    // bytes, we can use 16-bit entries instead. Then there won't be an<br>
> -    // alignment issue.<br>
> -    unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT) ? 2 : 4;<br>
> -    unsigned NumEntries = JT[JTI].MBBs.size();<br>
> -    if (Opc == ARM::t2TBB_JT && (NumEntries & 1))<br>
> -      // Make sure the instruction that follows TBB is 2-byte aligned.<br>
> -      // FIXME: Constant island pass should insert an "ALIGN" instruction<br>
> -      // instead.<br>
> -      ++NumEntries;<br>
> -    return NumEntries * EntrySize + InstSize;<br>
> -  }<br>
>    case ARM::SPACE:<br>
>      return MI->getOperand(1).getImm();<br>
>    }<br>
><br>
> Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_ARM_ARMConstantIslandPass.cpp-3Frev-3D237590-26r1-3D237589-26r2-3D237590-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=TpUsvLJl1CbKsG4-s11f2AxPgo3ikfpVbERPBLIvixY&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=237590&r1=237589&r2=237590&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original)<br>
> +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon May 18 12:10:40 2015<br>
> @@ -180,9 +180,7 @@ namespace {<br>
>        MachineInstr *MI;<br>
>        MachineInstr *CPEMI;<br>
>        MachineBasicBlock *HighWaterMark;<br>
> -    private:<br>
>        unsigned MaxDisp;<br>
> -    public:<br>
>        bool NegOk;<br>
>        bool IsSoImm;<br>
>        bool KnownAlignment;<br>
> @@ -216,12 +214,24 @@ namespace {<br>
>      };<br>
><br>
>      /// CPEntries - Keep track of all of the constant pool entry machine<br>
> -    /// instructions. For each original constpool index (i.e. those that<br>
> -    /// existed upon entry to this pass), it keeps a vector of entries.<br>
> -    /// Original elements are cloned as we go along; the clones are<br>
> -    /// put in the vector of the original element, but have distinct CPIs.<br>
> +    /// instructions. For each original constpool index (i.e. those that existed<br>
> +    /// upon entry to this pass), it keeps a vector of entries.  Original<br>
> +    /// elements are cloned as we go along; the clones are put in the vector of<br>
> +    /// the original element, but have distinct CPIs.<br>
> +    ///<br>
> +    /// The first half of CPEntries contains generic constants, the second half<br>
> +    /// contains jump tables. Use getCombinedIndex on a generic CPEMI to look up<br>
> +    /// which vector it will be in here.<br>
>      std::vector<std::vector<CPEntry> > CPEntries;<br>
><br>
> +    /// Maps a JT index to the offset in CPEntries containing copies of that<br>
> +    /// table. The equivalent map for a CONSTPOOL_ENTRY is the identity.<br>
> +    DenseMap<int, int> JumpTableEntryIndices;<br>
> +<br>
> +    /// Maps a JT index to the LEA that actually uses the index to calculate its<br>
> +    /// base address.<br>
> +    DenseMap<int, int> JumpTableUserIndices;<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>
> @@ -269,7 +279,8 @@ namespace {<br>
>      }<br>
><br>
>    private:<br>
> -    void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);<br>
> +    void doInitialConstPlacement(std::vector<MachineInstr *> &CPEMIs);<br>
> +    void doInitialJumpTablePlacement(std::vector<MachineInstr *> &CPEMIs);<br>
>      bool BBHasFallthrough(MachineBasicBlock *MBB);<br>
>      CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI);<br>
>      unsigned getCPELogAlign(const MachineInstr *CPEMI);<br>
> @@ -279,6 +290,7 @@ namespace {<br>
>      void updateForInsertedWaterBlock(MachineBasicBlock *NewBB);<br>
>      void adjustBBOffsetsAfter(MachineBasicBlock *BB);<br>
>      bool decrementCPEReferenceCount(unsigned CPI, MachineInstr* CPEMI);<br>
> +    unsigned getCombinedIndex(const MachineInstr *CPEMI);<br>
>      int findInRangeCPEntry(CPUser& U, unsigned UserOffset);<br>
>      bool findAvailableWater(CPUser&U, unsigned UserOffset,<br>
>                              water_iterator &WaterIter);<br>
> @@ -413,7 +425,10 @@ bool ARMConstantIslands::runOnMachineFun<br>
>    // we put them all at the end of the function.<br>
>    std::vector<MachineInstr*> CPEMIs;<br>
>    if (!MCP->isEmpty())<br>
> -    doInitialPlacement(CPEMIs);<br>
> +    doInitialConstPlacement(CPEMIs);<br>
> +<br>
> +  if (MF->getJumpTableInfo())<br>
> +    doInitialJumpTablePlacement(CPEMIs);<br>
><br>
>    /// The next UID to take is the first unused one.<br>
>    AFI->initPICLabelUId(CPEMIs.size());<br>
> @@ -478,7 +493,8 @@ bool ARMConstantIslands::runOnMachineFun<br>
>    for (unsigned i = 0, e = CPEntries.size(); i != e; ++i) {<br>
>      for (unsigned j = 0, je = CPEntries[i].size(); j != je; ++j) {<br>
>        const CPEntry & CPE = CPEntries[i][j];<br>
> -      AFI->recordCPEClone(i, CPE.CPI);<br>
> +      if (CPE.CPEMI && CPE.CPEMI->getOperand(1).isCPI())<br>
> +        AFI->recordCPEClone(i, CPE.CPI);<br>
>      }<br>
>    }<br>
><br>
> @@ -488,6 +504,8 @@ bool ARMConstantIslands::runOnMachineFun<br>
>    WaterList.clear();<br>
>    CPUsers.clear();<br>
>    CPEntries.clear();<br>
> +  JumpTableEntryIndices.clear();<br>
> +  JumpTableUserIndices.clear();<br>
>    ImmBranches.clear();<br>
>    PushPopMIs.clear();<br>
>    T2JumpTables.clear();<br>
> @@ -495,10 +513,10 @@ bool ARMConstantIslands::runOnMachineFun<br>
>    return MadeChange;<br>
>  }<br>
><br>
> -/// doInitialPlacement - Perform the initial placement of the constant pool<br>
> -/// entries.  To start with, we put them all at the end of the function.<br>
> +/// \brief Perform the initial placement of the regular constant pool entries.<br>
> +/// To start with, we put them all at the end of the function.<br>
>  void<br>
> -ARMConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {<br>
> +ARMConstantIslands::doInitialConstPlacement(std::vector<MachineInstr*> &CPEMIs) {<br>
>    // Create the basic block to hold the CPE's.<br>
>    MachineBasicBlock *BB = MF->CreateMachineBasicBlock();<br>
>    MF->push_back(BB);<br>
> @@ -556,6 +574,66 @@ ARMConstantIslands::doInitialPlacement(s<br>
>    DEBUG(BB->dump());<br>
>  }<br>
><br>
> +/// \brief Do initial placement of the jump tables. Because Thumb2's TBB and TBH<br>
> +/// instructions can be made more efficient if the jump table immediately<br>
> +/// follows the instruction, it's best to place them immediately next to their<br>
> +/// jumps to begin with. In almost all cases they'll never be moved from that<br>
> +/// position.<br>
> +void ARMConstantIslands::doInitialJumpTablePlacement(<br>
> +    std::vector<MachineInstr *> &CPEMIs) {<br>
> +  unsigned i = CPEntries.size();<br>
> +  auto MJTI = MF->getJumpTableInfo();<br>
> +  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();<br>
> +<br>
> +  MachineBasicBlock *LastCorrectlyNumberedBB = nullptr;<br>
> +  for (MachineBasicBlock &MBB : *MF) {<br>
> +    auto MI = MBB.getLastNonDebugInstr();<br>
> +<br>
> +    unsigned JTOpcode;<br>
> +    switch (MI->getOpcode()) {<br>
> +    default:<br>
> +      continue;<br>
> +    case ARM::BR_JTadd:<br>
> +    case ARM::BR_JTr:<br>
> +    case ARM::tBR_JTr:<br>
> +    case ARM::BR_JTm:<br>
> +      JTOpcode = ARM::JUMPTABLE_ADDRS;<br>
> +      break;<br>
> +    case ARM::t2BR_JT:<br>
> +      JTOpcode = ARM::JUMPTABLE_INSTS;<br>
> +      break;<br>
> +    case ARM::t2TBB_JT:<br>
> +      JTOpcode = ARM::JUMPTABLE_TBB;<br>
> +      break;<br>
> +    case ARM::t2TBH_JT:<br>
> +      JTOpcode = ARM::JUMPTABLE_TBH;<br>
> +      break;<br>
> +    }<br>
> +<br>
> +    unsigned NumOps = MI->getDesc().getNumOperands();<br>
> +    MachineOperand JTOp =<br>
> +      MI->getOperand(NumOps - (MI->isPredicable() ? 2 : 1));<br>
> +    unsigned JTI = JTOp.getIndex();<br>
> +    unsigned Size = JT[JTI].MBBs.size() * sizeof(uint32_t);<br>
> +    MachineBasicBlock *JumpTableBB = MF->CreateMachineBasicBlock();<br>
> +    MF->insert(std::next(MachineFunction::iterator(MBB)), JumpTableBB);<br>
> +    MachineInstr *CPEMI = BuildMI(*JumpTableBB, JumpTableBB->begin(),<br>
> +                                  DebugLoc(), TII->get(JTOpcode))<br>
> +                              .addImm(i++)<br>
> +                              .addJumpTableIndex(JTI)<br>
> +                              .addImm(Size);<br>
> +    CPEMIs.push_back(CPEMI);<br>
> +    CPEntries.emplace_back(1, CPEntry(CPEMI, JTI));<br>
> +    JumpTableEntryIndices.insert(std::make_pair(JTI, CPEntries.size() - 1));<br>
> +    if (!LastCorrectlyNumberedBB)<br>
> +      LastCorrectlyNumberedBB = &MBB;<br>
> +  }<br>
> +<br>
> +  // If we did anything then we need to renumber the subsequent blocks.<br>
> +  if (LastCorrectlyNumberedBB)<br>
> +    MF->RenumberBlocks(LastCorrectlyNumberedBB);<br>
> +}<br>
> +<br>
>  /// BBHasFallthrough - Return true if the specified basic block can fallthrough<br>
>  /// into the block immediately after it.<br>
>  bool ARMConstantIslands::BBHasFallthrough(MachineBasicBlock *MBB) {<br>
> @@ -595,9 +673,21 @@ ARMConstantIslands::CPEntry<br>
>  /// getCPELogAlign - Returns the required alignment of the constant pool entry<br>
>  /// represented by CPEMI.  Alignment is measured in log2(bytes) units.<br>
>  unsigned ARMConstantIslands::getCPELogAlign(const MachineInstr *CPEMI) {<br>
> -  assert(CPEMI && CPEMI->getOpcode() == ARM::CONSTPOOL_ENTRY);<br>
> +  switch (CPEMI->getOpcode()) {<br>
> +  case ARM::CONSTPOOL_ENTRY:<br>
> +    break;<br>
> +  case ARM::JUMPTABLE_TBB:<br>
> +    return 0;<br>
> +  case ARM::JUMPTABLE_TBH:<br>
> +  case ARM::JUMPTABLE_INSTS:<br>
> +    return 1;<br>
> +  case ARM::JUMPTABLE_ADDRS:<br>
> +    return 2;<br>
> +  default:<br>
> +    llvm_unreachable("unknown constpool entry kind");<br>
> +  }<br>
><br>
> -  unsigned CPI = CPEMI->getOperand(1).getIndex();<br>
> +  unsigned CPI = getCombinedIndex(CPEMI);<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>
> @@ -706,12 +796,14 @@ initializeFunctionInfo(const std::vector<br>
>        if (Opc == ARM::tPUSH || Opc == ARM::tPOP_RET)<br>
>          PushPopMIs.push_back(I);<br>
><br>
> -      if (Opc == ARM::CONSTPOOL_ENTRY)<br>
> +      if (Opc == ARM::CONSTPOOL_ENTRY || Opc == ARM::JUMPTABLE_ADDRS ||<br>
> +          Opc == ARM::JUMPTABLE_INSTS || Opc == ARM::JUMPTABLE_TBB ||<br>
> +          Opc == ARM::JUMPTABLE_TBH)<br>
>          continue;<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>
> +        if (I->getOperand(op).isCPI() || I->getOperand(op).isJTI()) {<br>
>            // We found one.  The addressing mode tells us the max displacement<br>
>            // from the PC that this instruction permits.<br>
><br>
> @@ -727,6 +819,7 @@ initializeFunctionInfo(const std::vector<br>
><br>
>            // Taking the address of a CP entry.<br>
>            case ARM::LEApcrel:<br>
> +          case ARM::LEApcrelJT:<br>
>              // This takes a SoImm, which is 8 bit immediate rotated. We'll<br>
>              // pretend the maximum offset is 255 * 4. Since each instruction<br>
>              // 4 byte wide, this is always correct. We'll check for other<br>
> @@ -737,10 +830,12 @@ initializeFunctionInfo(const std::vector<br>
>              IsSoImm = true;<br>
>              break;<br>
>            case ARM::t2LEApcrel:<br>
> +          case ARM::t2LEApcrelJT:<br>
>              Bits = 12;<br>
>              NegOk = true;<br>
>              break;<br>
>            case ARM::tLEApcrel:<br>
> +          case ARM::tLEApcrelJT:<br>
>              Bits = 8;<br>
>              Scale = 4;<br>
>              break;<br>
> @@ -768,6 +863,11 @@ initializeFunctionInfo(const std::vector<br>
><br>
>            // Remember that this is a user of a CP entry.<br>
>            unsigned CPI = I->getOperand(op).getIndex();<br>
> +          if (I->getOperand(op).isJTI()) {<br>
> +            JumpTableUserIndices.insert(std::make_pair(CPI, CPUsers.size()));<br>
> +            CPI = JumpTableEntryIndices[CPI];<br>
> +          }<br>
> +<br>
>            MachineInstr *CPEMI = CPEMIs[CPI];<br>
>            unsigned MaxOffs = ((1 << Bits)-1) * Scale;<br>
>            CPUsers.push_back(CPUser(I, CPEMI, MaxOffs, NegOk, IsSoImm));<br>
> @@ -1101,6 +1201,13 @@ bool ARMConstantIslands::decrementCPERef<br>
>    return false;<br>
>  }<br>
><br>
> +unsigned ARMConstantIslands::getCombinedIndex(const MachineInstr *CPEMI) {<br>
> +  if (CPEMI->getOperand(1).isCPI())<br>
> +    return CPEMI->getOperand(1).getIndex();<br>
> +<br>
> +  return JumpTableEntryIndices[CPEMI->getOperand(1).getIndex()];<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>
> @@ -1120,7 +1227,7 @@ int ARMConstantIslands::findInRangeCPEnt<br>
>    }<br>
><br>
>    // No.  Look for previously created clones of the CPE that are in range.<br>
> -  unsigned CPI = CPEMI->getOperand(1).getIndex();<br>
> +  unsigned CPI = getCombinedIndex(CPEMI);<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>
> @@ -1365,7 +1472,7 @@ bool ARMConstantIslands::handleConstantP<br>
>    CPUser &U = CPUsers[CPUserIndex];<br>
>    MachineInstr *UserMI = U.MI;<br>
>    MachineInstr *CPEMI  = U.CPEMI;<br>
> -  unsigned CPI = CPEMI->getOperand(1).getIndex();<br>
> +  unsigned CPI = getCombinedIndex(CPEMI);<br>
>    unsigned Size = CPEMI->getOperand(2).getImm();<br>
>    // Compute this only once, it's expensive.<br>
>    unsigned UserOffset = getUserOffset(U);<br>
> @@ -1429,17 +1536,17 @@ bool ARMConstantIslands::handleConstantP<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(ARM::CONSTPOOL_ENTRY))<br>
> -                .addImm(ID).addConstantPoolIndex(CPI).addImm(Size);<br>
> +  U.CPEMI = BuildMI(NewIsland, DebugLoc(), CPEMI->getDesc())<br>
> +                .addImm(ID).addOperand(CPEMI->getOperand(1)).addImm(Size);<br>
>    CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));<br>
>    ++NumCPEs;<br>
><br>
> +  // Decrement the old entry, and remove it if refcount becomes 0.<br>
> +  decrementCPEReferenceCount(CPI, CPEMI);<br>
> +<br>
>    // Mark the basic block as aligned as required by the const-pool entry.<br>
>    NewIsland->setAlignment(getCPELogAlign(U.CPEMI));<br>
><br>
> @@ -1917,6 +2024,19 @@ unsigned ARMConstantIslands::removeDeadD<br>
>    return BytesRemoved;<br>
>  }<br>
><br>
> +/// \brief Returns whether CPEMI is the first instruction in the block<br>
> +/// immediately following JTMI (assumed to be a TBB or TBH terminator). If so,<br>
> +/// we can switch the first register to PC and usually remove the address<br>
> +/// calculation that preceeded it.<br>
> +static bool jumpTableFollowsTB(MachineInstr *JTMI, MachineInstr *CPEMI) {<br>
> +  MachineFunction::iterator MBB = JTMI->getParent();<br>
> +  MachineFunction *MF = MBB->getParent();<br>
> +  ++MBB;<br>
> +<br>
> +  return MBB != MF->end() && MBB->begin() != MBB->end() &&<br>
> +         &*MBB->begin() == CPEMI;<br>
> +}<br>
> +<br>
>  /// optimizeThumb2JumpTables - Use tbb / tbh instructions to generate smaller<br>
>  /// jumptables when it's possible.<br>
>  bool ARMConstantIslands::optimizeThumb2JumpTables() {<br>
> @@ -1955,37 +2075,73 @@ bool ARMConstantIslands::optimizeThumb2J<br>
>          break;<br>
>      }<br>
><br>
> -    if (ByteOk || HalfWordOk) {<br>
> -      MachineBasicBlock *MBB = MI->getParent();<br>
> -      unsigned BaseReg = MI->getOperand(0).getReg();<br>
> -      bool BaseRegKill = MI->getOperand(0).isKill();<br>
> -      if (!BaseRegKill)<br>
> -        continue;<br>
> -      unsigned IdxReg = MI->getOperand(1).getReg();<br>
> -      bool IdxRegKill = MI->getOperand(1).isKill();<br>
> +    if (!ByteOk && !HalfWordOk)<br>
> +      continue;<br>
> +<br>
> +    MachineBasicBlock *MBB = MI->getParent();<br>
> +    unsigned BaseReg = MI->getOperand(0).getReg();<br>
> +    bool BaseRegKill = MI->getOperand(0).isKill();<br>
> +    if (!BaseRegKill)<br>
> +      continue;<br>
> +    unsigned IdxReg = MI->getOperand(1).getReg();<br>
> +    bool IdxRegKill = MI->getOperand(1).isKill();<br>
><br>
> -      DEBUG(dbgs() << "Shrink JT: " << *MI);<br>
> -      unsigned Opc = ByteOk ? ARM::t2TBB_JT : ARM::t2TBH_JT;<br>
> -      MachineBasicBlock::iterator MI_JT = MI;<br>
> -      MachineInstr *NewJTMI =<br>
> +    DEBUG(dbgs() << "Shrink JT: " << *MI);<br>
> +    CPUser &User = CPUsers[JumpTableUserIndices[JTI]];<br>
> +    MachineInstr *CPEMI = User.CPEMI;<br>
> +    unsigned Opc = ByteOk ? ARM::t2TBB_JT : ARM::t2TBH_JT;<br>
> +    MachineBasicBlock::iterator MI_JT = MI;<br>
> +    MachineInstr *NewJTMI =<br>
>          BuildMI(*MBB, MI_JT, MI->getDebugLoc(), TII->get(Opc))<br>
> -        .addReg(IdxReg, getKillRegState(IdxRegKill))<br>
> -        .addJumpTableIndex(JTI, JTOP.getTargetFlags());<br>
> -      DEBUG(dbgs() << "BB#" << MBB->getNumber() << ": " << *NewJTMI);<br>
> -      // FIXME: Insert an "ALIGN" instruction to ensure the next instruction<br>
> -      // is 2-byte aligned. For now, asm printer will fix it up.<br>
> -      unsigned NewSize = TII->GetInstSizeInBytes(NewJTMI);<br>
> -      unsigned OrigSize = TII->GetInstSizeInBytes(MI);<br>
> -      unsigned DeadSize = removeDeadDefinitions(MI, BaseReg, IdxReg);<br>
> -      MI->eraseFromParent();<br>
> +            .addReg(BaseReg, getKillRegState(BaseRegKill))<br>
> +            .addReg(IdxReg, getKillRegState(IdxRegKill))<br>
> +            .addJumpTableIndex(JTI, JTOP.getTargetFlags())<br>
> +            .addImm(CPEMI->getOperand(0).getImm());<br>
> +    DEBUG(dbgs() << "BB#" << MBB->getNumber() << ": " << *NewJTMI);<br>
> +<br>
> +    unsigned JTOpc = ByteOk ? ARM::JUMPTABLE_TBB : ARM::JUMPTABLE_TBH;<br>
> +    CPEMI->setDesc(TII->get(JTOpc));<br>
> +<br>
> +    // Now we need to determine whether the actual jump table has been moved<br>
> +    // from immediately after this instruction. If not, we can replace BaseReg<br>
> +    // with PC and probably eliminate the BaseReg calculations.<br>
> +    unsigned DeadSize = 0;<br>
> +    if (jumpTableFollowsTB(NewJTMI, User.CPEMI)) {<br>
> +      NewJTMI->getOperand(0).setReg(ARM::PC);<br>
> +      NewJTMI->getOperand(0).setIsKill(false);<br>
> +<br>
> +      DeadSize = removeDeadDefinitions(MI, BaseReg, IdxReg);<br>
> +      if (!User.MI->getParent()) {<br>
> +        // The LEA was eliminated, the TBB instruction becomes the only new user<br>
> +        // of the jump table.<br>
> +        User.MI = NewJTMI;<br>
> +        User.MaxDisp = 4;<br>
> +        User.NegOk = false;<br>
> +        User.IsSoImm = false;<br>
> +        User.KnownAlignment = false;<br>
> +      } else {<br>
> +        // The LEA couldn't be eliminated, so we must add another CPUser to<br>
> +        // record the TBB or TBH use.<br>
> +        int CPEntryIdx = JumpTableEntryIndices[JTI];<br>
> +        auto &CPEs = CPEntries[CPEntryIdx];<br>
> +        auto Entry = std::find_if(CPEs.begin(), CPEs.end(), [&](CPEntry &E) {<br>
> +          return E.CPEMI == User.CPEMI;<br>
> +        });<br>
> +        ++Entry->RefCount;<br>
> +        CPUsers.emplace_back(CPUser(NewJTMI, User.CPEMI, 4, false, false));<br>
> +      }<br>
> +    }<br>
><br>
> -      int delta = OrigSize - NewSize + DeadSize;<br>
> -      BBInfo[MBB->getNumber()].Size -= delta;<br>
> -      adjustBBOffsetsAfter(MBB);<br>
> +    unsigned NewSize = TII->GetInstSizeInBytes(NewJTMI);<br>
> +    unsigned OrigSize = TII->GetInstSizeInBytes(MI);<br>
> +    MI->eraseFromParent();<br>
> +<br>
> +    int Delta = OrigSize - NewSize + DeadSize;<br>
> +    BBInfo[MBB->getNumber()].Size -= Delta;<br>
> +    adjustBBOffsetsAfter(MBB);<br>
><br>
> -      ++NumTBs;<br>
> -      MadeChange = true;<br>
> -    }<br>
> +    ++NumTBs;<br>
> +    MadeChange = true;<br>
>    }<br>
><br>
>    return MadeChange;<br>
><br>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_ARM_ARMInstrInfo.td-3Frev-3D237590-26r1-3D237589-26r2-3D237590-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=rEKssQa4vCJhFevQeJsbr8iVh0cn6Z-UBw6Y5axoXP0&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=237590&r1=237589&r2=237590&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)<br>
> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Mon May 18 12:10:40 2015<br>
> @@ -1826,6 +1826,32 @@ def CONSTPOOL_ENTRY :<br>
>  PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,<br>
>                      i32imm:$size), NoItinerary, []>;<br>
><br>
> +/// A jumptable consisting of direct 32-bit addresses of the destination basic<br>
> +/// blocks (either absolute, or relative to the start of the jump-table in PIC<br>
> +/// mode). Used mostly in ARM and Thumb-1 modes.<br>
> +def JUMPTABLE_ADDRS :<br>
> +PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,<br>
> +                        i32imm:$size), NoItinerary, []>;<br>
> +<br>
> +/// A jumptable consisting of 32-bit jump instructions. Used for Thumb-2 tables<br>
> +/// that cannot be optimised to use TBB or TBH.<br>
> +def JUMPTABLE_INSTS :<br>
> +PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,<br>
> +                        i32imm:$size), NoItinerary, []>;<br>
> +<br>
> +/// A jumptable consisting of 8-bit unsigned integers representing offsets from<br>
> +/// a TBB instruction.<br>
> +def JUMPTABLE_TBB :<br>
> +PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,<br>
> +                        i32imm:$size), NoItinerary, []>;<br>
> +<br>
> +/// A jumptable consisting of 16-bit unsigned integers representing offsets from<br>
> +/// a TBH instruction.<br>
> +def JUMPTABLE_TBH :<br>
> +PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,<br>
> +                        i32imm:$size), NoItinerary, []>;<br>
> +<br>
> +<br>
>  // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE<br>
>  // from removing one half of the matched pairs. That breaks PEI, which assumes<br>
>  // these will always be in pairs, and asserts if it finds otherwise. Better way?<br>
> @@ -2224,7 +2250,7 @@ let isBranch = 1, isTerminator = 1 in {<br>
>                  [(br bb:$target)], (Bcc br_target:$target, (ops 14, zero_reg))>,<br>
>                  Sched<[WriteBr]>;<br>
><br>
> -    let isNotDuplicable = 1, isIndirectBranch = 1 in {<br>
> +    let Size = 4, isNotDuplicable = 1, isIndirectBranch = 1 in {<br>
>      def BR_JTr : ARMPseudoInst<(outs),<br>
>                        (ins GPR:$target, i32imm:$jt),<br>
>                        0, IIC_Br,<br>
><br>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_ARM_ARMInstrThumb.td-3Frev-3D237590-26r1-3D237589-26r2-3D237590-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=IIt7zq6QCajtD-M978QvijYKMmE4vu7KesQ7A00RQ94&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=237590&r1=237589&r2=237590&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original)<br>
> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Mon May 18 12:10:40 2015<br>
> @@ -526,6 +526,7 @@ let isBranch = 1, isTerminator = 1, isBa<br>
>                        0, IIC_Br,<br>
>                        [(ARMbrjt tGPR:$target, tjumptable:$jt)]>,<br>
>                        Sched<[WriteBrTbl]> {<br>
> +    let Size = 2;<br>
>      list<Predicate> Predicates = [IsThumb, IsThumb1Only];<br>
>    }<br>
>  }<br>
><br>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_ARM_ARMInstrThumb2.td-3Frev-3D237590-26r1-3D237589-26r2-3D237590-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=7IgQ1-L8ntMpi2rAIzptAjDwqCCQ_AYVE_IyvBtTNvw&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=237590&r1=237589&r2=237590&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)<br>
> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon May 18 12:10:40 2015<br>
> @@ -3531,20 +3531,20 @@ def t2B   : T2I<(outs), (ins uncondbrtar<br>
>    let AsmMatchConverter = "cvtThumbBranches";<br>
>  }<br>
><br>
> -let isNotDuplicable = 1, isIndirectBranch = 1 in {<br>
> +let Size = 4, isNotDuplicable = 1, isIndirectBranch = 1 in {<br>
>  def t2BR_JT : t2PseudoInst<(outs),<br>
>            (ins GPR:$target, GPR:$index, i32imm:$jt),<br>
>             0, IIC_Br,<br>
>            [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt)]>,<br>
>            Sched<[WriteBr]>;<br>
><br>
> -// FIXME: Add a non-pc based case that can be predicated.<br>
> +// FIXME: Add a case that can be predicated.<br>
>  def t2TBB_JT : t2PseudoInst<(outs),<br>
> -        (ins GPR:$index, i32imm:$jt), 0, IIC_Br, []>,<br>
> +        (ins GPR:$base, GPR:$index, i32imm:$jt, i32imm:$pclbl), 0, IIC_Br, []>,<br>
>          Sched<[WriteBr]>;<br>
><br>
>  def t2TBH_JT : t2PseudoInst<(outs),<br>
> -        (ins GPR:$index, i32imm:$jt), 0, IIC_Br, []>,<br>
> +        (ins GPR:$base, GPR:$index, i32imm:$jt, i32imm:$pclbl), 0, IIC_Br, []>,<br>
>          Sched<[WriteBr]>;<br>
><br>
>  def t2TBB : T2I<(outs), (ins addrmode_tbb:$addr), IIC_Br,<br>
><br>
> Added: llvm/trunk/test/CodeGen/ARM/jump-table-islands.ll<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_ARM_jump-2Dtable-2Dislands.ll-3Frev-3D237590-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=Icyph-XWFm71BRz0ey6Pa0o7bI6uZyYgjqk4c241h2s&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/jump-table-islands.ll?rev=237590&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/ARM/jump-table-islands.ll (added)<br>
> +++ llvm/trunk/test/CodeGen/ARM/jump-table-islands.ll Mon May 18 12:10:40 2015<br>
> @@ -0,0 +1,40 @@<br>
> +; RUN: llc -mtriple=armv7-apple-ios8.0 -o - %s | FileCheck %s<br>
> +<br>
> +%BigInt = type i5500<br>
> +<br>
> +define %BigInt @test_moved_jumptable(i1 %tst, i32 %sw, %BigInt %l) {<br>
> +; CHECK-LABEL: test_moved_jumptable:<br>
> +<br>
> +; CHECK:   adr {{r[0-9]+}}, [[JUMP_TABLE:LJTI[0-9]+_[0-9]+]]<br>
> +; CHECK:   b [[SKIP_TABLE:LBB[0-9]+_[0-9]+]]<br>
> +<br>
> +; CHECK: [[JUMP_TABLE]]:<br>
> +; CHECK:   .data_region jt32<br>
> +; CHECK:   .long LBB{{[0-9]+_[0-9]+}}-[[JUMP_TABLE]]<br>
> +<br>
> +; CHECK: [[SKIP_TABLE]]:<br>
> +; CHECK:   add pc, {{r[0-9]+}}, {{r[0-9]+}}<br>
> +  br i1 %tst, label %simple, label %complex<br>
> +<br>
> +simple:<br>
> +  br label %end<br>
> +<br>
> +complex:<br>
> +  switch i32 %sw, label %simple [ i32 0, label %other<br>
> +                                  i32 1, label %third<br>
> +                                  i32 5, label %end<br>
> +                                  i32 6, label %other ]<br>
> +<br>
> +third:<br>
> +  ret %BigInt 0<br>
> +<br>
> +other:<br>
> +  call void @bar()<br>
> +  unreachable<br>
> +<br>
> +end:<br>
> +  %val = phi %BigInt [ %l, %complex ], [ -1, %simple ]<br>
> +  ret %BigInt %val<br>
> +}<br>
> +<br>
> +declare void @bar()<br>
><br>
> Modified: llvm/trunk/test/CodeGen/ARM/jumptable-label.ll<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_ARM_jumptable-2Dlabel.ll-3Frev-3D237590-26r1-3D237589-26r2-3D237590-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=agk2exWjo_8Z7w2rKID7gar8IyfmMCajyVMTwP6Y5uo&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/jumptable-label.ll?rev=237590&r1=237589&r2=237590&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/ARM/jumptable-label.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/ARM/jumptable-label.ll Mon May 18 12:10:40 2015<br>
> @@ -2,8 +2,8 @@<br>
><br>
>  ; test that we print the label of a bb that is only used in a jump table.<br>
><br>
> -; CHECK:     .long   LBB0_2<br>
> -; CHECK: LBB0_2:<br>
> +; CHECK:     .long   [[JUMPTABLE_DEST:LBB[0-9]+_[0-9]+]]<br>
> +; CHECK: [[JUMPTABLE_DEST]]:<br>
><br>
>  define i32 @calculate()  {<br>
>  entry:<br>
><br>
> Modified: llvm/trunk/test/CodeGen/Thumb2/constant-islands-jump-table.ll<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_Thumb2_constant-2Dislands-2Djump-2Dtable.ll-3Frev-3D237590-26r1-3D237589-26r2-3D237590-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=doTKHuWUA8yc3zc7cb0tYwfuyXmGGuCMe08Vx_24maA&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/constant-islands-jump-table.ll?rev=237590&r1=237589&r2=237590&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/Thumb2/constant-islands-jump-table.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/Thumb2/constant-islands-jump-table.ll Mon May 18 12:10:40 2015<br>
> @@ -1,7 +1,7 @@<br>
>  ; RUN: llc < %s -mtriple=thumbv7-linux-gnueabihf -O1 %s -o - | FileCheck %s<br>
><br>
>  ; CHECK-LABEL: test_jump_table:<br>
> -; CHECK: b .LBB<br>
> +; CHECK: b{{.*}} .LBB<br>
>  ; CHECK-NOT: tbh<br>
><br>
>  define i32 @test_jump_table(i32 %x, float %in) {<br>
><br>
> Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-tbh.ll<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_Thumb2_thumb2-2Dtbh.ll-3Frev-3D237590-26r1-3D237589-26r2-3D237590-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=vvl6suS3FHb8SxNDml1YWdMlGNLBHMB_Fyg0zO0Lp9o&s=fS8acIcazi-ziEJ0wIHlEUdqeU_IVdVfPPPjwyQd9NU&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-tbh.ll?rev=237590&r1=237589&r2=237590&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/Thumb2/thumb2-tbh.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/Thumb2/thumb2-tbh.ll Mon May 18 12:10:40 2015<br>
> @@ -14,9 +14,19 @@ declare void @Z_fatal(i8*) noreturn noun<br>
><br>
>  declare noalias i8* @calloc(i32, i32) nounwind<br>
><br>
> +; Jump tables are not anchored next to the TBB/TBH any more. Make sure the<br>
> +; correct address is still calculated (i.e. via a PC-relative symbol *at* the<br>
> +; TBB/TBH).<br>
>  define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {<br>
>  ; CHECK-LABEL: main:<br>
> -; CHECK: tbb<br>
> +; CHECK-NOT: adr {{r[0-9]+}}, LJTI<br>
> +; CHECK: [[PCREL_ANCHOR:LCPI[0-9]+_[0-9]+]]:<br>
> +; CHECK-NEXT:     tbb [pc, {{r[0-9]+}}]<br>
> +<br>
> +; CHECK: LJTI0_0:<br>
> +; CHECK-NEXT: .data_region jt8<br>
> +; CHECK-NEXT: .byte (LBB{{[0-9]+_[0-9]+}}-([[PCREL_ANCHOR]]+4))/2<br>
> +<br>
>  entry:<br>
>       br label %bb42.i<br>
><br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
><br>
<br>
--<br>
Peter<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>