diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -102,16 +102,45 @@ return *RM; } +static bool HasReferenceTypes(StringRef FS) { + bool ReferenceTypes = false; + SmallVector Features; + + FS.split(Features, ',', -1, false /* KeepEmpty */); + for (auto &Feature : Features) { + if (Feature == "reference-types" || Feature == "+reference-types") + ReferenceTypes = true; + if (Feature == "-reference-types") + ReferenceTypes = false; + } + + return ReferenceTypes; +} + +static std::string computeDataLayout(const Triple &TT, StringRef FS) { + std::string Ret = "e-m:e"; + + if (TT.isArch64Bit()) { + Ret += "-p:64:64"; + } else { + Ret += "-p:32:32"; + } + + Ret += "-i64:64-n32:64-S128"; + + if (HasReferenceTypes(FS)) { + Ret += "-ni:256"; // anyref + } + return Ret; +} + /// Create an WebAssembly architecture model. /// WebAssemblyTargetMachine::WebAssemblyTargetMachine( const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional RM, Optional CM, CodeGenOpt::Level OL, bool JIT) - : LLVMTargetMachine(T, - TT.isArch64Bit() - ? "e-m:e-p:64:64-i64:64-n32:64-S128-ni:256" - : "e-m:e-p:32:32-i64:64-n32:64-S128-ni:256", + : LLVMTargetMachine(T, computeDataLayout(TT, FS), TT, CPU, FS, Options, getEffectiveRelocModel(RM, TT), getEffectiveCodeModel(CM, CodeModel::Large), OL), TLOF(new WebAssemblyTargetObjectFile()) {