ARM: remove special cases for Darwin dynamic-no-pic mode.

These are handled almost identically to static mode (and ELF's global address
materialisation), except that a symbol may have "$non_lazy_ptr" appended. This
can be handled by passing appropriate flags along with the instruction instead
of using entirely separate pseudo-instructions.

llvm-svn: 195655
This commit is contained in:
Tim Northover 2013-11-25 16:24:52 +00:00
parent edcf1ff7d1
commit db962e2c45
11 changed files with 73 additions and 104 deletions

View File

@ -774,8 +774,10 @@ getModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
llvm_unreachable("Invalid ARMCPModifier!");
}
MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) {
MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV,
unsigned char TargetFlags) {
bool isIndirect = Subtarget->isTargetDarwin() &&
(TargetFlags & ARMII::MO_NONLAZY) &&
Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
if (!isIndirect)
return getSymbol(GV);
@ -811,7 +813,11 @@ EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
MCSym = GetBlockAddressSymbol(BA);
} else if (ACPV->isGlobalValue()) {
const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
MCSym = GetARMGVSymbol(GV);
// On Darwin, const-pool entries may get the "FOO$non_lazy_ptr" mangling, so
// flag the global as MO_NONLAZY.
unsigned char TF = Subtarget->isTargetDarwin() ? ARMII::MO_NONLAZY : 0;
MCSym = GetARMGVSymbol(GV, TF);
} else if (ACPV->isMachineBasicBlock()) {
const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB();
MCSym = MBB->getSymbol();
@ -1239,26 +1245,21 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
unsigned TF = MI->getOperand(1).getTargetFlags();
bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC;
const GlobalValue *GV = MI->getOperand(1).getGlobal();
MCSymbol *GVSym = GetARMGVSymbol(GV);
MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
if (isPIC) {
MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
getFunctionNumber(),
MI->getOperand(2).getImm(), OutContext);
const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
const MCExpr *PCRelExpr =
ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr,
MCBinaryExpr::CreateAdd(LabelSymExpr,
MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
getFunctionNumber(),
MI->getOperand(2).getImm(), OutContext);
const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
const MCExpr *PCRelExpr =
ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr,
MCBinaryExpr::CreateAdd(LabelSymExpr,
MCConstantExpr::Create(PCAdj, OutContext),
OutContext), OutContext), OutContext);
OutContext), OutContext), OutContext);
TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
} else {
const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext);
TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
}
// Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
@ -1277,26 +1278,21 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
unsigned TF = MI->getOperand(2).getTargetFlags();
bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC;
const GlobalValue *GV = MI->getOperand(2).getGlobal();
MCSymbol *GVSym = GetARMGVSymbol(GV);
MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
if (isPIC) {
MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
getFunctionNumber(),
MI->getOperand(3).getImm(), OutContext);
const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
const MCExpr *PCRelExpr =
MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
getFunctionNumber(),
MI->getOperand(3).getImm(), OutContext);
const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
const MCExpr *PCRelExpr =
ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr,
MCBinaryExpr::CreateAdd(LabelSymExpr,
MCConstantExpr::Create(PCAdj, OutContext),
OutContext), OutContext), OutContext);
TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
} else {
const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext);
TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
}
// Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
TmpInst.addOperand(MCOperand::CreateReg(0));

View File

@ -115,7 +115,7 @@ private:
MCSymbol *GetARMSJLJEHLabel() const;
MCSymbol *GetARMGVSymbol(const GlobalValue *GV);
MCSymbol *GetARMGVSymbol(const GlobalValue *GV, unsigned char TargetFlags);
public:
/// EmitMachineConstantPoolValue - Print a machine constantpool value to

View File

