diff options
| author | Vladimir Stefanovic <vladimir.stefanovic@rt-rk.com> | 2019-01-17 21:50:37 +0000 | 
|---|---|---|
| committer | Vladimir Stefanovic <vladimir.stefanovic@rt-rk.com> | 2019-01-17 21:50:37 +0000 | 
| commit | 3daf8bc96a121279030e93f4462ff4daa1ffa8e4 (patch) | |
| tree | 7223dfc35cd801163135f03f5d479623c660d2e3 /llvm/lib/Target/Mips | |
| parent | 73b51ae160af6b94d4468331ff3fb6855cff3b18 (diff) | |
| download | bcm5719-llvm-3daf8bc96a121279030e93f4462ff4daa1ffa8e4.tar.gz bcm5719-llvm-3daf8bc96a121279030e93f4462ff4daa1ffa8e4.zip  | |
[mips] Emit .reloc R_{MICRO}MIPS_JALR along with j(al)r(c) $25
The callee address is added as an optional operand (MCSymbol) in
AdjustInstrPostInstrSelection() and then used by asm printer to insert:
'.reloc tmplabel, R_MIPS_JALR, symbol
tmplabel:'.
Controlled with '-mips-jalr-reloc', default is true.
Differential revision: https://reviews.llvm.org/D56694
llvm-svn: 351485
Diffstat (limited to 'llvm/lib/Target/Mips')
| -rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MicroMipsInstrInfo.td | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 41 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsFastISel.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsISelLowering.cpp | 53 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsISelLowering.h | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 12 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsMCInstLower.cpp | 2 | 
13 files changed, 147 insertions, 11 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index d2fed686147..f10d100bfe1 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -65,10 +65,7 @@ class MCInstrInfo;  } // end namespace llvm -static cl::opt<bool> -EmitJalrReloc("mips-jalr-reloc", cl::Hidden, -              cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"), -              cl::init(true)); +extern cl::opt<bool> EmitJalrReloc;  namespace { diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp index 18d7dd99be3..2f2dd4e03c4 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp @@ -15,6 +15,13 @@  using namespace llvm; +// Note: this option is defined here to be visible from libLLVMMipsAsmParser +//       and libLLVMMipsCodeGen +cl::opt<bool> +EmitJalrReloc("mips-jalr-reloc", cl::Hidden, +              cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"), +              cl::init(true)); +  namespace {  static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3}; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h index a90db2384c4..ab8a6753ead 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h @@ -89,7 +89,10 @@ namespace MipsII {      MO_GOT_HI16,      MO_GOT_LO16,      MO_CALL_HI16, -    MO_CALL_LO16 +    MO_CALL_LO16, + +    /// Helper operand used to generate R_MIPS_JALR +    MO_JALR    };    enum { diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index 814918d25e7..c441aa76ad4 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -460,6 +460,7 @@ class JALRC16_MMR6_DESC_BASE<string opstr, RegisterOperand RO>    let isCall = 1;    let hasDelaySlot = 0;    let Defs = [RA]; +  let hasPostISelHook = 1;  }  class JALRC16_MMR6_DESC : JALRC16_MMR6_DESC_BASE<"jalr", GPR32Opnd>; diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td index af380a0ec71..ccc4f04bb92 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td @@ -426,6 +426,7 @@ class JumpLinkRegMM16<string opstr, RegisterOperand RO> :    let isCall = 1;    let hasDelaySlot = 1;    let Defs = [RA]; +  let hasPostISelHook = 1;  }  // 16-bit Jump Reg diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index 2bd0cf2d59a..fb239f572ef 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -1105,7 +1105,7 @@ def : MipsPat<(select i32:$cond, immz, i32:$f),  // Pseudo instructions  let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, -    hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in { +    hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT], hasPostISelHook = 1 in {    class TailCallRegR6<Instruction JumpInst, Register RT, RegisterOperand RO> :      PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,      PseudoInstExpansion<(JumpInst RT:$rt, RO:$rs)>; diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp index 362431fd42a..a7a748b0840 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp @@ -68,6 +68,8 @@ using namespace llvm;  #define DEBUG_TYPE "mips-asm-printer" +extern cl::opt<bool> EmitJalrReloc; +  MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const {    return static_cast<MipsTargetStreamer &>(*OutStreamer->getTargetStreamer());  } @@ -148,6 +150,40 @@ void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,    EmitToStreamer(OutStreamer, TmpInst0);  } +// If there is an MO_JALR operand, insert: +// +// .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol +// tmplabel: +// +// This is an optimization hint for the linker which may then replace +// an indirect call with a direct branch. +static void emitDirectiveRelocJalr(const MachineInstr &MI, +                                   MCContext &OutContext, +                                   TargetMachine &TM, +                                   MCStreamer &OutStreamer, +                                   const MipsSubtarget &Subtarget) { +  for (unsigned int I = MI.getDesc().getNumOperands(), E = MI.getNumOperands(); +       I < E; ++I) { +    MachineOperand MO = MI.getOperand(I); +    if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) { +      MCSymbol *Callee = MO.getMCSymbol(); +      if (Callee && !Callee->getName().empty()) { +        MCSymbol *OffsetLabel = OutContext.createTempSymbol(); +        const MCExpr *OffsetExpr = +            MCSymbolRefExpr::create(OffsetLabel, OutContext); +        const MCExpr *CaleeExpr = +            MCSymbolRefExpr::create(Callee, OutContext); +        OutStreamer.EmitRelocDirective +            (*OffsetExpr, +             Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR", +             CaleeExpr, SMLoc(), *TM.getMCSubtargetInfo()); +        OutStreamer.EmitLabel(OffsetLabel); +        return; +      } +    } +  } +} +  void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {    MipsTargetStreamer &TS = getTargetStreamer();    unsigned Opc = MI->getOpcode(); @@ -207,6 +243,11 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {      return;    } +  if (EmitJalrReloc && +      (MI->isReturn() || MI->isCall() || MI->isIndirectBranch())) { +    emitDirectiveRelocJalr(*MI, OutContext, TM, *OutStreamer, *Subtarget); +  } +    MachineBasicBlock::const_instr_iterator I = MI->getIterator();    MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); diff --git a/llvm/lib/Target/Mips/MipsFastISel.cpp b/llvm/lib/Target/Mips/MipsFastISel.cpp index 22ade31a72c..a18416b9e86 100644 --- a/llvm/lib/Target/Mips/MipsFastISel.cpp +++ b/llvm/lib/Target/Mips/MipsFastISel.cpp @@ -56,6 +56,7 @@  #include "llvm/IR/Type.h"  #include "llvm/IR/User.h"  #include "llvm/IR/Value.h" +#include "llvm/MC/MCContext.h"  #include "llvm/MC/MCInstrDesc.h"  #include "llvm/MC/MCRegisterInfo.h"  #include "llvm/MC/MCSymbol.h" @@ -75,6 +76,8 @@  using namespace llvm; +extern cl::opt<bool> EmitJalrReloc; +  namespace {  class MipsFastISel final : public FastISel { @@ -1551,6 +1554,16 @@ bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {    CLI.Call = MIB; +  if (EmitJalrReloc && !Subtarget->inMips16Mode()) { +    // Attach callee address to the instruction, let asm printer emit +    // .reloc R_MIPS_JALR. +    if (Symbol) +      MIB.addSym(Symbol, MipsII::MO_JALR); +    else +      MIB.addSym(FuncInfo.MF->getContext().getOrCreateSymbol( +	                   Addr.getGlobalValue()->getName()), MipsII::MO_JALR); +  } +    // Finish off the call including any return values.    return finishCall(CLI, RetVT, NumBytes);  } diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index 8c2a364cdfa..0f9c075ba0c 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -57,6 +57,7 @@  #include "llvm/IR/GlobalValue.h"  #include "llvm/IR/Type.h"  #include "llvm/IR/Value.h" +#include "llvm/MC/MCContext.h"  #include "llvm/MC/MCRegisterInfo.h"  #include "llvm/Support/Casting.h"  #include "llvm/Support/CodeGen.h" @@ -91,6 +92,8 @@ NoZeroDivCheck("mno-check-zero-division", cl::Hidden,                 cl::desc("MIPS: Don't trap on integer division by zero."),                 cl::init(false)); +extern cl::opt<bool> EmitJalrReloc; +  static const MCPhysReg Mips64DPRegs[8] = {    Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,    Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64 @@ -2879,6 +2882,54 @@ getOpndList(SmallVectorImpl<SDValue> &Ops,      Ops.push_back(InFlag);  } +void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI, +                                                       SDNode *Node) const { +  switch (MI.getOpcode()) { +    default: +      return; +    case Mips::JALR: +    case Mips::JALRPseudo: +    case Mips::JALR64: +    case Mips::JALR64Pseudo: +    case Mips::JALR16_MM: +    case Mips::JALRC16_MMR6: +    case Mips::TAILCALLREG: +    case Mips::TAILCALLREG64: +    case Mips::TAILCALLR6REG: +    case Mips::TAILCALL64R6REG: +    case Mips::TAILCALLREG_MM: +    case Mips::TAILCALLREG_MMR6: { +      if (!EmitJalrReloc || +          Subtarget.inMips16Mode() || +          !isPositionIndependent() || +          Node->getNumOperands() < 1 || +          Node->getOperand(0).getNumOperands() < 2) { +        return; +      } +      // We are after the callee address, set by LowerCall(). +      // If added to MI, asm printer will emit .reloc R_MIPS_JALR for the +      // symbol. +      const SDValue TargetAddr = Node->getOperand(0).getOperand(1); +      StringRef Sym; +      if (const GlobalAddressSDNode *G = +              dyn_cast_or_null<const GlobalAddressSDNode>(TargetAddr)) { +        Sym = G->getGlobal()->getName(); +      } +      else if (const ExternalSymbolSDNode *ES = +                   dyn_cast_or_null<const ExternalSymbolSDNode>(TargetAddr)) { +        Sym = ES->getSymbol(); +      } + +      if (Sym.empty()) +        return; + +      MachineFunction *MF = MI.getParent()->getParent(); +      MCSymbol *S = MF->getContext().getOrCreateSymbol(Sym); +      MI.addOperand(MachineOperand::CreateMCSymbol(S, MipsII::MO_JALR)); +    } +  } +} +  /// LowerCall - functions arguments are copied from virtual regs to  /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.  SDValue @@ -2930,7 +2981,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,    // the maximum out going argument area (including the reserved area), and    // preallocates the stack space on entrance to the caller.    // -  // FIXME: We should do the same for efficency and space. +  // FIXME: We should do the same for efficiency and space.    // Note: The check on the calling convention below must match    //       MipsABIInfo::GetCalleeAllocdArgSizeInBytes(). diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h index e043f133a09..c88633be02b 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.h +++ b/llvm/lib/Target/Mips/MipsISelLowering.h @@ -341,6 +341,9 @@ class TargetRegisterClass;      EmitInstrWithCustomInserter(MachineInstr &MI,                                  MachineBasicBlock *MBB) const override; +    void AdjustInstrPostInstrSelection(MachineInstr &MI, +                                       SDNode *Node) const override; +      void HandleByVal(CCState *, unsigned &, unsigned) const override;      unsigned getRegisterByName(const char* RegName, EVT VT, diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp index bfb4c775205..e38bef4663a 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp @@ -653,6 +653,16 @@ MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc,      MIB.addImm(0); +    // If I has an MCSymbol operand (used by asm printer, to emit R_MIPS_JALR), +    // add it to the new instruction. +    for (unsigned J = I->getDesc().getNumOperands(), E = I->getNumOperands(); +         J < E; ++J) { +      const MachineOperand &MO = I->getOperand(J); +      if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) +        MIB.addSym(MO.getMCSymbol(), MipsII::MO_JALR); +    } + +    } else {      for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) {        if (BranchWithZeroOperand && (unsigned)ZeroOperandPosition == J) @@ -825,7 +835,8 @@ MipsInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {      {MO_GOT_HI16,     "mips-got-hi16"},      {MO_GOT_LO16,     "mips-got-lo16"},      {MO_CALL_HI16,    "mips-call-hi16"}, -    {MO_CALL_LO16,    "mips-call-lo16"} +    {MO_CALL_LO16,    "mips-call-lo16"}, +    {MO_JALR,         "mips-jalr"}    };    return makeArrayRef(Flags);  } diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index d9398b7d602..46721e6cb9e 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -1623,11 +1623,15 @@ let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {    class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,                            Register RetReg, RegisterOperand ResRO = RO>:      PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>, -    PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>; +    PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)> { +    let hasPostISelHook = 1; +  }    class JumpLinkReg<string opstr, RegisterOperand RO>:      InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), -           [], II_JALR, FrmR, opstr>; +           [], II_JALR, FrmR, opstr> { +    let hasPostISelHook = 1; +  }    class BGEZAL_FT<string opstr, DAGOperand opnd,                    RegisterOperand RO> : @@ -1646,7 +1650,9 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,    class TailCallReg<Instruction JumpInst, RegisterOperand RO> :      PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>, -    PseudoInstExpansion<(JumpInst RO:$rs)>; +    PseudoInstExpansion<(JumpInst RO:$rs)> { +    let hasPostISelHook = 1; +  }  }  class BAL_BR_Pseudo<Instruction RealInst, DAGOperand opnd> : diff --git a/llvm/lib/Target/Mips/MipsMCInstLower.cpp b/llvm/lib/Target/Mips/MipsMCInstLower.cpp index 46b37ceae39..4a7c0ce2be1 100644 --- a/llvm/lib/Target/Mips/MipsMCInstLower.cpp +++ b/llvm/lib/Target/Mips/MipsMCInstLower.cpp @@ -117,6 +117,8 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,    case MipsII::MO_CALL_LO16:      TargetKind = MipsMCExpr::MEK_CALL_LO16;      break; +  case MipsII::MO_JALR: +    return MCOperand();    }    switch (MOTy) {  | 

