diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2009-08-01 06:13:52 +0000 | 
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2009-08-01 06:13:52 +0000 | 
| commit | e64f48ba8b51f54bf0f1d1a53e33e5a314d04466 (patch) | |
| tree | b352defb26d9c9d38f8882de323a69767e0a9b3c /llvm/lib/Target/ARM | |
| parent | 769f940655255f2929f10c553743a1764ef0e629 (diff) | |
| download | bcm5719-llvm-e64f48ba8b51f54bf0f1d1a53e33e5a314d04466.tar.gz bcm5719-llvm-e64f48ba8b51f54bf0f1d1a53e33e5a314d04466.zip | |
Workaround a couple of Darwin assembler bugs.
llvm-svn: 77781
Diffstat (limited to 'llvm/lib/Target/ARM')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMConstantIslandPass.cpp | 64 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 27 | 
3 files changed, 71 insertions, 31 deletions
| diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index 84fad70c15e..8dca6efbe84 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -466,9 +466,14 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {        // FIXME: If we know the size of the function is less than (1 << 16) *2        // bytes, we can use 16-bit entries instead. Then there won't be an        // alignment issue. -      unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT) -        ? 2 : 4; -      return getNumJTEntries(JT, JTI) * EntrySize + InstSize; +      unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT) ? 2 : 4; +      unsigned NumEntries = getNumJTEntries(JT, JTI); +      if (Opc == ARM::t2TBB && (NumEntries & 1)) +        // Make sure the instruction that follows TBB is 2-byte aligned. +        // FIXME: Constant island pass should insert an "ALIGN" instruction +        // instead. +        ++NumEntries; +      return NumEntries * EntrySize + InstSize;      }      default:        // Otherwise, pseudo-instruction sizes are zero. diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp index bf2784a54da..782765a4335 100644 --- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -132,6 +132,7 @@ namespace {      bool HasFarJump;      const TargetInstrInfo *TII; +    const ARMSubtarget *STI;      ARMFunctionInfo *AFI;      bool isThumb;      bool isThumb1; @@ -227,6 +228,8 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {    TII = MF.getTarget().getInstrInfo();    AFI = MF.getInfo<ARMFunctionInfo>(); +  STI = &MF.getTarget().getSubtarget<ARMSubtarget>(); +    isThumb = AFI->isThumbFunction();    isThumb1 = AFI->isThumb1OnlyFunction();    isThumb2 = AFI->isThumb2Function(); @@ -281,6 +284,9 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {      MadeChange = true;    } +  // Let's see if we can use tbb / tbh to do jump tables. +  MadeChange |= OptimizeThumb2JumpTables(MF); +    // After a while, this might be made debug-only, but it is not expensive.    verify(MF); @@ -289,9 +295,6 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {    if (isThumb && !HasFarJump && AFI->isLRSpilledForFarJump())      MadeChange |= UndoLRSpillRestore(); -  // Let's see if we can use tbb / tbh to do jump tables. -  MadeChange |= OptimizeThumb2JumpTables(MF); -    BBSizes.clear();    BBOffsets.clear();    WaterList.clear(); @@ -464,6 +467,8 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &MF,            bool NegOk = false;            bool IsSoImm = false; +          // FIXME: Temporary workaround until I can figure out what's going on. +          unsigned Slack = T2JumpTables.empty() ? 0 : 4;            switch (Opc) {            default:              llvm_unreachable("Unknown addressing mode for CP reference!"); @@ -513,7 +518,7 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &MF,            // Remember that this is a user of a CP entry.            unsigned CPI = I->getOperand(op).getIndex();            MachineInstr *CPEMI = CPEMIs[CPI]; -          unsigned MaxOffs = ((1 << Bits)-1) * Scale; +          unsigned MaxOffs = ((1 << Bits)-1) * Scale - Slack;            CPUsers.push_back(CPUser(I, CPEMI, MaxOffs, NegOk, IsSoImm));            // Increment corresponding CPEntry reference count. @@ -675,7 +680,7 @@ MachineBasicBlock *ARMConstantIslands::SplitBlockBeforeInstr(MachineInstr *MI) {    // We removed instructions from UserMBB, subtract that off from its size.    // Add 2 or 4 to the block to count the unconditional branch we added to it. -  unsigned delta = isThumb1 ? 2 : 4; +  int delta = isThumb1 ? 2 : 4;    BBSizes[OrigBBI] -= NewBBSize - delta;    // ...and adjust BBOffsets for NewBB accordingly. @@ -1362,7 +1367,10 @@ bool ARMConstantIslands::OptimizeThumb2JumpTables(MachineFunction &MF) {        // sure all the branches are forward.        if (ByteOk && (DstOffset - JTOffset) > ((1<<8)-1)*2)          ByteOk = false; -      if (HalfWordOk && (DstOffset - JTOffset) > ((1<<16)-1)*2) +      unsigned TBHLimit = ((1<<16)-1)*2; +      if (STI->isTargetDarwin()) +        TBHLimit >>= 1;  // FIXME: Work around an assembler bug. +      if (HalfWordOk && (DstOffset - JTOffset) > TBHLimit)          HalfWordOk = false;        if (!ByteOk && !HalfWordOk)          break; @@ -1406,23 +1414,33 @@ bool ARMConstantIslands::OptimizeThumb2JumpTables(MachineFunction &MF) {        MachineInstr *LeaMI = --PrevI;        if (LeaMI->getOpcode() != ARM::t2LEApcrelJT ||            LeaMI->getOperand(0).getReg() != BaseReg) -        LeaMI = 0; - -      if (OptOk) { -        unsigned Opc = ByteOk ? ARM::t2TBB : ARM::t2TBH; -        AddDefaultPred(BuildMI(MBB, MI->getDebugLoc(), TII->get(Opc)) -                       .addReg(IdxReg, getKillRegState(IdxRegKill)) -                       .addJumpTableIndex(JTI, JTOP.getTargetFlags()) -                       .addImm(MI->getOperand(JTOpIdx+1).getImm())); -        // FIXME: Insert an "ALIGN" instruction to ensure the next instruction -        // is 2-byte aligned. For now, asm printer will fix it up. -        AddrMI->eraseFromParent(); -        if (LeaMI) -          LeaMI->eraseFromParent(); -        MI->eraseFromParent(); -        ++NumTBs; -        MadeChange = true; -      } +        OptOk = false; + +      if (!OptOk) +        continue; + +      unsigned Opc = ByteOk ? ARM::t2TBB : ARM::t2TBH; +      MachineInstr *NewJTMI = BuildMI(MBB, MI->getDebugLoc(), TII->get(Opc)) +        .addReg(IdxReg, getKillRegState(IdxRegKill)) +        .addJumpTableIndex(JTI, JTOP.getTargetFlags()) +        .addImm(MI->getOperand(JTOpIdx+1).getImm()); +      // FIXME: Insert an "ALIGN" instruction to ensure the next instruction +      // is 2-byte aligned. For now, asm printer will fix it up. +      unsigned NewSize = TII->GetInstSizeInBytes(NewJTMI); +      unsigned OrigSize = TII->GetInstSizeInBytes(AddrMI); +      OrigSize += TII->GetInstSizeInBytes(LeaMI); +      OrigSize += TII->GetInstSizeInBytes(MI); + +      AddrMI->eraseFromParent(); +      LeaMI->eraseFromParent(); +      MI->eraseFromParent(); + +      int delta = OrigSize - NewSize; +      BBSizes[MBB->getNumber()] -= delta; +      AdjustBBOffsetsAfter(MBB, -delta); + +      ++NumTBs; +      MadeChange = true;      }    } diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index afab366639b..8c562b04355 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -749,7 +749,21 @@ def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),  // FIXME: A8.6.18  BFI - Bitfield insert (Encoding T1) +/*  defm t2ORN  : T2I_bin_irs<"orn", BinOpFrag<(or  node:$LHS, (not node:$RHS))>>; +*/ +// FIXME: Disable this pattern on Darwin to workaround an assembler bug. +def t2ORNri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), +                   "orn", " $dst, $lhs, $rhs", +                   [(set GPR:$dst, (or GPR:$lhs, (not t2_so_imm:$rhs)))]>, +                   Requires<[IsThumb2, IsNotDarwin]>; + +def t2ORNrr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), +                   "orn", " $dst, $lhs, $rhs", +                   [(set GPR:$dst, (or GPR:$lhs, (not GPR:$rhs)))]>; +def t2ORNrs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), +                   "orn", " $dst, $lhs, $rhs", +                   [(set GPR:$dst, (or GPR:$lhs, (not t2_so_reg:$rhs)))]>;  // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version  let AddedComplexity = 1 in @@ -759,8 +773,10 @@ defm t2MVN  : T2I_un_irs  <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;  def : T2Pat<(and     GPR:$src, t2_so_imm_not:$imm),              (t2BICri GPR:$src, t2_so_imm_not:$imm)>; +// FIXME: Disable this pattern on Darwin to workaround an assembler bug.  def : T2Pat<(or      GPR:$src, t2_so_imm_not:$imm), -            (t2ORNri GPR:$src, t2_so_imm_not:$imm)>; +            (t2ORNri GPR:$src, t2_so_imm_not:$imm)>, +            Requires<[IsThumb2, IsNotDarwin]>;  def : T2Pat<(t2_so_imm_not:$src),              (t2MVNi t2_so_imm_not:$src)>; @@ -1037,15 +1053,16 @@ def t2BR_JT :            "mov pc, $target\n$jt",            [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>; +// FIXME: Add a non-pc based case that can be predicated.  def t2TBB : -    T2I<(outs), +    T2JTI<(outs),          (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), -        "tbb", " $index\n$jt", []>; +        "tbb $index\n$jt", []>;  def t2TBH : -    T2I<(outs), +    T2JTI<(outs),          (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), -        "tbh", " $index\n$jt", []>; +        "tbh $index\n$jt", []>;  } // isNotDuplicable, isIndirectBranch  } // isBranch, isTerminator, isBarrier | 