@ -1325,10 +1325,8 @@ bool ARMBaseInstrInfo::produceSameValue(const MachineInstr *MI0,
Opcode == ARM::t2LDRpci_pic ||
Opcode == ARM::tLDRpci ||
Opcode == ARM::tLDRpci_pic ||
Opcode == ARM::MOV_ga_dyn ||
Opcode == ARM::MOV_ga_pcrel ||
Opcode == ARM::MOV_ga_pcrel_ldr ||
Opcode == ARM::t2MOV_ga_dyn ||
Opcode == ARM::t2MOV_ga_pcrel) {
if (MI1->getOpcode() != Opcode)
return false;
@ -1340,10 +1338,8 @@ bool ARMBaseInstrInfo::produceSameValue(const MachineInstr *MI0,
if (MO0.getOffset() != MO1.getOffset())
return false;
if (Opcode == ARM::MOV_ga_dyn ||
Opcode == ARM::MOV_ga_pcrel ||
if (Opcode == ARM::MOV_ga_pcrel ||
Opcode == ARM::MOV_ga_pcrel_ldr ||
Opcode == ARM::t2MOV_ga_dyn ||
Opcode == ARM::t2MOV_ga_pcrel)
// Ignore the PC labels.
return MO0.getGlobal() == MO1.getGlobal();

View File

@ -898,10 +898,8 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
return true;
}
case ARM::MOV_ga_dyn:
case ARM::MOV_ga_pcrel:
case ARM::MOV_ga_pcrel_ldr:
case ARM::t2MOV_ga_dyn:
case ARM::t2MOV_ga_pcrel: {
// Expand into movw + movw. Also "add pc" / ldr [pc] in PIC mode.
unsigned LabelId = AFI->createPICLabelUId();
@ -910,14 +908,11 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
const MachineOperand &MO1 = MI.getOperand(1);
const GlobalValue *GV = MO1.getGlobal();
unsigned TF = MO1.getTargetFlags();
bool isARM = (Opcode != ARM::t2MOV_ga_pcrel && Opcode!=ARM::t2MOV_ga_dyn);
bool isPIC = (Opcode != ARM::MOV_ga_dyn && Opcode != ARM::t2MOV_ga_dyn);
bool isARM = Opcode != ARM::t2MOV_ga_pcrel;
unsigned LO16Opc = isARM ? ARM::MOVi16_ga_pcrel : ARM::t2MOVi16_ga_pcrel;
unsigned HI16Opc = isARM ? ARM::MOVTi16_ga_pcrel :ARM::t2MOVTi16_ga_pcrel;
unsigned LO16TF = isPIC
? ARMII::MO_LO16_NONLAZY_PIC : ARMII::MO_LO16_NONLAZY;
unsigned HI16TF = isPIC
? ARMII::MO_HI16_NONLAZY_PIC : ARMII::MO_HI16_NONLAZY;
unsigned LO16TF = TF | ARMII::MO_LO16;
unsigned HI16TF = TF | ARMII::MO_HI16;
unsigned PICAddOpc = isARM
? (Opcode == ARM::MOV_ga_pcrel_ldr ? ARM::PICLDR : ARM::PICADD)
: ARM::tPICADD;
@ -925,16 +920,11 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
TII->get(LO16Opc), DstReg)
.addGlobalAddress(GV, MO1.getOffset(), TF | LO16TF)
.addImm(LabelId);
MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
TII->get(HI16Opc), DstReg)
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc), DstReg)
.addReg(DstReg)
.addGlobalAddress(GV, MO1.getOffset(), TF | HI16TF)
.addImm(LabelId);
if (!isPIC) {
TransferImpOps(MI, MIB1, MIB2);
MI.eraseFromParent();
return true;
}
MachineInstrBuilder MIB3 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
TII->get(PICAddOpc))

View File

