1
0
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:
Sam Clegg 2020-11-12 21:43:57 -08:00
parent 4f4c287383
commit 372af5a9de
3 changed files with 51 additions and 39 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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]>;