From 0f863bdd8506b0d32f55fb635129db09b83b684c Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 26 Apr 2022 16:42:55 -0400 Subject: [PATCH] Explicitly use large code models in AArch64 code gen This appears to be necessary to compile our programs on AArch64 boxes. My guess is special-cased code due to PIEs for large code models in LLVM's codebase but I really have no idea. --- compiler/build/src/link.rs | 5 ++--- compiler/build/src/program.rs | 6 ++---- compiler/build/src/target.rs | 13 +++++++++++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/compiler/build/src/link.rs b/compiler/build/src/link.rs index a7e32d0328..4bf75d24b3 100644 --- a/compiler/build/src/link.rs +++ b/compiler/build/src/link.rs @@ -1072,7 +1072,7 @@ pub fn module_to_dylib( opt_level: OptLevel, ) -> Result { use crate::target::{self, convert_opt_level}; - use inkwell::targets::{CodeModel, FileType, RelocMode}; + use inkwell::targets::{FileType, RelocMode}; let dir = tempfile::tempdir().unwrap(); let filename = PathBuf::from("Test.roc"); @@ -1083,9 +1083,8 @@ pub fn module_to_dylib( // Emit the .o file using position-independent code (PIC) - needed for dylibs let reloc = RelocMode::PIC; - let model = CodeModel::Default; let target_machine = - target::target_machine(target, convert_opt_level(opt_level), reloc, model).unwrap(); + target::target_machine(target, convert_opt_level(opt_level), reloc).unwrap(); target_machine .write_to_file(module, FileType::Object, &app_o_file) diff --git a/compiler/build/src/program.rs b/compiler/build/src/program.rs index 3d8ac5e456..62a965d8aa 100644 --- a/compiler/build/src/program.rs +++ b/compiler/build/src/program.rs @@ -249,7 +249,7 @@ pub fn gen_from_mono_module_llvm( use inkwell::attributes::{Attribute, AttributeLoc}; use inkwell::context::Context; use inkwell::module::Linkage; - use inkwell::targets::{CodeModel, FileType, RelocMode}; + use inkwell::targets::{FileType, RelocMode}; let code_gen_start = SystemTime::now(); @@ -437,10 +437,8 @@ pub fn gen_from_mono_module_llvm( match target.architecture { Architecture::X86_64 | Architecture::X86_32(_) | Architecture::Aarch64(_) => { let reloc = RelocMode::PIC; - let model = CodeModel::Default; let target_machine = - target::target_machine(target, convert_opt_level(opt_level), reloc, model) - .unwrap(); + target::target_machine(target, convert_opt_level(opt_level), reloc).unwrap(); target_machine .write_to_file(env.module, FileType::Object, app_o_file) diff --git a/compiler/build/src/target.rs b/compiler/build/src/target.rs index 6beee37300..096ccbc867 100644 --- a/compiler/build/src/target.rs +++ b/compiler/build/src/target.rs @@ -147,19 +147,28 @@ pub fn target_machine( target: &Triple, opt: OptimizationLevel, reloc: RelocMode, - model: CodeModel, ) -> Option { let arch = arch_str(target); init_arch(target); + let code_model = match target.architecture { + // LLVM 12 will not compile our programs without a large code model. + // The reason is not totally clear to me, but my guess is a few special-cases in + // llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (instructions) + // llvm/lib/Target/AArch64/AArch64Subtarget.cpp (GoT tables) + // Revisit when upgrading to LLVM 13. + Architecture::Aarch64(..) => CodeModel::Large, + _ => CodeModel::Default, + }; + Target::from_name(arch).unwrap().create_target_machine( &TargetTriple::create(target_triple_str(target)), "generic", "", // TODO: this probably should be TargetMachine::get_host_cpu_features() to enable all features. opt, reloc, - model, + code_model, ) }