From 82777a94adc540d479e9536a344b47afdb86612b Mon Sep 17 00:00:00 2001
From: WANG Xuerui <xen0n@gentoo.org>
Date: Mon, 5 Feb 2024 13:18:32 +0800
Subject: [PATCH] target: default to the medium code model on LoongArch targets
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The Rust LoongArch targets have been using the default LLVM code model
so far, which is "small" in LLVM-speak and "normal" in LoongArch-speak.
As described in the "Code Model" section of LoongArch ELF psABI spec
v20231219 [1], one can only make function calls as far as ±128MiB with
the "normal" code model; this is insufficient for very large software
containing Rust components that needs to be linked into the big text
section, such as Chromium.

Because:

* we do not want to ask users to recompile std if they are to build
  such software,
* objects compiled with larger code models can be linked with those
  with smaller code models without problems, and
* the "medium" code model is comparable to the "small"/"normal" one
  performance-wise (same data access pattern; each function call
  becomes 2-insn long and indirect, but this may be relaxed back into
  the direct 1-insn form in a future LLVM version), but is able to
  perform function calls within ±128GiB,

it is better to just switch the targets to the "medium" code model,
which is also "medium" in LLVM-speak.

[1]: https://github.com/loongson/la-abi-specs/blob/v2.30/laelf.adoc#code-models

Co-authored-by: WANG Rui <wangrui@loongson.cn>
---
 .../src/spec/targets/loongarch64_unknown_linux_gnu.rs          | 3 ++-
 .../src/spec/targets/loongarch64_unknown_linux_musl.rs         | 3 ++-
 .../rustc_target/src/spec/targets/loongarch64_unknown_none.rs  | 2 +-
 .../src/spec/targets/loongarch64_unknown_none_softfloat.rs     | 2 +-
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
index d33c7af92c656..0bcbf655bd89e 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, CodeModel, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
     Target {
@@ -13,6 +13,7 @@ pub(crate) fn target() -> Target {
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
         arch: "loongarch64".into(),
         options: TargetOptions {
+            code_model: Some(CodeModel::Medium),
             cpu: "generic".into(),
             features: "+f,+d".into(),
             llvm_abiname: "lp64d".into(),
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
index 5540e71ad4f31..223d979a06fbf 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, CodeModel, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
     Target {
@@ -13,6 +13,7 @@ pub(crate) fn target() -> Target {
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
         arch: "loongarch64".into(),
         options: TargetOptions {
+            code_model: Some(CodeModel::Medium),
             cpu: "generic".into(),
             features: "+f,+d".into(),
             llvm_abiname: "lp64d".into(),
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs
index 5628519026831..db527c8b63697 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs
@@ -23,7 +23,7 @@ pub(crate) fn target() -> Target {
             max_atomic_width: Some(64),
             relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
-            code_model: Some(CodeModel::Small),
+            code_model: Some(CodeModel::Medium),
             ..Default::default()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs
index 7e57715ce7a73..221ca02fe3e3b 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs
@@ -24,7 +24,7 @@ pub(crate) fn target() -> Target {
             max_atomic_width: Some(64),
             relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
-            code_model: Some(CodeModel::Small),
+            code_model: Some(CodeModel::Medium),
             ..Default::default()
         },
     }