From: Tim Northover Date: Mon, 25 Nov 2013 16:24:52 +0000 (+0000) Subject: ARM: remove special cases for Darwin dynamic-no-pic mode. X-Git-Tag: android-x86-7.1-r4~67363 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ff3808915c82806a83e99918a96b813bcd6ed51a;p=android-x86%2Fexternal-llvm.git 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195655 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index e79f88d4b6f..122aafd5bf1 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -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(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(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)); diff --git a/lib/Target/ARM/ARMAsmPrinter.h b/lib/Target/ARM/ARMAsmPrinter.h index de72e063e0d..70064001071 100644 --- a/lib/Target/ARM/ARMAsmPrinter.h +++ b/lib/Target/ARM/ARMAsmPrinter.h @@ -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 diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 67534c4a445..dc3e81a1136 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -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(); diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp index e6f7f86c558..d4302cbb107 100644 --- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -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)) diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index a4004f32db3..e04a4ef1a1c 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -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()); diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 76a0a831f69..f66ff35aaa9 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -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(), diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index f195381538b..f17b8df0c9b 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -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 diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 6b9485c0b81..3ef50f095ff 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -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, diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 44ce649f94a..10ba894329e 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -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 diff --git a/lib/Target/ARM/ARMMCInstLower.cpp b/lib/Target/ARM/ARMMCInstLower.cpp index e12c9c61ab1..1cc987ce99d 100644 --- a/lib/Target/ARM/ARMMCInstLower.cpp +++ b/lib/Target/ARM/ARMMCInstLower.cpp @@ -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())); diff --git a/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h b/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h index af939fc1912..bb781ecece0 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h +++ b/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h @@ -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 {