diff options
| author | Petar Avramovic <Petar.Avramovic@rt-rk.com> | 2019-05-31 08:27:06 +0000 |
|---|---|---|
| committer | Petar Avramovic <Petar.Avramovic@rt-rk.com> | 2019-05-31 08:27:06 +0000 |
| commit | efcd3c000991ba9e98428810b7dffecbd8848f57 (patch) | |
| tree | a3bbeb07ec54ef18e7e119030f553d776a63cf82 /llvm/lib/Target/Mips | |
| parent | d1d915b8da91e3e527706c838e2cb4b338336e7a (diff) | |
| download | bcm5719-llvm-efcd3c000991ba9e98428810b7dffecbd8848f57.tar.gz bcm5719-llvm-efcd3c000991ba9e98428810b7dffecbd8848f57.zip | |
[MIPS GlobalISel] Handle position independent code
Handle position independent code for MIPS32.
When callee is global address, lower call will emit callee
as G_GLOBAL_VALUE and add target flag if needed.
Support $gp in getRegBankFromRegClass().
Select G_GLOBAL_VALUE, specially handle case when
there are target flags attached by lowerCall.
Differential Revision: https://reviews.llvm.org/D62589
llvm-svn: 362210
Diffstat (limited to 'llvm/lib/Target/Mips')
| -rw-r--r-- | llvm/lib/Target/Mips/MipsCallLowering.cpp | 23 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstructionSelector.cpp | 65 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsMachineFunction.cpp | 8 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsMachineFunction.h | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp | 1 |
5 files changed, 79 insertions, 19 deletions
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp index 04aff60b2f2..50fb986e5d8 100644 --- a/llvm/lib/Target/Mips/MipsCallLowering.cpp +++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp @@ -14,6 +14,7 @@ #include "MipsCallLowering.h" #include "MipsCCState.h" +#include "MipsMachineFunction.h" #include "MipsTargetMachine.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" @@ -522,10 +523,22 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, MachineInstrBuilder CallSeqStart = MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN); + const bool IsCalleeGlobalPIC = + Callee.isGlobal() && TM.isPositionIndependent(); + MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert( - Callee.isReg() ? Mips::JALRPseudo : Mips::JAL); + Callee.isReg() || IsCalleeGlobalPIC ? Mips::JALRPseudo : Mips::JAL); MIB.addDef(Mips::SP, RegState::Implicit); - MIB.add(Callee); + if (IsCalleeGlobalPIC) { + unsigned CalleeReg = + MF.getRegInfo().createGenericVirtualRegister(LLT::pointer(0, 32)); + MachineInstr *CalleeGlobalValue = + MIRBuilder.buildGlobalValue(CalleeReg, Callee.getGlobal()); + if (!Callee.getGlobal()->hasLocalLinkage()) + CalleeGlobalValue->getOperand(1).setTargetFlags(MipsII::MO_GOT_CALL); + MIB.addUse(CalleeReg); + } else + MIB.add(Callee); const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); MIB.addRegMask(TRI->getCallPreservedMask(MF, F.getCallingConv())); @@ -568,6 +581,12 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, NextStackOffset = alignTo(NextStackOffset, StackAlignment); CallSeqStart.addImm(NextStackOffset).addImm(0); + if (IsCalleeGlobalPIC) { + MIRBuilder.buildCopy( + Mips::GP, + MF.getInfo<MipsFunctionInfo>()->getGlobalBaseRegForGlobalISel()); + MIB.addDef(Mips::GP, RegState::Implicit); + } MIRBuilder.insertInstr(MIB); if (MIB->getOpcode() == Mips::JALRPseudo) { const MipsSubtarget &STI = diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp index a03e7ef57b7..442244af609 100644 --- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp +++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp @@ -11,6 +11,7 @@ /// \todo This should be generated by TableGen. //===----------------------------------------------------------------------===// +#include "MipsMachineFunction.h" #include "MipsRegisterBankInfo.h" #include "MipsTargetMachine.h" #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" @@ -356,29 +357,59 @@ bool MipsInstructionSelector::select(MachineInstr &I, return true; } case G_GLOBAL_VALUE: { - if (MF.getTarget().isPositionIndependent()) - return false; - const llvm::GlobalValue *GVal = I.getOperand(1).getGlobal(); - unsigned LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass); - MachineInstr *LUi, *ADDiu; + if (MF.getTarget().isPositionIndependent()) { + MachineInstr *LWGOT = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW)) + .addDef(I.getOperand(0).getReg()) + .addReg(MF.getInfo<MipsFunctionInfo>() + ->getGlobalBaseRegForGlobalISel()) + .addGlobalAddress(GVal); + // Global Values that don't have local linkage are handled differently + // when they are part of call sequence. MipsCallLowering::lowerCall + // creates G_GLOBAL_VALUE instruction as part of call sequence and adds + // MO_GOT_CALL flag when Callee doesn't have local linkage. + if (I.getOperand(1).getTargetFlags() == MipsII::MO_GOT_CALL) + LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT_CALL); + else + LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT); + LWGOT->addMemOperand( + MF, MF.getMachineMemOperand(MachinePointerInfo::getGOT(MF), + MachineMemOperand::MOLoad, 4, 4)); + if (!constrainSelectedInstRegOperands(*LWGOT, TII, TRI, RBI)) + return false; - LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi)) - .addDef(LUiReg) - .addGlobalAddress(GVal); - LUi->getOperand(1).setTargetFlags(MipsII::MO_ABS_HI); + if (GVal->hasLocalLinkage()) { + unsigned LWGOTDef = MRI.createVirtualRegister(&Mips::GPR32RegClass); + LWGOT->getOperand(0).setReg(LWGOTDef); - ADDiu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu)) + MachineInstr *ADDiu = + BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu)) .addDef(I.getOperand(0).getReg()) - .addUse(LUiReg) + .addReg(LWGOTDef) .addGlobalAddress(GVal); - ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO); - - if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI)) - return false; - if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI)) - return false; + ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO); + if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI)) + return false; + } + } else { + unsigned LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass); + + MachineInstr *LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi)) + .addDef(LUiReg) + .addGlobalAddress(GVal); + LUi->getOperand(1).setTargetFlags(MipsII::MO_ABS_HI); + if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI)) + return false; + MachineInstr *ADDiu = + BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu)) + .addDef(I.getOperand(0).getReg()) + .addUse(LUiReg) + .addGlobalAddress(GVal); + ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO); + if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI)) + return false; + } I.eraseFromParent(); return true; } diff --git a/llvm/lib/Target/Mips/MipsMachineFunction.cpp b/llvm/lib/Target/Mips/MipsMachineFunction.cpp index 57749054b5f..d489fac937e 100644 --- a/llvm/lib/Target/Mips/MipsMachineFunction.cpp +++ b/llvm/lib/Target/Mips/MipsMachineFunction.cpp @@ -51,6 +51,14 @@ unsigned MipsFunctionInfo::getGlobalBaseReg() { return GlobalBaseReg; } +unsigned MipsFunctionInfo::getGlobalBaseRegForGlobalISel() { + if (!GlobalBaseReg) { + getGlobalBaseReg(); + initGlobalBaseReg(); + } + return GlobalBaseReg; +} + void MipsFunctionInfo::initGlobalBaseReg() { if (!GlobalBaseReg) return; diff --git a/llvm/lib/Target/Mips/MipsMachineFunction.h b/llvm/lib/Target/Mips/MipsMachineFunction.h index b2c6c8d4f33..d9d53c8d631 100644 --- a/llvm/lib/Target/Mips/MipsMachineFunction.h +++ b/llvm/lib/Target/Mips/MipsMachineFunction.h @@ -33,6 +33,7 @@ public: bool globalBaseRegSet() const; unsigned getGlobalBaseReg(); + unsigned getGlobalBaseRegForGlobalISel(); // Insert instructions to initialize the global base register in the // first MBB of the function. diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp index 1192db7e1a1..4814ef4b039 100644 --- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp +++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp @@ -79,6 +79,7 @@ const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass( case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID: case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID: case Mips::SP32RegClassID: + case Mips::GP32RegClassID: return getRegBank(Mips::GPRBRegBankID); case Mips::FGRCCRegClassID: case Mips::FGR32RegClassID: |

