diff options
| author | Konstantin Zhuravlyov <kzhuravl_dev@outlook.com> | 2016-10-14 04:37:34 +0000 |
|---|---|---|
| committer | Konstantin Zhuravlyov <kzhuravl_dev@outlook.com> | 2016-10-14 04:37:34 +0000 |
| commit | c96b5d7073217d378510379e1f1077fca62d2075 (patch) | |
| tree | a6b684f8a45f4c423d33366f386e394ebf981e80 /llvm/lib/Target/AMDGPU/SIISelLowering.cpp | |
| parent | 2a2ac37c2ce05fa56a4ee523a418cc58c5bdc0d3 (diff) | |
| download | bcm5719-llvm-c96b5d7073217d378510379e1f1077fca62d2075.tar.gz bcm5719-llvm-c96b5d7073217d378510379e1f1077fca62d2075.zip | |
[AMDGPU] Emit 32-bit lo/hi got and pc relative variant kinds for external and global address space variables
Differential Revision: https://reviews.llvm.org/D25562
llvm-svn: 284196
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIISelLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 7decb8f1c7f..0df5ea075a6 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -1979,12 +1979,24 @@ SDValue SITargetLowering::lowerADDRSPACECAST(SDValue Op, return DAG.getUNDEF(ASC->getValueType(0)); } +static bool shouldEmitFixup(const GlobalValue *GV, + const TargetMachine &TM) { + // FIXME: We need to emit global variables in constant address space in a + // separate section, and use relocations. + return GV->getType()->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS; +} + static bool shouldEmitGOTReloc(const GlobalValue *GV, const TargetMachine &TM) { return GV->getType()->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS && !TM.shouldAssumeDSOLocal(*GV->getParent(), GV); } +static bool shouldEmitPCReloc(const GlobalValue *GV, + const TargetMachine &TM) { + return !shouldEmitFixup(GV, TM) && !shouldEmitGOTReloc(GV, TM); +} + bool SITargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { // We can fold offsets for anything that doesn't require a GOT relocation. @@ -1997,14 +2009,27 @@ static SDValue buildPCRelGlobalAddress(SelectionDAG &DAG, const GlobalValue *GV, unsigned GAFlags = SIInstrInfo::MO_NONE) { // In order to support pc-relative addressing, the PC_ADD_REL_OFFSET SDNode is // lowered to the following code sequence: - // s_getpc_b64 s[0:1] - // s_add_u32 s0, s0, $symbol - // s_addc_u32 s1, s1, 0 // - // s_getpc_b64 returns the address of the s_add_u32 instruction and then - // a fixup or relocation is emitted to replace $symbol with a literal - // constant, which is a pc-relative offset from the encoding of the $symbol - // operand to the global variable. + // For constant address space: + // s_getpc_b64 s[0:1] + // s_add_u32 s0, s0, $symbol + // s_addc_u32 s1, s1, 0 + // + // s_getpc_b64 returns the address of the s_add_u32 instruction and then + // a fixup or relocation is emitted to replace $symbol with a literal + // constant, which is a pc-relative offset from the encoding of the $symbol + // operand to the global variable. + // + // For global address space: + // s_getpc_b64 s[0:1] + // s_add_u32 s0, s0, $symbol@{gotpc}rel32@lo + // s_addc_u32 s1, s1, $symbol@{gotpc}rel32@hi + // + // s_getpc_b64 returns the address of the s_add_u32 instruction and then + // fixups or relocations are emitted to replace $symbol@*@lo and + // $symbol@*@hi with lower 32 bits and higher 32 bits of a literal constant, + // which is a 64-bit pc-relative offset from the encoding of the $symbol + // operand to the global variable. // // What we want here is an offset from the value returned by s_getpc // (which is the address of the s_add_u32 instruction) to the global @@ -2012,9 +2037,12 @@ static SDValue buildPCRelGlobalAddress(SelectionDAG &DAG, const GlobalValue *GV, // of the s_add_u32 instruction, we end up with an offset that is 4 bytes too // small. This requires us to add 4 to the global variable offset in order to // compute the correct address. - SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, Offset + 4, - GAFlags); - return DAG.getNode(AMDGPUISD::PC_ADD_REL_OFFSET, DL, PtrVT, GA); + SDValue PtrLo = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, Offset + 4, + GAFlags); + SDValue PtrHi = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, Offset + 4, + GAFlags == SIInstrInfo::MO_NONE ? + GAFlags : GAFlags + 1); + return DAG.getNode(AMDGPUISD::PC_ADD_REL_OFFSET, DL, PtrVT, PtrLo, PtrHi); } SDValue SITargetLowering::LowerGlobalAddress(AMDGPUMachineFunction *MFI, @@ -2030,11 +2058,14 @@ SDValue SITargetLowering::LowerGlobalAddress(AMDGPUMachineFunction *MFI, const GlobalValue *GV = GSD->getGlobal(); EVT PtrVT = Op.getValueType(); - if (!shouldEmitGOTReloc(GV, getTargetMachine())) + if (shouldEmitFixup(GV, getTargetMachine())) return buildPCRelGlobalAddress(DAG, GV, DL, GSD->getOffset(), PtrVT); + else if (shouldEmitPCReloc(GV, getTargetMachine())) + return buildPCRelGlobalAddress(DAG, GV, DL, GSD->getOffset(), PtrVT, + SIInstrInfo::MO_REL32); SDValue GOTAddr = buildPCRelGlobalAddress(DAG, GV, DL, 0, PtrVT, - SIInstrInfo::MO_GOTPCREL); + SIInstrInfo::MO_GOTPCREL32); Type *Ty = PtrVT.getTypeForEVT(*DAG.getContext()); PointerType *PtrTy = PointerType::get(Ty, AMDGPUAS::CONSTANT_ADDRESS); |

