Workaround a couple of Darwin assembler bugs.
llvm-svn: 77781
This commit is contained in:
parent
769f940655
commit
e64f48ba8b
|
@ -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
|
// 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
|
// bytes, we can use 16-bit entries instead. Then there won't be an
|
||||||
// alignment issue.
|
// alignment issue.
|
||||||
unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT)
|
unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT) ? 2 : 4;
|
||||||
? 2 : 4;
|
unsigned NumEntries = getNumJTEntries(JT, JTI);
|
||||||
return getNumJTEntries(JT, JTI) * EntrySize + InstSize;
|
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:
|
default:
|
||||||
// Otherwise, pseudo-instruction sizes are zero.
|
// Otherwise, pseudo-instruction sizes are zero.
|
||||||
|
|
|
@ -132,6 +132,7 @@ namespace {
|
||||||
bool HasFarJump;
|
bool HasFarJump;
|
||||||
|
|
||||||
const TargetInstrInfo *TII;
|
const TargetInstrInfo *TII;
|
||||||
|
const ARMSubtarget *STI;
|
||||||
ARMFunctionInfo *AFI;
|
ARMFunctionInfo *AFI;
|
||||||
bool isThumb;
|
bool isThumb;
|
||||||
bool isThumb1;
|
bool isThumb1;
|
||||||
|
@ -227,6 +228,8 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {
|
||||||
|
|
||||||
TII = MF.getTarget().getInstrInfo();
|
TII = MF.getTarget().getInstrInfo();
|
||||||
AFI = MF.getInfo<ARMFunctionInfo>();
|
AFI = MF.getInfo<ARMFunctionInfo>();
|
||||||
|
STI = &MF.getTarget().getSubtarget<ARMSubtarget>();
|
||||||
|
|
||||||
isThumb = AFI->isThumbFunction();
|
isThumb = AFI->isThumbFunction();
|
||||||
isThumb1 = AFI->isThumb1OnlyFunction();
|
isThumb1 = AFI->isThumb1OnlyFunction();
|
||||||
isThumb2 = AFI->isThumb2Function();
|
isThumb2 = AFI->isThumb2Function();
|
||||||
|
@ -281,6 +284,9 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {
|
||||||
MadeChange = true;
|
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.
|
// After a while, this might be made debug-only, but it is not expensive.
|
||||||
verify(MF);
|
verify(MF);
|
||||||
|
|
||||||
|
@ -289,9 +295,6 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {
|
||||||
if (isThumb && !HasFarJump && AFI->isLRSpilledForFarJump())
|
if (isThumb && !HasFarJump && AFI->isLRSpilledForFarJump())
|
||||||
MadeChange |= UndoLRSpillRestore();
|
MadeChange |= UndoLRSpillRestore();
|
||||||
|
|
||||||
// Let's see if we can use tbb / tbh to do jump tables.
|
|
||||||
MadeChange |= OptimizeThumb2JumpTables(MF);
|
|
||||||
|
|
||||||
BBSizes.clear();
|
BBSizes.clear();
|
||||||
BBOffsets.clear();
|
BBOffsets.clear();
|
||||||
WaterList.clear();
|
WaterList.clear();
|
||||||
|
@ -464,6 +467,8 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &MF,
|
||||||
bool NegOk = false;
|
bool NegOk = false;
|
||||||
bool IsSoImm = false;
|
bool IsSoImm = false;
|
||||||
|
|
||||||
|
// FIXME: Temporary workaround until I can figure out what's going on.
|
||||||
|
unsigned Slack = T2JumpTables.empty() ? 0 : 4;
|
||||||
switch (Opc) {
|
switch (Opc) {
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("Unknown addressing mode for CP reference!");
|
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.
|
// Remember that this is a user of a CP entry.
|
||||||
unsigned CPI = I->getOperand(op).getIndex();
|
unsigned CPI = I->getOperand(op).getIndex();
|
||||||
MachineInstr *CPEMI = CPEMIs[CPI];
|
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));
|
CPUsers.push_back(CPUser(I, CPEMI, MaxOffs, NegOk, IsSoImm));
|
||||||
|
|
||||||
// Increment corresponding CPEntry reference count.
|
// 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.
|
// 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.
|
// 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;
|
BBSizes[OrigBBI] -= NewBBSize - delta;
|
||||||
|
|
||||||
// ...and adjust BBOffsets for NewBB accordingly.
|
// ...and adjust BBOffsets for NewBB accordingly.
|
||||||
|
@ -1362,7 +1367,10 @@ bool ARMConstantIslands::OptimizeThumb2JumpTables(MachineFunction &MF) {
|
||||||
// sure all the branches are forward.
|
// sure all the branches are forward.
|
||||||
if (ByteOk && (DstOffset - JTOffset) > ((1<<8)-1)*2)
|
if (ByteOk && (DstOffset - JTOffset) > ((1<<8)-1)*2)
|
||||||
ByteOk = false;
|
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;
|
HalfWordOk = false;
|
||||||
if (!ByteOk && !HalfWordOk)
|
if (!ByteOk && !HalfWordOk)
|
||||||
break;
|
break;
|
||||||
|
@ -1406,23 +1414,33 @@ bool ARMConstantIslands::OptimizeThumb2JumpTables(MachineFunction &MF) {
|
||||||
MachineInstr *LeaMI = --PrevI;
|
MachineInstr *LeaMI = --PrevI;
|
||||||
if (LeaMI->getOpcode() != ARM::t2LEApcrelJT ||
|
if (LeaMI->getOpcode() != ARM::t2LEApcrelJT ||
|
||||||
LeaMI->getOperand(0).getReg() != BaseReg)
|
LeaMI->getOperand(0).getReg() != BaseReg)
|
||||||
LeaMI = 0;
|
OptOk = false;
|
||||||
|
|
||||||
if (OptOk) {
|
if (!OptOk)
|
||||||
unsigned Opc = ByteOk ? ARM::t2TBB : ARM::t2TBH;
|
continue;
|
||||||
AddDefaultPred(BuildMI(MBB, MI->getDebugLoc(), TII->get(Opc))
|
|
||||||
.addReg(IdxReg, getKillRegState(IdxRegKill))
|
unsigned Opc = ByteOk ? ARM::t2TBB : ARM::t2TBH;
|
||||||
.addJumpTableIndex(JTI, JTOP.getTargetFlags())
|
MachineInstr *NewJTMI = BuildMI(MBB, MI->getDebugLoc(), TII->get(Opc))
|
||||||
.addImm(MI->getOperand(JTOpIdx+1).getImm()));
|
.addReg(IdxReg, getKillRegState(IdxRegKill))
|
||||||
// FIXME: Insert an "ALIGN" instruction to ensure the next instruction
|
.addJumpTableIndex(JTI, JTOP.getTargetFlags())
|
||||||
// is 2-byte aligned. For now, asm printer will fix it up.
|
.addImm(MI->getOperand(JTOpIdx+1).getImm());
|
||||||
AddrMI->eraseFromParent();
|
// FIXME: Insert an "ALIGN" instruction to ensure the next instruction
|
||||||
if (LeaMI)
|
// is 2-byte aligned. For now, asm printer will fix it up.
|
||||||
LeaMI->eraseFromParent();
|
unsigned NewSize = TII->GetInstSizeInBytes(NewJTMI);
|
||||||
MI->eraseFromParent();
|
unsigned OrigSize = TII->GetInstSizeInBytes(AddrMI);
|
||||||
++NumTBs;
|
OrigSize += TII->GetInstSizeInBytes(LeaMI);
|
||||||
MadeChange = true;
|
OrigSize += TII->GetInstSizeInBytes(MI);
|
||||||
}
|
|
||||||
|
AddrMI->eraseFromParent();
|
||||||
|
LeaMI->eraseFromParent();
|
||||||
|
MI->eraseFromParent();
|
||||||
|
|
||||||
|
int delta = OrigSize - NewSize;
|
||||||
|
BBSizes[MBB->getNumber()] -= delta;
|
||||||
|
AdjustBBOffsetsAfter(MBB, -delta);
|
||||||
|
|
||||||
|
++NumTBs;
|
||||||
|
MadeChange = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
|
||||||
|
|
||||||
|
/*
|
||||||
defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
|
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
|
// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
|
||||||
let AddedComplexity = 1 in
|
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),
|
def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
|
||||||
(t2BICri 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),
|
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),
|
def : T2Pat<(t2_so_imm_not:$src),
|
||||||
(t2MVNi t2_so_imm_not:$src)>;
|
(t2MVNi t2_so_imm_not:$src)>;
|
||||||
|
@ -1037,15 +1053,16 @@ def t2BR_JT :
|
||||||
"mov pc, $target\n$jt",
|
"mov pc, $target\n$jt",
|
||||||
[(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
|
[(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
|
||||||
|
|
||||||
|
// FIXME: Add a non-pc based case that can be predicated.
|
||||||
def t2TBB :
|
def t2TBB :
|
||||||
T2I<(outs),
|
T2JTI<(outs),
|
||||||
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
|
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
|
||||||
"tbb", " $index\n$jt", []>;
|
"tbb $index\n$jt", []>;
|
||||||
|
|
||||||
def t2TBH :
|
def t2TBH :
|
||||||
T2I<(outs),
|
T2JTI<(outs),
|
||||||
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
|
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
|
||||||
"tbh", " $index\n$jt", []>;
|
"tbh $index\n$jt", []>;
|
||||||
} // isNotDuplicable, isIndirectBranch
|
} // isNotDuplicable, isIndirectBranch
|
||||||
|
|
||||||
} // isBranch, isTerminator, isBarrier
|
} // isBranch, isTerminator, isBarrier
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep {orn\\W*r\[0-9\]*,\\W*r\[0-9\]*,\\W*#\[0-9\]*} | grep {#187\\|#11141290\\|#3422604288\\|#1114112} | count 4
|
; RUN: llvm-as < %s | llc -mtriple=thumb-linux -mattr=+thumb2 | grep {orn\\W*r\[0-9\]*,\\W*r\[0-9\]*,\\W*#\[0-9\]*} | grep {#187\\|#11141290\\|#3422604288\\|#1114112} | count 4
|
||||||
|
|
||||||
; 0x000000bb = 187
|
; 0x000000bb = 187
|
||||||
define i32 @f1(i32 %a) {
|
define i32 @f1(i32 %a) {
|
||||||
|
|
Loading…
Reference in New Issue