mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
[WebAssembly] Move GlobalTLSAddress handling to WebAssemblyISelLowering. NFC
I'm not why it was added to DAGToDAG oringally but it seems to make sense alongside the non-TLS version: LowerGlobalAddress Differential Revision: https://reviews.llvm.org/D91432
This commit is contained in:
parent
4f4c287383
commit
372af5a9de
@ -80,9 +80,6 @@ void WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
|
||||
MVT PtrVT = TLI->getPointerTy(CurDAG->getDataLayout());
|
||||
auto GlobalGetIns = PtrVT == MVT::i64 ? WebAssembly::GLOBAL_GET_I64
|
||||
: WebAssembly::GLOBAL_GET_I32;
|
||||
auto ConstIns =
|
||||
PtrVT == MVT::i64 ? WebAssembly::CONST_I64 : WebAssembly::CONST_I32;
|
||||
auto AddIns = PtrVT == MVT::i64 ? WebAssembly::ADD_I64 : WebAssembly::ADD_I32;
|
||||
|
||||
// Few custom selection stuff.
|
||||
SDLoc DL(Node);
|
||||
@ -126,42 +123,6 @@ void WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::GlobalTLSAddress: {
|
||||
const auto *GA = cast<GlobalAddressSDNode>(Node);
|
||||
|
||||
if (!MF.getSubtarget<WebAssemblySubtarget>().hasBulkMemory())
|
||||
report_fatal_error("cannot use thread-local storage without bulk memory",
|
||||
false);
|
||||
|
||||
// Currently Emscripten does not support dynamic linking with threads.
|
||||
// Therefore, if we have thread-local storage, only the local-exec model
|
||||
// is possible.
|
||||
// TODO: remove this and implement proper TLS models once Emscripten
|
||||
// supports dynamic linking with threads.
|
||||
if (GA->getGlobal()->getThreadLocalMode() !=
|
||||
GlobalValue::LocalExecTLSModel &&
|
||||
!Subtarget->getTargetTriple().isOSEmscripten()) {
|
||||
report_fatal_error("only -ftls-model=local-exec is supported for now on "
|
||||
"non-Emscripten OSes: variable " +
|
||||
GA->getGlobal()->getName(),
|
||||
false);
|
||||
}
|
||||
|
||||
SDValue TLSBaseSym = CurDAG->getTargetExternalSymbol("__tls_base", PtrVT);
|
||||
SDValue TLSOffsetSym = CurDAG->getTargetGlobalAddress(
|
||||
GA->getGlobal(), DL, PtrVT, GA->getOffset(),
|
||||
WebAssemblyII::MO_TLS_BASE_REL);
|
||||
|
||||
MachineSDNode *TLSBase =
|
||||
CurDAG->getMachineNode(GlobalGetIns, DL, PtrVT, TLSBaseSym);
|
||||
MachineSDNode *TLSOffset =
|
||||
CurDAG->getMachineNode(ConstIns, DL, PtrVT, TLSOffsetSym);
|
||||
MachineSDNode *TLSAddress = CurDAG->getMachineNode(
|
||||
AddIns, DL, PtrVT, SDValue(TLSBase, 0), SDValue(TLSOffset, 0));
|
||||
ReplaceNode(Node, TLSAddress);
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::INTRINSIC_WO_CHAIN: {
|
||||
unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue();
|
||||
switch (IntNo) {
|
||||
|
@ -69,6 +69,7 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
|
||||
computeRegisterProperties(Subtarget->getRegisterInfo());
|
||||
|
||||
setOperationAction(ISD::GlobalAddress, MVTPtr, Custom);
|
||||
setOperationAction(ISD::GlobalTLSAddress, MVTPtr, Custom);
|
||||
setOperationAction(ISD::ExternalSymbol, MVTPtr, Custom);
|
||||
setOperationAction(ISD::JumpTable, MVTPtr, Custom);
|
||||
setOperationAction(ISD::BlockAddress, MVTPtr, Custom);
|
||||
@ -1170,6 +1171,8 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
|
||||
return LowerFrameIndex(Op, DAG);
|
||||
case ISD::GlobalAddress:
|
||||
return LowerGlobalAddress(Op, DAG);
|
||||
case ISD::GlobalTLSAddress:
|
||||
return LowerGlobalTLSAddress(Op, DAG);
|
||||
case ISD::ExternalSymbol:
|
||||
return LowerExternalSymbol(Op, DAG);
|
||||
case ISD::JumpTable:
|
||||
@ -1278,6 +1281,49 @@ SDValue WebAssemblyTargetLowering::LowerFRAMEADDR(SDValue Op,
|
||||
return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), FP, VT);
|
||||
}
|
||||
|
||||
SDValue
|
||||
WebAssemblyTargetLowering::LowerGlobalTLSAddress(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
const auto *GA = cast<GlobalAddressSDNode>(Op);
|
||||
MVT PtrVT = getPointerTy(DAG.getDataLayout());
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
if (!MF.getSubtarget<WebAssemblySubtarget>().hasBulkMemory())
|
||||
report_fatal_error("cannot use thread-local storage without bulk memory",
|
||||
false);
|
||||
|
||||
const GlobalValue *GV = GA->getGlobal();
|
||||
|
||||
// Currently Emscripten does not support dynamic linking with threads.
|
||||
// Therefore, if we have thread-local storage, only the local-exec model
|
||||
// is possible.
|
||||
// TODO: remove this and implement proper TLS models once Emscripten
|
||||
// supports dynamic linking with threads.
|
||||
if (GV->getThreadLocalMode() != GlobalValue::LocalExecTLSModel &&
|
||||
!Subtarget->getTargetTriple().isOSEmscripten()) {
|
||||
report_fatal_error("only -ftls-model=local-exec is supported for now on "
|
||||
"non-Emscripten OSes: variable " +
|
||||
GV->getName(),
|
||||
false);
|
||||
}
|
||||
|
||||
auto GlobalGet = PtrVT == MVT::i64 ? WebAssembly::GLOBAL_GET_I64
|
||||
: WebAssembly::GLOBAL_GET_I32;
|
||||
const char *BaseName = MF.createExternalSymbolName("__tls_base");
|
||||
|
||||
SDValue BaseAddr(
|
||||
DAG.getMachineNode(GlobalGet, DL, PtrVT,
|
||||
DAG.getTargetExternalSymbol(BaseName, PtrVT)),
|
||||
0);
|
||||
|
||||
SDValue TLSOffset = DAG.getTargetGlobalAddress(
|
||||
GV, DL, PtrVT, GA->getOffset(), WebAssemblyII::MO_TLS_BASE_REL);
|
||||
SDValue SymAddr = DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT, TLSOffset);
|
||||
|
||||
return DAG.getNode(ISD::ADD, DL, PtrVT, BaseAddr, SymAddr);
|
||||
}
|
||||
|
||||
SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
|
@ -352,6 +352,11 @@ def : Pat<(i32 (WebAssemblywrapperPIC tglobaladdr:$addr)),
|
||||
def : Pat<(i64 (WebAssemblywrapperPIC tglobaladdr:$addr)),
|
||||
(CONST_I64 tglobaladdr:$addr)>, Requires<[IsPIC, HasAddr64]>;
|
||||
|
||||
def : Pat<(i32 (WebAssemblywrapper tglobaltlsaddr:$addr)),
|
||||
(CONST_I32 tglobaltlsaddr:$addr)>, Requires<[HasAddr32]>;
|
||||
def : Pat<(i64 (WebAssemblywrapper tglobaltlsaddr:$addr)),
|
||||
(CONST_I64 tglobaltlsaddr:$addr)>, Requires<[HasAddr64]>;
|
||||
|
||||
def : Pat<(i32 (WebAssemblywrapper texternalsym:$addr)),
|
||||
(GLOBAL_GET_I32 texternalsym:$addr)>, Requires<[IsPIC, HasAddr32]>;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user