/// Create an WebAssembly architecture model. /// WebAssemblyTargetMachine::WebAssemblyTargetMachine( const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT) : LLVMTargetMachine(T, TT.isArch64Bit() ? "e-m:e-p:64:64-i64:64-n32:64-S128" : "e-m:e-p:32:32-i64:64-n32:64-S128", TT, CPU, FS, Options, getEffectiveRelocModel(RM), CM ? *CM : CodeModel::Large, OL), TLOF(TT.isOSBinFormatELF() ? static_cast<TargetLoweringObjectFile*>( new WebAssemblyTargetObjectFileELF()) : static_cast<TargetLoweringObjectFile*>( new WebAssemblyTargetObjectFile())) { // 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 // 'unreachable' instructions which is meant for that case. this->Options.TrapUnreachable = true; // WebAssembly treats each function as an independent unit. Force // -ffunction-sections, effectively, so that we can emit them independently. if (!TT.isOSBinFormatELF()) { this->Options.FunctionSections = true; this->Options.DataSections = true; this->Options.UniqueSectionNames = true; } initAsmInfo(); // Note that we don't use setRequiresStructuredCFG(true). It disables // optimizations than we're ok with, and want, such as critical edge // splitting and tail merging. }
static Reloc::Model getEffectiveRelocModel(const Triple &TT, Optional<Reloc::Model> RM) { if (!RM.hasValue()) // Default relocation model on Darwin is PIC. return TT.isOSBinFormatMachO() ? Reloc::PIC_ : Reloc::Static; if (*RM == Reloc::ROPI || *RM == Reloc::RWPI || *RM == Reloc::ROPI_RWPI) assert(TT.isOSBinFormatELF() && "ROPI/RWPI currently only supported for ELF"); // DynamicNoPIC is only used on darwin. if (*RM == Reloc::DynamicNoPIC && !TT.isOSDarwin()) return Reloc::Static; return *RM; }
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) { if (TT.isOSBinFormatMachO()) { if (TT.getArch() == Triple::x86_64) return make_unique<X86_64MachoTargetObjectFile>(); return make_unique<TargetLoweringObjectFileMachO>(); } if (TT.isOSLinux() || TT.isOSNaCl()) return make_unique<X86LinuxNaClTargetObjectFile>(); if (TT.isOSBinFormatELF()) return make_unique<X86ELFTargetObjectFile>(); if (TT.isKnownWindowsMSVCEnvironment() || TT.isWindowsCoreCLREnvironment()) return make_unique<X86WindowsTargetObjectFile>(); if (TT.isOSBinFormatCOFF()) return make_unique<TargetLoweringObjectFileCOFF>(); llvm_unreachable("unknown subtarget type"); }
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) { if (TT.isOSBinFormatMachO()) { if (TT.getArch() == Triple::x86_64) return llvm::make_unique<X86_64MachoTargetObjectFile>(); return llvm::make_unique<TargetLoweringObjectFileMachO>(); } if (TT.isOSFreeBSD()) return llvm::make_unique<X86FreeBSDTargetObjectFile>(); if (TT.isOSLinux() || TT.isOSNaCl() || TT.isOSIAMCU()) return llvm::make_unique<X86LinuxNaClTargetObjectFile>(); if (TT.isOSSolaris()) return llvm::make_unique<X86SolarisTargetObjectFile>(); if (TT.isOSFuchsia()) return llvm::make_unique<X86FuchsiaTargetObjectFile>(); if (TT.isOSBinFormatELF()) return llvm::make_unique<X86ELFTargetObjectFile>(); if (TT.isOSBinFormatCOFF()) return llvm::make_unique<TargetLoweringObjectFileCOFF>(); llvm_unreachable("unknown subtarget type"); }