diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2024-07-27 23:34:35 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2024-12-01 12:32:12 +0000 | 
| commit | fbc266465ed3585efdbd8e9ebf71e97ce7e8b464 (patch) | |
| tree | 7560c2cbec09e542e5f2e2100ffc16ca742b1075 /contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp | |
| parent | ac8517f04c0fe31968ed43e36608ad02d72d3597 (diff) | |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp | 85 | 
1 files changed, 54 insertions, 31 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index 2db1b6493cc4..23539a5f4b26 100644 --- a/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -68,6 +68,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTarget() {    initializeLowerGlobalDtorsLegacyPassPass(PR);    initializeFixFunctionBitcastsPass(PR);    initializeOptimizeReturnedPass(PR); +  initializeWebAssemblyRefTypeMem2LocalPass(PR);    initializeWebAssemblyArgumentMovePass(PR);    initializeWebAssemblySetP2AlignOperandsPass(PR);    initializeWebAssemblyReplacePhysRegsPass(PR); @@ -89,7 +90,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTarget() {    initializeWebAssemblyMCLowerPrePassPass(PR);    initializeWebAssemblyLowerRefTypesIntPtrConvPass(PR);    initializeWebAssemblyFixBrTableDefaultsPass(PR); -  initializeWebAssemblyDAGToDAGISelPass(PR); +  initializeWebAssemblyDAGToDAGISelLegacyPass(PR);  }  //===----------------------------------------------------------------------===// @@ -127,7 +128,8 @@ WebAssemblyTargetMachine::WebAssemblyTargetMachine(                                         "n32:64-S128-ni:1:10:20"),            TT, CPU, FS, Options, getEffectiveRelocModel(RM, TT),            getEffectiveCodeModel(CM, CodeModel::Large), OL), -      TLOF(new WebAssemblyTargetObjectFile()) { +      TLOF(new WebAssemblyTargetObjectFile()), +      UsesMultivalueABI(Options.MCOptions.getABIName() == "experimental-mv") {    // WebAssembly type-checks instructions, but a noreturn function with a return    // type that doesn't match the context will cause a check failure. So we lower    // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's @@ -200,7 +202,8 @@ public:    bool runOnModule(Module &M) override {      FeatureBitset Features = coalesceFeatures(M); -    std::string FeatureStr = getFeatureString(Features); +    std::string FeatureStr = +        getFeatureString(Features, WasmTM->getTargetFeatureString());      WasmTM->setTargetFeatureString(FeatureStr);      for (auto &F : M)        replaceFeatures(F, FeatureStr); @@ -238,12 +241,17 @@ private:      return Features;    } -  std::string getFeatureString(const FeatureBitset &Features) { +  static std::string getFeatureString(const FeatureBitset &Features, +                                      StringRef TargetFS) {      std::string Ret;      for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) {        if (Features[KV.Value])          Ret += (StringRef("+") + KV.Key + ",").str();      } +    SubtargetFeatures TF{TargetFS}; +    for (std::string const &F : TF.getFeatures()) +      if (!SubtargetFeatures::isEnabled(F)) +        Ret += F + ",";      return Ret;    } @@ -284,6 +292,17 @@ private:      bool Stripped = false;      for (auto &GV : M.globals()) {        if (GV.isThreadLocal()) { +        // replace `@llvm.threadlocal.address.pX(GV)` with `GV`. +        for (Use &U : make_early_inc_range(GV.uses())) { +          if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(U.getUser())) { +            if (II->getIntrinsicID() == Intrinsic::threadlocal_address && +                II->getArgOperand(0) == &GV) { +              II->replaceAllUsesWith(&GV); +              II->eraseFromParent(); +            } +          } +        } +          Stripped = true;          GV.setThreadLocal(false);        } @@ -366,18 +385,36 @@ FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {  using WebAssembly::WasmEnableEH;  using WebAssembly::WasmEnableEmEH;  using WebAssembly::WasmEnableEmSjLj; +using WebAssembly::WasmEnableExnref;  using WebAssembly::WasmEnableSjLj;  static void basicCheckForEHAndSjLj(TargetMachine *TM) { -  // Before checking, we make sure TargetOptions.ExceptionModel is the same as + +  // You can't enable two modes of EH at the same time +  if (WasmEnableEmEH && WasmEnableEH) +    report_fatal_error( +        "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-eh"); +  // You can't enable two modes of SjLj at the same time +  if (WasmEnableEmSjLj && WasmEnableSjLj) +    report_fatal_error( +        "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj"); +  // You can't mix Emscripten EH with Wasm SjLj. +  if (WasmEnableEmEH && WasmEnableSjLj) +    report_fatal_error( +        "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-sjlj"); +  if (WasmEnableExnref && !WasmEnableEH) +    report_fatal_error( +        "-wasm-enable-exnref should be used with -wasm-enable-eh"); + +  // Here we make sure TargetOptions.ExceptionModel is the same as    // MCAsmInfo.ExceptionsType. Normally these have to be the same, because clang    // stores the exception model info in LangOptions, which is later transferred    // to TargetOptions and MCAsmInfo. But when clang compiles bitcode directly,    // clang's LangOptions is not used and thus the exception model info is not    // correctly transferred to TargetOptions and MCAsmInfo, so we make sure we -  // have the correct exception model in WebAssemblyMCAsmInfo constructor. -  // But in this case TargetOptions is still not updated, so we make sure they -  // are the same. +  // have the correct exception model in WebAssemblyMCAsmInfo constructor. But +  // in this case TargetOptions is still not updated, so we make sure they are +  // the same.    TM->Options.ExceptionModel = TM->getMCAsmInfo()->getExceptionHandlingType();    // Basic Correctness checking related to -exception-model @@ -397,20 +434,8 @@ static void basicCheckForEHAndSjLj(TargetMachine *TM) {        TM->Options.ExceptionModel == ExceptionHandling::Wasm)      report_fatal_error(          "-exception-model=wasm only allowed with at least one of " -        "-wasm-enable-eh or -wasm-enable-sjj"); +        "-wasm-enable-eh or -wasm-enable-sjlj"); -  // You can't enable two modes of EH at the same time -  if (WasmEnableEmEH && WasmEnableEH) -    report_fatal_error( -        "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-eh"); -  // You can't enable two modes of SjLj at the same time -  if (WasmEnableEmSjLj && WasmEnableSjLj) -    report_fatal_error( -        "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj"); -  // You can't mix Emscripten EH with Wasm SjLj. -  if (WasmEnableEmEH && WasmEnableSjLj) -    report_fatal_error( -        "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-sjlj");    // Currently it is allowed to mix Wasm EH with Emscripten SjLj as an interim    // measure, but some code will error out at compile time in this combination.    // See WebAssemblyLowerEmscriptenEHSjLj pass for details. @@ -465,20 +490,14 @@ void WebAssemblyPassConfig::addIRPasses() {  }  void WebAssemblyPassConfig::addISelPrepare() { -  WebAssemblyTargetMachine *WasmTM = -      static_cast<WebAssemblyTargetMachine *>(TM); -  const WebAssemblySubtarget *Subtarget = -      WasmTM->getSubtargetImpl(std::string(WasmTM->getTargetCPU()), -                               std::string(WasmTM->getTargetFeatureString())); -  if (Subtarget->hasReferenceTypes()) { -    // We need to remove allocas for reference types -    addPass(createPromoteMemoryToRegisterPass(true)); -  } +  // We need to move reference type allocas to WASM_ADDRESS_SPACE_VAR so that +  // loads and stores are promoted to local.gets/local.sets. +  addPass(createWebAssemblyRefTypeMem2Local());    // Lower atomics and TLS if necessary    addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));    // This is a no-op if atomics are not used in the module -  addPass(createAtomicExpandPass()); +  addPass(createAtomicExpandLegacyPass());    TargetPassConfig::addISelPrepare();  } @@ -499,6 +518,10 @@ bool WebAssemblyPassConfig::addInstSelector() {    // Eliminate range checks and add default targets to br_table instructions.    addPass(createWebAssemblyFixBrTableDefaults()); +  // unreachable is terminator, non-terminator instruction after it is not +  // allowed. +  addPass(createWebAssemblyCleanCodeAfterTrap()); +    return false;  }  | 
