From a083b28a31d1e1bbb2d4601dbbc6f314dea8a0e7 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 12 Nov 2020 21:43:57 -0800 Subject: [PATCH] [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 --- .../Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp | 39 ------------------ .../Target/WebAssembly/WebAssemblyISelLowering.cpp | 46 ++++++++++++++++++++++ .../lib/Target/WebAssembly/WebAssemblyInstrInfo.td | 5 +++ 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp index e838a74..b9154b0 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp @@ -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(Node); - - if (!MF.getSubtarget().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(Node->getOperand(0))->getZExtValue(); switch (IntNo) { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 778f213..5713499 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -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(Op); + MVT PtrVT = getPointerTy(DAG.getDataLayout()); + + MachineFunction &MF = DAG.getMachineFunction(); + if (!MF.getSubtarget().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); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td index b57d6fd..5f421e2 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td @@ -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]>; -- 2.7.4