@ -685,19 +685,20 @@ unsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, MVT VT) {
if (Subtarget->useMovt() &&
Subtarget->isTargetDarwin() == (RelocM != Reloc::Static)) {
unsigned Opc;
unsigned char TF = 0;
if (Subtarget->isTargetDarwin() && RelocM != Reloc::Static)
TF = ARMII::MO_NONLAZY;
switch (RelocM) {
case Reloc::PIC_:
Opc = isThumb2 ? ARM::t2MOV_ga_pcrel : ARM::MOV_ga_pcrel;
break;
case Reloc::DynamicNoPIC:
Opc = isThumb2 ? ARM::t2MOV_ga_dyn : ARM::MOV_ga_dyn;
break;
default:
Opc = isThumb2 ? ARM::t2MOVi32imm : ARM::MOVi32imm;
break;
}
AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
DestReg).addGlobalAddress(GV));
DestReg).addGlobalAddress(GV, 0, TF));
} else {
// MachineConstantPool wants an explicit alignment.
unsigned Align = TD.getPrefTypeAlignment(GV->getType());

View File

@ -1009,7 +1009,6 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
switch (Opcode) {
default: return 0;
case ARMISD::Wrapper: return "ARMISD::Wrapper";
case ARMISD::WrapperDYN: return "ARMISD::WrapperDYN";
case ARMISD::WrapperPIC: return "ARMISD::WrapperPIC";
case ARMISD::WrapperJT: return "ARMISD::WrapperJT";
case ARMISD::CALL: return "ARMISD::CALL";
@ -2548,10 +2547,12 @@ SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
return DAG.getNode(ARMISD::Wrapper, dl, PtrVT,
DAG.getTargetGlobalAddress(GV, dl, PtrVT));
unsigned Wrapper = (RelocM == Reloc::PIC_)
? ARMISD::WrapperPIC : ARMISD::WrapperDYN;
SDValue Result = DAG.getNode(Wrapper, dl, PtrVT,
DAG.getTargetGlobalAddress(GV, dl, PtrVT));
unsigned Wrapper =
RelocM == Reloc::PIC_ ? ARMISD::WrapperPIC : ARMISD::Wrapper;
SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, ARMII::MO_NONLAZY);
SDValue Result = DAG.getNode(Wrapper, dl, PtrVT, G);
if (Subtarget->GVIsIndirectSymbol(GV, RelocM))
Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
MachinePointerInfo::getGOT(),

View File

@ -35,8 +35,6 @@ namespace llvm {
Wrapper, // Wrapper - A wrapper node for TargetConstantPool,
// TargetExternalSymbol, and TargetGlobalAddress.
WrapperDYN, // WrapperDYN - A wrapper node for TargetGlobalAddress in
// DYN mode.
WrapperPIC, // WrapperPIC - A wrapper node for TargetGlobalAddress in
// PIC mode.
WrapperJT, // WrapperJT - A wrapper node for TargetJumpTable

View File

@ -95,7 +95,6 @@ def ARMSmlal : SDNode<"ARMISD::SMLAL", SDT_ARM64bitmlal>;
// Node definitions.
def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
def ARMWrapperDYN : SDNode<"ARMISD::WrapperDYN", SDTIntUnaryOp>;
def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntUnaryOp>;
def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
@ -5193,11 +5192,6 @@ def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
[(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
Requires<[IsARM, UseMovt]>;
def MOV_ga_dyn : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
IIC_iMOVix2,
[(set GPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
Requires<[IsARM, UseMovt]>;
let AddedComplexity = 10 in
def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
IIC_iMOVix2ld,

View File

@ -3793,10 +3793,6 @@ def t2MOV_ga_pcrel : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr),
[(set rGPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
Requires<[IsThumb2, UseMovt]>;
def t2MOV_ga_dyn : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr),
IIC_iMOVix2,
[(set rGPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>,
Requires<[IsThumb2, UseMovt]>;
}
// ConstantPool, GlobalAddress, and JumpTable

View File

@ -26,11 +26,12 @@ using namespace llvm;
MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
const MCSymbol *Symbol) {
const MCExpr *Expr;
switch (MO.getTargetFlags()) {
unsigned Option = MO.getTargetFlags() & ARMII::MO_OPTION_MASK;
switch (Option) {
default: {
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
OutContext);
switch (MO.getTargetFlags()) {
switch (Option) {
default: llvm_unreachable("Unknown target flag on symbol operand");
case 0:
break;
@ -81,9 +82,11 @@ bool ARMAsmPrinter::lowerOperand(const MachineOperand &MO,
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
MO.getMBB()->getSymbol(), OutContext));
break;
case MachineOperand::MO_GlobalAddress:
MCOp = GetSymbolRef(MO, getSymbol(MO.getGlobal()));
case MachineOperand::MO_GlobalAddress: {
MCOp = GetSymbolRef(MO,
GetARMGVSymbol(MO.getGlobal(), MO.getTargetFlags()));
break;
}
case MachineOperand::MO_ExternalSymbol:
MCOp = GetSymbolRef(MO,
GetExternalSymbolSymbol(MO.getSymbolName()));

View File

@ -278,42 +278,36 @@ namespace ARMII {
//===------------------------------------------------------------------===//
// ARM Specific MachineOperand flags.
MO_NO_FLAG,
MO_NO_FLAG = 0,
/// MO_LO16 - On a symbol operand, this represents a relocation containing
/// lower 16 bit of the address. Used only via movw instruction.
MO_LO16,
MO_LO16 = 0x1,
/// MO_HI16 - On a symbol operand, this represents a relocation containing
/// higher 16 bit of the address. Used only via movt instruction.
MO_HI16,
/// MO_LO16_NONLAZY - On a symbol operand "FOO", this represents a
/// relocation containing lower 16 bit of the non-lazy-ptr indirect symbol,
/// i.e. "FOO$non_lazy_ptr".
/// Used only via movw instruction.
MO_LO16_NONLAZY,
/// MO_HI16_NONLAZY - On a symbol operand "FOO", this represents a
/// relocation containing lower 16 bit of the non-lazy-ptr indirect symbol,
/// i.e. "FOO$non_lazy_ptr". Used only via movt instruction.
MO_HI16_NONLAZY,
/// MO_LO16_NONLAZY_PIC - On a symbol operand "FOO", this represents a
/// relocation containing lower 16 bit of the PC relative address of the
/// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".
/// Used only via movw instruction.
MO_LO16_NONLAZY_PIC,
/// MO_HI16_NONLAZY_PIC - On a symbol operand "FOO", this represents a
/// relocation containing lower 16 bit of the PC relative address of the
/// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".
/// Used only via movt instruction.
MO_HI16_NONLAZY_PIC,
MO_HI16 = 0x2,
/// MO_PLT - On a symbol operand, this represents an ELF PLT reference on a
/// call operand.
MO_PLT
MO_PLT = 0x3,
/// MO_OPTION_MASK - Most flags are mutually exclusive; this mask selects
/// just that part of the flag set.
MO_OPTION_MASK = 0x7f,
/// MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it
/// represents a symbol which, if indirect, will get special Darwin mangling
/// as a non-lazy-ptr indirect symbol (i.e. "L_FOO$non_lazy_ptr"). Can be
/// combined with MO_LO16, MO_HI16 or MO_NO_FLAG (in a constant-pool, for
/// example).
MO_NONLAZY = 0x80,
// It's undefined behaviour if an enum overflows the range between its
// smallest and largest values, but since these are |ed together, it can
// happen. Put a sentinel in (values of this enum are stored as "unsigned
// char").
MO_UNUSED_MAXIMUM = 0xff
};
enum {