mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 06:35:27 +00:00
Merge commit '09fae60a86b848a2fc0ad219ecc4e438dc1eef86' into sync_cg_clif-2024-03-28
This commit is contained in:
commit
987ed345af
@ -46,18 +46,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9515fcc42b6cb5137f76b84c1a6f819782d0cf12473d145d3bc5cd67eedc8bc2"
|
||||
checksum = "6a535eb1cf5a6003197dc569320c40c1cb2d2f97ef5d5348eebf067f20957381"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad827c6071bfe6d22de1bc331296a29f9ddc506ff926d8415b435ec6a6efce0"
|
||||
checksum = "11b5066db32cec1492573827183af2142d2d88fe85a83cfc9e73f0f63d3788d4"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"cranelift-bforest",
|
||||
@ -76,39 +76,39 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10e6b36237a9ca2ce2fb4cc7741d418a080afa1327402138412ef85d5367bef1"
|
||||
checksum = "64942e5774308e835fbad4dd25f253105412c90324631910e1ec27963147bddb"
|
||||
dependencies = [
|
||||
"cranelift-codegen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c36bf4bfb86898a94ccfa773a1f86e8a5346b1983ff72059bdd2db4600325251"
|
||||
checksum = "c39c33db9a86dd6d8d04166a10c53deb477aeea3500eaaefca682e4eda9bb986"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-control"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cbf36560e7a6bd1409ca91e7b43b2cc7ed8429f343d7605eadf9046e8fac0d0"
|
||||
checksum = "4b7fc4937613aea3156a0538800a17bf56f345a5da2e79ae3df58488c93d867f"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a71e11061a75b1184c09bea97c026a88f08b59ade96a7bb1f259d4ea0df2e942"
|
||||
checksum = "f85575e79a153ce1ddbfb7fe1813519b4bfe1eb200cc9c8353b45ad123ae4d36"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af5d4da63143ee3485c7bcedde0a818727d737d1083484a0ceedb8950c89e495"
|
||||
checksum = "bbc31d6c0ab2249fe0c21e988256b42f5f401ab2673b4fc40076c82a698bdfb9"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
@ -118,15 +118,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-isle"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "457a9832b089e26f5eea70dcf49bed8ec6edafed630ce7c83161f24d46ab8085"
|
||||
checksum = "dc14f37e3314c0e4c53779c2f46753bf242efff76ee9473757a1fff3b495ad37"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-jit"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0af95fe68d5a10919012c8db82b1d59820405b8001c8c6d05f94b08031334fa9"
|
||||
checksum = "cfdd1942f3233176a68c285380dbc84ff0440246a1bce308611c0a385b56ab18"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
@ -144,9 +144,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-module"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11b0b201fa10a4014062d4c56c307c8d18fdf9a84cb5279efe6080241f42c7a7"
|
||||
checksum = "121b2b5a16912554a1b9aace75b9b21eca49f28e33cbfbad4786dd9bc5361a5c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
@ -155,9 +155,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-native"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b490d579df1ce365e1ea359e24ed86d82289fa785153327c2f6a69a59a731e4"
|
||||
checksum = "2ea5375f76ab31f9800a23fb2b440810286a6f669a3eb467cdd7ff255ea64268"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"libc",
|
||||
@ -166,9 +166,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-object"
|
||||
version = "0.105.2"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb7e821ac6db471bcdbd004e5a4fa0d374f1046bd3a2ce278c332e0b0c01ca63"
|
||||
checksum = "f34e04419ab41661e973d90a73aa7b12771455394dae7a69b101a9b7e7589db7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
@ -392,9 +392,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.12"
|
||||
version = "0.12.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a"
|
||||
checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
@ -410,9 +410,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-jit-icache-coherence"
|
||||
version = "18.0.2"
|
||||
version = "19.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33f4121cb29dda08139b2824a734dd095d83ce843f2d613a84eb580b9cfc17ac"
|
||||
checksum = "2796e4b4989db62899d2117e1e0258b839d088c044591b14e3a0396e7b3ae53a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
|
@ -8,12 +8,12 @@ crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
# These have to be in sync with each other
|
||||
cranelift-codegen = { version = "0.105.2", default-features = false, features = ["std", "unwind", "all-arch"] }
|
||||
cranelift-frontend = { version = "0.105.2" }
|
||||
cranelift-module = { version = "0.105.2" }
|
||||
cranelift-native = { version = "0.105.2" }
|
||||
cranelift-jit = { version = "0.105.2", optional = true }
|
||||
cranelift-object = { version = "0.105.2" }
|
||||
cranelift-codegen = { version = "0.106.0", default-features = false, features = ["std", "unwind", "all-arch"] }
|
||||
cranelift-frontend = { version = "0.106.0" }
|
||||
cranelift-module = { version = "0.106.0" }
|
||||
cranelift-native = { version = "0.106.0" }
|
||||
cranelift-jit = { version = "0.106.0", optional = true }
|
||||
cranelift-object = { version = "0.106.0" }
|
||||
target-lexicon = "0.12.0"
|
||||
gimli = { version = "0.28", default-features = false, features = ["write"]}
|
||||
object = { version = "0.32", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
|
@ -39,6 +39,6 @@ index 42a26ae..5ac1042 100644
|
||||
+#![cfg(test)]
|
||||
#![feature(alloc_layout_extra)]
|
||||
#![feature(array_chunks)]
|
||||
#![feature(array_windows)]
|
||||
#![feature(array_ptr_get)]
|
||||
--
|
||||
2.21.0 (Apple Git-122)
|
||||
|
@ -1,3 +1,3 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-16"
|
||||
channel = "nightly-2024-03-28"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools"]
|
||||
|
@ -26,9 +26,10 @@ fn main() {
|
||||
codegen_backend_arg.push(cg_clif_dylib_path);
|
||||
args.push(codegen_backend_arg);
|
||||
}
|
||||
if !passed_args.iter().any(|arg| {
|
||||
arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot="))
|
||||
}) {
|
||||
if !passed_args
|
||||
.iter()
|
||||
.any(|arg| arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot=")))
|
||||
{
|
||||
args.push(OsString::from("--sysroot"));
|
||||
args.push(OsString::from(sysroot.to_str().unwrap()));
|
||||
}
|
||||
|
@ -26,12 +26,18 @@ fn main() {
|
||||
codegen_backend_arg.push(cg_clif_dylib_path);
|
||||
args.push(codegen_backend_arg);
|
||||
}
|
||||
if !passed_args.iter().any(|arg| {
|
||||
arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot="))
|
||||
}) {
|
||||
if !passed_args
|
||||
.iter()
|
||||
.any(|arg| arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot=")))
|
||||
{
|
||||
args.push(OsString::from("--sysroot"));
|
||||
args.push(OsString::from(sysroot.to_str().unwrap()));
|
||||
}
|
||||
if passed_args.is_empty() {
|
||||
// Don't pass any arguments when the user didn't pass any arguments
|
||||
// either to ensure the help message is shown.
|
||||
args.clear();
|
||||
}
|
||||
args.extend(passed_args);
|
||||
|
||||
let rustdoc = if let Some(rustdoc) = option_env!("RUSTDOC") {
|
||||
|
@ -10,14 +10,6 @@ pushd rust
|
||||
|
||||
command -v rg >/dev/null 2>&1 || cargo install ripgrep
|
||||
|
||||
# FIXME(rust-lang/rust#122196) fix stage0 rmake.rs run-make tests and remove
|
||||
# this workaround
|
||||
for test in $(ls tests/run-make); do
|
||||
if [[ -e "tests/run-make/$test/rmake.rs" ]]; then
|
||||
rm -r "tests/run-make/$test"
|
||||
fi
|
||||
done
|
||||
|
||||
# FIXME remove this workaround once ICE tests no longer emit an outdated nightly message
|
||||
for test in $(rg -i --files-with-matches "//@(\[.*\])? failure-status: 101" tests/ui); do
|
||||
echo "rm $test"
|
||||
@ -42,7 +34,6 @@ rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR
|
||||
# ================
|
||||
|
||||
# vendor intrinsics
|
||||
rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant"
|
||||
rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic
|
||||
|
||||
# exotic linkages
|
||||
@ -59,12 +50,9 @@ rm -r tests/run-make/c-link-to-rust-va-list-fn # requires callee side vararg sup
|
||||
rm -r tests/run-pass-valgrind/unsized-locals
|
||||
|
||||
# misc unimplemented things
|
||||
rm tests/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics
|
||||
rm tests/ui/target-feature/missing-plusminus.rs # error not implemented
|
||||
rm -r tests/run-make/emit-named-files # requires full --emit support
|
||||
rm -r tests/run-make/repr128-dwarf # debuginfo test
|
||||
rm -r tests/run-make/split-debuginfo # same
|
||||
rm -r tests/run-make/symbols-include-type-name # --emit=asm not supported
|
||||
rm -r tests/run-make/target-specs # i686 not supported by Cranelift
|
||||
rm -r tests/run-make/mismatching-target-triples # same
|
||||
rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly
|
||||
@ -102,6 +90,17 @@ rm tests/ui/abi/stack-protector.rs # requires stack protector support
|
||||
rm -r tests/run-make/emit-stack-sizes # requires support for -Z emit-stack-sizes
|
||||
rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific
|
||||
|
||||
# requires asm, llvm-ir and/or llvm-bc emit support
|
||||
# =============================================
|
||||
rm -r tests/run-make/emit-named-files
|
||||
rm -r tests/run-make/issue-30063
|
||||
rm -r tests/run-make/multiple-emits
|
||||
rm -r tests/run-make/output-type-permutations
|
||||
rm -r tests/run-make/emit-to-stdout
|
||||
rm -r tests/run-make/compressed-debuginfo
|
||||
rm -r tests/run-make/symbols-include-type-name
|
||||
|
||||
|
||||
# giving different but possibly correct results
|
||||
# =============================================
|
||||
rm tests/ui/mir/mir_misc_casts.rs # depends on deduplication of constants
|
||||
@ -109,35 +108,21 @@ rm tests/ui/mir/mir_raw_fat_ptr.rs # same
|
||||
rm tests/ui/consts/issue-33537.rs # same
|
||||
rm tests/ui/consts/const-mut-refs-crate.rs # same
|
||||
|
||||
# rustdoc-clif passes extra args, suppressing the help message when no args are passed
|
||||
rm -r tests/run-make/issue-88756-default-output
|
||||
|
||||
# doesn't work due to the way the rustc test suite is invoked.
|
||||
# should work when using ./x.py test the way it is intended
|
||||
# ============================================================
|
||||
rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
|
||||
rm -r tests/run-make/compiler-builtins # Expects lib/rustlib/src/rust to contains the standard library source
|
||||
|
||||
# genuine bugs
|
||||
# ============
|
||||
rm tests/incremental/spike-neg1.rs # errors out for some reason
|
||||
rm tests/incremental/spike-neg2.rs # same
|
||||
|
||||
rm -r tests/run-make/issue-51671 # wrong filename given in case of --emit=obj
|
||||
rm -r tests/run-make/issue-30063 # same
|
||||
rm -r tests/run-make/multiple-emits # same
|
||||
rm -r tests/run-make/output-type-permutations # same
|
||||
rm -r tests/run-make/used # same
|
||||
rm -r tests/run-make/no-alloc-shim
|
||||
rm -r tests/run-make/emit-to-stdout
|
||||
rm -r tests/run-make/compressed-debuginfo
|
||||
|
||||
rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet supported
|
||||
|
||||
rm tests/ui/codegen/subtyping-enforces-type-equality.rs # assert_assignable bug with Coroutine's
|
||||
rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort
|
||||
|
||||
# bugs in the test suite
|
||||
# ======================
|
||||
rm tests/ui/backtrace.rs # TODO warning
|
||||
rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue
|
||||
|
||||
rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
|
||||
@ -160,6 +145,19 @@ index ea06b620c4c..b969d0009c6 100644
|
||||
ifdef RUSTC_LINKER
|
||||
RUSTC := \$(RUSTC) -Clinker='\$(RUSTC_LINKER)'
|
||||
RUSTDOC := \$(RUSTDOC) -Clinker='\$(RUSTC_LINKER)'
|
||||
diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs
|
||||
index 9607ff02f96..b7d97caf9a2 100644
|
||||
--- a/src/tools/run-make-support/src/rustdoc.rs
|
||||
+++ b/src/tools/run-make-support/src/rustdoc.rs
|
||||
@@ -34,8 +34,6 @@ pub fn bare() -> Self {
|
||||
/// Construct a \`rustdoc\` invocation with \`-L \$(TARGET_RPATH_DIR)\` set.
|
||||
pub fn new() -> Self {
|
||||
let mut cmd = setup_common();
|
||||
- let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap();
|
||||
- cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy()));
|
||||
Self { cmd }
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
echo "[TEST] rustc test suite"
|
||||
|
@ -222,17 +222,15 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
|
||||
Spread(Vec<Option<CValue<'tcx>>>),
|
||||
}
|
||||
|
||||
let fn_abi = fx.fn_abi.take().unwrap();
|
||||
|
||||
// FIXME implement variadics in cranelift
|
||||
if fn_abi.c_variadic {
|
||||
if fx.fn_abi.c_variadic {
|
||||
fx.tcx.dcx().span_fatal(
|
||||
fx.mir.span,
|
||||
"Defining variadic functions is not yet supported by Cranelift",
|
||||
);
|
||||
}
|
||||
|
||||
let mut arg_abis_iter = fn_abi.args.iter();
|
||||
let mut arg_abis_iter = fx.fn_abi.args.iter();
|
||||
|
||||
let func_params = fx
|
||||
.mir
|
||||
@ -279,7 +277,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
|
||||
}
|
||||
|
||||
assert!(arg_abis_iter.next().is_none(), "ArgAbi left behind");
|
||||
fx.fn_abi = Some(fn_abi);
|
||||
assert!(block_params_iter.next().is_none(), "arg_value left behind");
|
||||
|
||||
self::comments::add_locals_header_comment(fx);
|
||||
|
@ -12,27 +12,15 @@ pub(super) fn codegen_return_param<'tcx>(
|
||||
ssa_analyzed: &rustc_index::IndexSlice<Local, crate::analyze::SsaKind>,
|
||||
block_params_iter: &mut impl Iterator<Item = Value>,
|
||||
) -> CPlace<'tcx> {
|
||||
let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode {
|
||||
let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.ret.mode {
|
||||
PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast { .. } => {
|
||||
let is_ssa =
|
||||
ssa_analyzed[RETURN_PLACE].is_ssa(fx, fx.fn_abi.as_ref().unwrap().ret.layout.ty);
|
||||
(
|
||||
super::make_local_place(
|
||||
fx,
|
||||
RETURN_PLACE,
|
||||
fx.fn_abi.as_ref().unwrap().ret.layout,
|
||||
is_ssa,
|
||||
),
|
||||
smallvec![],
|
||||
)
|
||||
let is_ssa = ssa_analyzed[RETURN_PLACE].is_ssa(fx, fx.fn_abi.ret.layout.ty);
|
||||
(super::make_local_place(fx, RETURN_PLACE, fx.fn_abi.ret.layout, is_ssa), smallvec![])
|
||||
}
|
||||
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
|
||||
let ret_param = block_params_iter.next().unwrap();
|
||||
assert_eq!(fx.bcx.func.dfg.value_type(ret_param), fx.pointer_type);
|
||||
(
|
||||
CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.as_ref().unwrap().ret.layout),
|
||||
smallvec![ret_param],
|
||||
)
|
||||
(CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.ret.layout), smallvec![ret_param])
|
||||
}
|
||||
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
|
||||
unreachable!("unsized return value")
|
||||
@ -45,8 +33,8 @@ pub(super) fn codegen_return_param<'tcx>(
|
||||
Some(RETURN_PLACE),
|
||||
None,
|
||||
&ret_param,
|
||||
&fx.fn_abi.as_ref().unwrap().ret.mode,
|
||||
fx.fn_abi.as_ref().unwrap().ret.layout,
|
||||
&fx.fn_abi.ret.mode,
|
||||
fx.fn_abi.ret.layout,
|
||||
);
|
||||
|
||||
ret_place
|
||||
@ -115,7 +103,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
|
||||
|
||||
/// Codegen a return instruction with the right return value(s) if any.
|
||||
pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) {
|
||||
match fx.fn_abi.as_ref().unwrap().ret.mode {
|
||||
match fx.fn_abi.ret.mode {
|
||||
PassMode::Ignore | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
|
||||
fx.bcx.ins().return_(&[]);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization;
|
||||
|
||||
use crate::constant::ConstantCx;
|
||||
use crate::debuginfo::FunctionDebugContext;
|
||||
use crate::debuginfo::{FunctionDebugContext, TypeDebugContext};
|
||||
use crate::prelude::*;
|
||||
use crate::pretty_clif::CommentWriter;
|
||||
|
||||
@ -26,6 +26,7 @@ pub(crate) struct CodegenedFunction {
|
||||
pub(crate) fn codegen_fn<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cx: &mut crate::CodegenCx,
|
||||
type_dbg: &mut TypeDebugContext<'tcx>,
|
||||
cached_func: Function,
|
||||
module: &mut dyn Module,
|
||||
instance: Instance<'tcx>,
|
||||
@ -69,8 +70,10 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||
let pointer_type = target_config.pointer_type();
|
||||
let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance);
|
||||
|
||||
let fn_abi = RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty());
|
||||
|
||||
let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context {
|
||||
Some(debug_context.define_function(tcx, &symbol_name, mir.span))
|
||||
Some(debug_context.define_function(tcx, type_dbg, instance, fn_abi, &symbol_name, mir.span))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -87,7 +90,7 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||
instance,
|
||||
symbol_name,
|
||||
mir,
|
||||
fn_abi: Some(RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty())),
|
||||
fn_abi,
|
||||
|
||||
bcx,
|
||||
block_map,
|
||||
@ -95,7 +98,6 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||
caller_location: None, // set by `codegen_fn_prelude`
|
||||
|
||||
clif_comments,
|
||||
last_source_file: None,
|
||||
next_ssa_var: 0,
|
||||
};
|
||||
|
||||
|
@ -1,12 +1,9 @@
|
||||
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||
use gimli::write::FileId;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers,
|
||||
};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::SourceFile;
|
||||
use rustc_target::abi::call::FnAbi;
|
||||
use rustc_target::abi::{Integer, Primitive};
|
||||
use rustc_target::spec::{HasTargetSpec, Target};
|
||||
@ -294,7 +291,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
|
||||
pub(crate) instance: Instance<'tcx>,
|
||||
pub(crate) symbol_name: String,
|
||||
pub(crate) mir: &'tcx Body<'tcx>,
|
||||
pub(crate) fn_abi: Option<&'tcx FnAbi<'tcx, Ty<'tcx>>>,
|
||||
pub(crate) fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>,
|
||||
|
||||
pub(crate) bcx: FunctionBuilder<'clif>,
|
||||
pub(crate) block_map: IndexVec<BasicBlock, Block>,
|
||||
@ -305,11 +302,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
|
||||
|
||||
pub(crate) clif_comments: crate::pretty_clif::CommentWriter,
|
||||
|
||||
/// Last accessed source file and it's debuginfo file id.
|
||||
///
|
||||
/// For optimization purposes only
|
||||
pub(crate) last_source_file: Option<(Lrc<SourceFile>, FileId)>,
|
||||
|
||||
/// This should only be accessed by `CPlace::new_var`.
|
||||
pub(crate) next_ssa_var: u32,
|
||||
}
|
||||
@ -419,25 +411,8 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
||||
|
||||
pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) {
|
||||
if let Some(debug_context) = &mut self.cx.debug_context {
|
||||
let (file, line, column) =
|
||||
DebugContext::get_span_loc(self.tcx, self.mir.span, source_info.span);
|
||||
|
||||
// add_source_file is very slow.
|
||||
// Optimize for the common case of the current file not being changed.
|
||||
let mut cached_file_id = None;
|
||||
if let Some((ref last_source_file, last_file_id)) = self.last_source_file {
|
||||
// If the allocations are not equal, the files may still be equal, but that
|
||||
// doesn't matter, as this is just an optimization.
|
||||
if rustc_data_structures::sync::Lrc::ptr_eq(last_source_file, &file) {
|
||||
cached_file_id = Some(last_file_id);
|
||||
}
|
||||
}
|
||||
|
||||
let file_id = if let Some(file_id) = cached_file_id {
|
||||
file_id
|
||||
} else {
|
||||
debug_context.add_source_file(&file)
|
||||
};
|
||||
let (file_id, line, column) =
|
||||
debug_context.get_span_loc(self.tcx, self.mir.span, source_info.span);
|
||||
|
||||
let source_loc =
|
||||
self.func_debug_cx.as_mut().unwrap().add_dbg_loc(file_id, line, column);
|
||||
|
@ -6,17 +6,16 @@ use cranelift_module::*;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::mir::interpret::{read_target_uint, AllocId, GlobalAlloc, Scalar};
|
||||
use rustc_middle::ty::ScalarInt;
|
||||
use rustc_middle::ty::{Binder, ExistentialTraitRef, ScalarInt};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) struct ConstantCx {
|
||||
todo: Vec<TodoItem>,
|
||||
done: FxHashSet<DataId>,
|
||||
anon_allocs: FxHashMap<AllocId, DataId>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
enum TodoItem {
|
||||
Alloc(AllocId),
|
||||
Static(DefId),
|
||||
@ -24,19 +23,24 @@ enum TodoItem {
|
||||
|
||||
impl ConstantCx {
|
||||
pub(crate) fn new() -> Self {
|
||||
ConstantCx { todo: vec![], done: FxHashSet::default(), anon_allocs: FxHashMap::default() }
|
||||
ConstantCx { todo: vec![], anon_allocs: FxHashMap::default() }
|
||||
}
|
||||
|
||||
pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut dyn Module) {
|
||||
define_all_allocs(tcx, module, &mut self);
|
||||
self.done.clear();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) {
|
||||
pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) -> DataId {
|
||||
let mut constants_cx = ConstantCx::new();
|
||||
constants_cx.todo.push(TodoItem::Static(def_id));
|
||||
constants_cx.finalize(tcx, module);
|
||||
|
||||
data_id_for_static(
|
||||
tcx, module, def_id, false,
|
||||
// For a declaration the stated mutability doesn't matter.
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn codegen_tls_ref<'tcx>(
|
||||
@ -153,14 +157,12 @@ pub(crate) fn codegen_const_value<'tcx>(
|
||||
fx.bcx.ins().func_addr(fx.pointer_type, local_func_id)
|
||||
}
|
||||
GlobalAlloc::VTable(ty, trait_ref) => {
|
||||
let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref));
|
||||
let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory();
|
||||
// FIXME: factor this common code with the `Memory` arm into a function?
|
||||
let data_id = data_id_for_alloc_id(
|
||||
let data_id = data_id_for_vtable(
|
||||
fx.tcx,
|
||||
&mut fx.constants_cx,
|
||||
fx.module,
|
||||
alloc_id,
|
||||
alloc.inner().mutability,
|
||||
ty,
|
||||
trait_ref,
|
||||
);
|
||||
let local_data_id =
|
||||
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
|
||||
@ -208,12 +210,8 @@ fn pointer_for_allocation<'tcx>(
|
||||
alloc_id: AllocId,
|
||||
) -> crate::pointer::Pointer {
|
||||
let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory();
|
||||
let data_id = data_id_for_alloc_id(
|
||||
&mut fx.constants_cx,
|
||||
&mut *fx.module,
|
||||
alloc_id,
|
||||
alloc.inner().mutability,
|
||||
);
|
||||
let data_id =
|
||||
data_id_for_alloc_id(&mut fx.constants_cx, fx.module, alloc_id, alloc.inner().mutability);
|
||||
|
||||
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
|
||||
if fx.clif_comments.enabled() {
|
||||
@ -235,6 +233,17 @@ pub(crate) fn data_id_for_alloc_id(
|
||||
.or_insert_with(|| module.declare_anonymous_data(mutability.is_mut(), false).unwrap())
|
||||
}
|
||||
|
||||
pub(crate) fn data_id_for_vtable<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cx: &mut ConstantCx,
|
||||
module: &mut dyn Module,
|
||||
ty: Ty<'tcx>,
|
||||
trait_ref: Option<Binder<'tcx, ExistentialTraitRef<'tcx>>>,
|
||||
) -> DataId {
|
||||
let alloc_id = tcx.vtable_allocation((ty, trait_ref));
|
||||
data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not)
|
||||
}
|
||||
|
||||
fn data_id_for_static(
|
||||
tcx: TyCtxt<'_>,
|
||||
module: &mut dyn Module,
|
||||
@ -327,7 +336,12 @@ fn data_id_for_static(
|
||||
}
|
||||
|
||||
fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) {
|
||||
let mut done = FxHashSet::default();
|
||||
while let Some(todo_item) = cx.todo.pop() {
|
||||
if !done.insert(todo_item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let (data_id, alloc, section_name) = match todo_item {
|
||||
TodoItem::Alloc(alloc_id) => {
|
||||
let alloc = match tcx.global_alloc(alloc_id) {
|
||||
@ -358,10 +372,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||
}
|
||||
};
|
||||
|
||||
if cx.done.contains(&data_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut data = DataDescription::new();
|
||||
let alloc = alloc.inner();
|
||||
data.set_align(alloc.align.bytes());
|
||||
@ -384,13 +394,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||
}
|
||||
|
||||
let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec();
|
||||
if bytes.is_empty() {
|
||||
// FIXME(bytecodealliance/wasmtime#7918) cranelift-jit has a bug where it causes UB on
|
||||
// empty data objects
|
||||
data.define(Box::new([0]));
|
||||
} else {
|
||||
data.define(bytes.into_boxed_slice());
|
||||
}
|
||||
data.define(bytes.into_boxed_slice());
|
||||
|
||||
for &(offset, prov) in alloc.provenance().ptrs().iter() {
|
||||
let alloc_id = prov.alloc_id();
|
||||
@ -418,8 +422,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||
data_id_for_alloc_id(cx, module, alloc_id, target_alloc.inner().mutability)
|
||||
}
|
||||
GlobalAlloc::VTable(ty, trait_ref) => {
|
||||
let alloc_id = tcx.vtable_allocation((ty, trait_ref));
|
||||
data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not)
|
||||
data_id_for_vtable(tcx, cx, module, ty, trait_ref)
|
||||
}
|
||||
GlobalAlloc::Static(def_id) => {
|
||||
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
|
||||
@ -446,7 +449,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||
}
|
||||
|
||||
module.define_data(data_id, &data).unwrap();
|
||||
cx.done.insert(data_id);
|
||||
}
|
||||
|
||||
assert!(cx.todo.is_empty(), "{:?}", cx.todo);
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! Write the debuginfo into an object file.
|
||||
|
||||
use cranelift_module::{DataId, FuncId};
|
||||
use cranelift_object::ObjectProduct;
|
||||
use gimli::write::{Address, AttributeValue, EndianVec, Result, Sections, Writer};
|
||||
use gimli::{RunTimeEndian, SectionId};
|
||||
@ -8,6 +9,18 @@ use rustc_data_structures::fx::FxHashMap;
|
||||
use super::object::WriteDebugInfo;
|
||||
use super::DebugContext;
|
||||
|
||||
pub(super) fn address_for_func(func_id: FuncId) -> Address {
|
||||
let symbol = func_id.as_u32();
|
||||
assert!(symbol & 1 << 31 == 0);
|
||||
Address::Symbol { symbol: symbol as usize, addend: 0 }
|
||||
}
|
||||
|
||||
pub(super) fn address_for_data(data_id: DataId) -> Address {
|
||||
let symbol = data_id.as_u32();
|
||||
assert!(symbol & 1 << 31 == 0);
|
||||
Address::Symbol { symbol: (symbol | 1 << 31) as usize, addend: 0 }
|
||||
}
|
||||
|
||||
impl DebugContext {
|
||||
pub(crate) fn emit(&mut self, product: &mut ObjectProduct) {
|
||||
let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
|
||||
@ -171,6 +184,7 @@ impl Writer for WriterRelocate {
|
||||
gimli::DW_EH_PE_pcrel => {
|
||||
let size = match eh_pe.format() {
|
||||
gimli::DW_EH_PE_sdata4 => 4,
|
||||
gimli::DW_EH_PE_sdata8 => 8,
|
||||
_ => return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)),
|
||||
};
|
||||
self.relocs.push(DebugReloc {
|
||||
|
@ -5,14 +5,12 @@ use std::path::{Component, Path};
|
||||
|
||||
use cranelift_codegen::binemit::CodeOffset;
|
||||
use cranelift_codegen::MachSrcLoc;
|
||||
use gimli::write::{
|
||||
Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable,
|
||||
};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable};
|
||||
use rustc_span::{
|
||||
FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm,
|
||||
};
|
||||
|
||||
use crate::debuginfo::emit::address_for_func;
|
||||
use crate::debuginfo::FunctionDebugContext;
|
||||
use crate::prelude::*;
|
||||
|
||||
@ -60,10 +58,11 @@ fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
|
||||
|
||||
impl DebugContext {
|
||||
pub(crate) fn get_span_loc(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'_>,
|
||||
function_span: Span,
|
||||
span: Span,
|
||||
) -> (Lrc<SourceFile>, u64, u64) {
|
||||
) -> (FileId, u64, u64) {
|
||||
// Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131
|
||||
// In order to have a good line stepping behavior in debugger, we overwrite debug
|
||||
// locations of macro expansions with that of the outermost expansion site (when the macro is
|
||||
@ -71,61 +70,66 @@ impl DebugContext {
|
||||
let span = tcx.collapsed_debuginfo(span, function_span);
|
||||
match tcx.sess.source_map().lookup_line(span.lo()) {
|
||||
Ok(SourceFileAndLine { sf: file, line }) => {
|
||||
let file_id = self.add_source_file(&file);
|
||||
let line_pos = file.lines()[line];
|
||||
let col = file.relative_position(span.lo()) - line_pos;
|
||||
|
||||
(file, u64::try_from(line).unwrap() + 1, u64::from(col.to_u32()) + 1)
|
||||
(file_id, u64::try_from(line).unwrap() + 1, u64::from(col.to_u32()) + 1)
|
||||
}
|
||||
Err(file) => (file, 0, 0),
|
||||
Err(file) => (self.add_source_file(&file), 0, 0),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn add_source_file(&mut self, source_file: &SourceFile) -> FileId {
|
||||
let line_program: &mut LineProgram = &mut self.dwarf.unit.line_program;
|
||||
let line_strings: &mut LineStringTable = &mut self.dwarf.line_strings;
|
||||
let cache_key = (source_file.stable_id, source_file.src_hash);
|
||||
*self.created_files.entry(cache_key).or_insert_with(|| {
|
||||
let line_program: &mut LineProgram = &mut self.dwarf.unit.line_program;
|
||||
let line_strings: &mut LineStringTable = &mut self.dwarf.line_strings;
|
||||
|
||||
match &source_file.name {
|
||||
FileName::Real(path) => {
|
||||
let (dir_path, file_name) =
|
||||
split_path_dir_and_file(if self.should_remap_filepaths {
|
||||
path.remapped_path_if_available()
|
||||
} else {
|
||||
path.local_path_if_available()
|
||||
});
|
||||
let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str());
|
||||
let file_name = osstr_as_utf8_bytes(file_name);
|
||||
|
||||
let dir_id = if !dir_name.is_empty() {
|
||||
let dir_name = LineString::new(dir_name, line_program.encoding(), line_strings);
|
||||
line_program.add_directory(dir_name)
|
||||
} else {
|
||||
line_program.default_directory()
|
||||
};
|
||||
let file_name = LineString::new(file_name, line_program.encoding(), line_strings);
|
||||
|
||||
let info = make_file_info(source_file.src_hash);
|
||||
|
||||
line_program.file_has_md5 &= info.is_some();
|
||||
line_program.add_file(file_name, dir_id, info)
|
||||
}
|
||||
// FIXME give more appropriate file names
|
||||
filename => {
|
||||
let dir_id = line_program.default_directory();
|
||||
let dummy_file_name = LineString::new(
|
||||
filename
|
||||
.display(if self.should_remap_filepaths {
|
||||
FileNameDisplayPreference::Remapped
|
||||
match &source_file.name {
|
||||
FileName::Real(path) => {
|
||||
let (dir_path, file_name) =
|
||||
split_path_dir_and_file(if self.should_remap_filepaths {
|
||||
path.remapped_path_if_available()
|
||||
} else {
|
||||
FileNameDisplayPreference::Local
|
||||
})
|
||||
.to_string()
|
||||
.into_bytes(),
|
||||
line_program.encoding(),
|
||||
line_strings,
|
||||
);
|
||||
line_program.add_file(dummy_file_name, dir_id, None)
|
||||
path.local_path_if_available()
|
||||
});
|
||||
let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str());
|
||||
let file_name = osstr_as_utf8_bytes(file_name);
|
||||
|
||||
let dir_id = if !dir_name.is_empty() {
|
||||
let dir_name =
|
||||
LineString::new(dir_name, line_program.encoding(), line_strings);
|
||||
line_program.add_directory(dir_name)
|
||||
} else {
|
||||
line_program.default_directory()
|
||||
};
|
||||
let file_name =
|
||||
LineString::new(file_name, line_program.encoding(), line_strings);
|
||||
|
||||
let info = make_file_info(source_file.src_hash);
|
||||
|
||||
line_program.file_has_md5 &= info.is_some();
|
||||
line_program.add_file(file_name, dir_id, info)
|
||||
}
|
||||
filename => {
|
||||
let dir_id = line_program.default_directory();
|
||||
let dummy_file_name = LineString::new(
|
||||
filename
|
||||
.display(if self.should_remap_filepaths {
|
||||
FileNameDisplayPreference::Remapped
|
||||
} else {
|
||||
FileNameDisplayPreference::Local
|
||||
})
|
||||
.to_string()
|
||||
.into_bytes(),
|
||||
line_program.encoding(),
|
||||
line_strings,
|
||||
);
|
||||
line_program.add_file(dummy_file_name, dir_id, None)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +142,7 @@ impl FunctionDebugContext {
|
||||
pub(super) fn create_debug_lines(
|
||||
&mut self,
|
||||
debug_context: &mut DebugContext,
|
||||
symbol: usize,
|
||||
func_id: FuncId,
|
||||
context: &Context,
|
||||
) -> CodeOffset {
|
||||
let create_row_for_span =
|
||||
@ -151,11 +155,7 @@ impl FunctionDebugContext {
|
||||
debug_context.dwarf.unit.line_program.generate_row();
|
||||
};
|
||||
|
||||
debug_context
|
||||
.dwarf
|
||||
.unit
|
||||
.line_program
|
||||
.begin_sequence(Some(Address::Symbol { symbol, addend: 0 }));
|
||||
debug_context.dwarf.unit.line_program.begin_sequence(Some(address_for_func(func_id)));
|
||||
|
||||
let mut func_end = 0;
|
||||
|
||||
@ -178,10 +178,7 @@ impl FunctionDebugContext {
|
||||
assert_ne!(func_end, 0);
|
||||
|
||||
let entry = debug_context.dwarf.unit.get_mut(self.entry_id);
|
||||
entry.set(
|
||||
gimli::DW_AT_low_pc,
|
||||
AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
|
||||
);
|
||||
entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id)));
|
||||
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end)));
|
||||
|
||||
func_end
|
||||
|
@ -3,20 +3,29 @@
|
||||
mod emit;
|
||||
mod line_info;
|
||||
mod object;
|
||||
mod types;
|
||||
mod unwind;
|
||||
|
||||
use cranelift_codegen::ir::Endianness;
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_module::DataId;
|
||||
use gimli::write::{
|
||||
Address, AttributeValue, DwarfUnit, FileId, LineProgram, LineString, Range, RangeList,
|
||||
UnitEntryId,
|
||||
Address, AttributeValue, DwarfUnit, Expression, FileId, LineProgram, LineString, Range,
|
||||
RangeList, UnitEntryId,
|
||||
};
|
||||
use gimli::{Encoding, Format, LineEncoding, RunTimeEndian};
|
||||
use gimli::{AArch64, Encoding, Format, LineEncoding, Register, RiscV, RunTimeEndian, X86_64};
|
||||
use indexmap::IndexSet;
|
||||
use rustc_codegen_ssa::debuginfo::type_names;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefIdMap;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::{SourceFileHash, StableSourceFileId};
|
||||
use rustc_target::abi::call::FnAbi;
|
||||
|
||||
pub(crate) use self::emit::{DebugReloc, DebugRelocName};
|
||||
pub(crate) use self::types::TypeDebugContext;
|
||||
pub(crate) use self::unwind::UnwindContext;
|
||||
use crate::debuginfo::emit::{address_for_data, address_for_func};
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) fn producer(sess: &Session) -> String {
|
||||
@ -28,6 +37,10 @@ pub(crate) struct DebugContext {
|
||||
|
||||
dwarf: DwarfUnit,
|
||||
unit_range_list: RangeList,
|
||||
created_files: FxHashMap<(StableSourceFileId, SourceFileHash), FileId>,
|
||||
stack_pointer_register: Register,
|
||||
namespace_map: DefIdMap<UnitEntryId>,
|
||||
array_size_type: UnitEntryId,
|
||||
|
||||
should_remap_filepaths: bool,
|
||||
}
|
||||
@ -39,7 +52,7 @@ pub(crate) struct FunctionDebugContext {
|
||||
}
|
||||
|
||||
impl DebugContext {
|
||||
pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa) -> Self {
|
||||
pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, cgu_name: &str) -> Self {
|
||||
let encoding = Encoding {
|
||||
format: Format::Dwarf32,
|
||||
// FIXME this should be configurable
|
||||
@ -60,6 +73,15 @@ impl DebugContext {
|
||||
Endianness::Big => RunTimeEndian::Big,
|
||||
};
|
||||
|
||||
let stack_pointer_register = match isa.triple().architecture {
|
||||
target_lexicon::Architecture::Aarch64(_) => AArch64::SP,
|
||||
target_lexicon::Architecture::Riscv64(_) => RiscV::SP,
|
||||
target_lexicon::Architecture::X86_64 | target_lexicon::Architecture::X86_64h => {
|
||||
X86_64::RSP
|
||||
}
|
||||
_ => Register(u16::MAX),
|
||||
};
|
||||
|
||||
let mut dwarf = DwarfUnit::new(encoding);
|
||||
|
||||
let should_remap_filepaths = tcx.sess.should_prefer_remapped_for_codegen();
|
||||
@ -95,7 +117,7 @@ impl DebugContext {
|
||||
dwarf.unit.line_program = line_program;
|
||||
|
||||
{
|
||||
let name = dwarf.strings.add(name);
|
||||
let name = dwarf.strings.add(format!("{name}/@/{cgu_name}"));
|
||||
let comp_dir = dwarf.strings.add(comp_dir);
|
||||
|
||||
let root = dwarf.unit.root();
|
||||
@ -103,41 +125,134 @@ impl DebugContext {
|
||||
root.set(gimli::DW_AT_producer, AttributeValue::StringRef(dwarf.strings.add(producer)));
|
||||
root.set(gimli::DW_AT_language, AttributeValue::Language(gimli::DW_LANG_Rust));
|
||||
root.set(gimli::DW_AT_name, AttributeValue::StringRef(name));
|
||||
|
||||
// This will be replaced when emitting the debuginfo. It is only
|
||||
// defined here to ensure that the order of the attributes matches
|
||||
// rustc.
|
||||
root.set(gimli::DW_AT_stmt_list, AttributeValue::Udata(0));
|
||||
|
||||
root.set(gimli::DW_AT_comp_dir, AttributeValue::StringRef(comp_dir));
|
||||
root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0)));
|
||||
}
|
||||
|
||||
let array_size_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type);
|
||||
let array_size_type_entry = dwarf.unit.get_mut(array_size_type);
|
||||
array_size_type_entry.set(
|
||||
gimli::DW_AT_name,
|
||||
AttributeValue::StringRef(dwarf.strings.add("__ARRAY_SIZE_TYPE__")),
|
||||
);
|
||||
array_size_type_entry
|
||||
.set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned));
|
||||
array_size_type_entry.set(
|
||||
gimli::DW_AT_byte_size,
|
||||
AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()),
|
||||
);
|
||||
|
||||
DebugContext {
|
||||
endian,
|
||||
dwarf,
|
||||
unit_range_list: RangeList(Vec::new()),
|
||||
created_files: FxHashMap::default(),
|
||||
stack_pointer_register,
|
||||
namespace_map: DefIdMap::default(),
|
||||
array_size_type,
|
||||
should_remap_filepaths,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn define_function(
|
||||
fn item_namespace(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> UnitEntryId {
|
||||
if let Some(&scope) = self.namespace_map.get(&def_id) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
let def_key = tcx.def_key(def_id);
|
||||
let parent_scope = def_key
|
||||
.parent
|
||||
.map(|parent| self.item_namespace(tcx, DefId { krate: def_id.krate, index: parent }))
|
||||
.unwrap_or(self.dwarf.unit.root());
|
||||
|
||||
let namespace_name = {
|
||||
let mut output = String::new();
|
||||
type_names::push_item_name(tcx, def_id, false, &mut output);
|
||||
output
|
||||
};
|
||||
let namespace_name_id = self.dwarf.strings.add(namespace_name);
|
||||
|
||||
let scope = self.dwarf.unit.add(parent_scope, gimli::DW_TAG_namespace);
|
||||
let scope_entry = self.dwarf.unit.get_mut(scope);
|
||||
scope_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(namespace_name_id));
|
||||
|
||||
self.namespace_map.insert(def_id, scope);
|
||||
scope
|
||||
}
|
||||
|
||||
pub(crate) fn define_function<'tcx>(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'_>,
|
||||
name: &str,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
type_dbg: &mut TypeDebugContext<'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>,
|
||||
linkage_name: &str,
|
||||
function_span: Span,
|
||||
) -> FunctionDebugContext {
|
||||
let (file, line, column) = DebugContext::get_span_loc(tcx, function_span, function_span);
|
||||
let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span);
|
||||
|
||||
let file_id = self.add_source_file(&file);
|
||||
let scope = self.item_namespace(tcx, tcx.parent(instance.def_id()));
|
||||
|
||||
// FIXME: add to appropriate scope instead of root
|
||||
let scope = self.dwarf.unit.root();
|
||||
let mut name = String::new();
|
||||
type_names::push_item_name(tcx, instance.def_id(), false, &mut name);
|
||||
|
||||
// Find the enclosing function, in case this is a closure.
|
||||
let enclosing_fn_def_id = tcx.typeck_root_def_id(instance.def_id());
|
||||
|
||||
// We look up the generics of the enclosing function and truncate the args
|
||||
// to their length in order to cut off extra stuff that might be in there for
|
||||
// closures or coroutines.
|
||||
let generics = tcx.generics_of(enclosing_fn_def_id);
|
||||
let args = instance.args.truncate_to(tcx, generics);
|
||||
|
||||
type_names::push_generic_params(
|
||||
tcx,
|
||||
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
|
||||
enclosing_fn_def_id,
|
||||
&mut name,
|
||||
);
|
||||
|
||||
let entry_id = self.dwarf.unit.add(scope, gimli::DW_TAG_subprogram);
|
||||
let entry = self.dwarf.unit.get_mut(entry_id);
|
||||
let linkage_name_id =
|
||||
if name != linkage_name { Some(self.dwarf.strings.add(linkage_name)) } else { None };
|
||||
let name_id = self.dwarf.strings.add(name);
|
||||
|
||||
// These will be replaced in FunctionDebugContext::finalize. They are
|
||||
// only defined here to ensure that the order of the attributes matches
|
||||
// rustc.
|
||||
entry.set(gimli::DW_AT_low_pc, AttributeValue::Udata(0));
|
||||
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(0));
|
||||
|
||||
let mut frame_base_expr = Expression::new();
|
||||
frame_base_expr.op_reg(self.stack_pointer_register);
|
||||
entry.set(gimli::DW_AT_frame_base, AttributeValue::Exprloc(frame_base_expr));
|
||||
|
||||
if let Some(linkage_name_id) = linkage_name_id {
|
||||
entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(linkage_name_id));
|
||||
}
|
||||
// Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped.
|
||||
entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id));
|
||||
entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id));
|
||||
|
||||
entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id)));
|
||||
entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line));
|
||||
entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(column));
|
||||
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
let return_dw_ty = self.debug_type(tcx, type_dbg, fn_abi.ret.layout.ty);
|
||||
let entry = self.dwarf.unit.get_mut(entry_id);
|
||||
entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(return_dw_ty));
|
||||
}
|
||||
|
||||
if tcx.is_reachable_non_generic(instance.def_id()) {
|
||||
let entry = self.dwarf.unit.get_mut(entry_id);
|
||||
entry.set(gimli::DW_AT_external, AttributeValue::FlagPresent);
|
||||
}
|
||||
|
||||
FunctionDebugContext {
|
||||
entry_id,
|
||||
@ -145,6 +260,62 @@ impl DebugContext {
|
||||
source_loc_set: IndexSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from https://github.com/rust-lang/rust/blob/10a7aa14fed9b528b74b0f098c4899c37c09a9c7/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs#L1288-L1346
|
||||
pub(crate) fn define_static<'tcx>(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
type_dbg: &mut TypeDebugContext<'tcx>,
|
||||
def_id: DefId,
|
||||
data_id: DataId,
|
||||
) {
|
||||
let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() };
|
||||
if nested {
|
||||
return;
|
||||
}
|
||||
|
||||
let scope = self.item_namespace(tcx, tcx.parent(def_id));
|
||||
|
||||
let span = tcx.def_span(def_id);
|
||||
let (file_id, line, _column) = self.get_span_loc(tcx, span, span);
|
||||
|
||||
let static_type = Instance::mono(tcx, def_id).ty(tcx, ty::ParamEnv::reveal_all());
|
||||
let static_layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(static_type)).unwrap();
|
||||
// FIXME use the actual type layout
|
||||
let type_id = self.debug_type(tcx, type_dbg, static_type);
|
||||
|
||||
let name = tcx.item_name(def_id);
|
||||
let linkage_name = tcx.symbol_name(Instance::mono(tcx, def_id)).name;
|
||||
|
||||
let entry_id = self.dwarf.unit.add(scope, gimli::DW_TAG_variable);
|
||||
let entry = self.dwarf.unit.get_mut(entry_id);
|
||||
let linkage_name_id = if name.as_str() != linkage_name {
|
||||
Some(self.dwarf.strings.add(linkage_name))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let name_id = self.dwarf.strings.add(name.as_str());
|
||||
|
||||
entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id));
|
||||
entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(type_id));
|
||||
|
||||
if tcx.is_reachable_non_generic(def_id) {
|
||||
entry.set(gimli::DW_AT_external, AttributeValue::FlagPresent);
|
||||
}
|
||||
|
||||
entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id)));
|
||||
entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line));
|
||||
|
||||
entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(static_layout.align.pref.bytes()));
|
||||
|
||||
let mut expr = Expression::new();
|
||||
expr.op_addr(address_for_data(data_id));
|
||||
entry.set(gimli::DW_AT_location, AttributeValue::Exprloc(expr));
|
||||
|
||||
if let Some(linkage_name_id) = linkage_name_id {
|
||||
entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(linkage_name_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FunctionDebugContext {
|
||||
@ -154,21 +325,16 @@ impl FunctionDebugContext {
|
||||
func_id: FuncId,
|
||||
context: &Context,
|
||||
) {
|
||||
let symbol = func_id.as_u32() as usize;
|
||||
let end = self.create_debug_lines(debug_context, func_id, context);
|
||||
|
||||
let end = self.create_debug_lines(debug_context, symbol, context);
|
||||
|
||||
debug_context.unit_range_list.0.push(Range::StartLength {
|
||||
begin: Address::Symbol { symbol, addend: 0 },
|
||||
length: u64::from(end),
|
||||
});
|
||||
debug_context
|
||||
.unit_range_list
|
||||
.0
|
||||
.push(Range::StartLength { begin: address_for_func(func_id), length: u64::from(end) });
|
||||
|
||||
let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id);
|
||||
// Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped.
|
||||
func_entry.set(
|
||||
gimli::DW_AT_low_pc,
|
||||
AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
|
||||
);
|
||||
func_entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id)));
|
||||
// Using Udata for DW_AT_high_pc requires at least DWARF4
|
||||
func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end)));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use cranelift_module::FuncId;
|
||||
use cranelift_module::{DataId, FuncId};
|
||||
use cranelift_object::ObjectProduct;
|
||||
use gimli::SectionId;
|
||||
use object::write::{Relocation, StandardSegment};
|
||||
@ -57,10 +57,13 @@ impl WriteDebugInfo for ObjectProduct {
|
||||
let (symbol, symbol_offset) = match reloc.name {
|
||||
DebugRelocName::Section(id) => (section_map.get(&id).unwrap().1, 0),
|
||||
DebugRelocName::Symbol(id) => {
|
||||
let symbol_id = self.function_symbol(FuncId::from_u32(id.try_into().unwrap()));
|
||||
self.object
|
||||
.symbol_section_and_offset(symbol_id)
|
||||
.expect("Debug reloc for undef sym???")
|
||||
let id = id.try_into().unwrap();
|
||||
let symbol_id = if id & 1 << 31 == 0 {
|
||||
self.function_symbol(FuncId::from_u32(id))
|
||||
} else {
|
||||
self.data_symbol(DataId::from_u32(id & !(1 << 31)))
|
||||
};
|
||||
self.object.symbol_section_and_offset(symbol_id).unwrap_or((symbol_id, 0))
|
||||
}
|
||||
};
|
||||
self.object
|
||||
|
204
compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
Normal file
204
compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
Normal file
@ -0,0 +1,204 @@
|
||||
// Adapted from https://github.com/rust-lang/rust/blob/10a7aa14fed9b528b74b0f098c4899c37c09a9c7/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
|
||||
|
||||
use gimli::write::{AttributeValue, UnitEntryId};
|
||||
use rustc_codegen_ssa::debuginfo::type_names;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
|
||||
use crate::{has_ptr_meta, DebugContext, RevealAllLayoutCx};
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct TypeDebugContext<'tcx> {
|
||||
type_map: FxHashMap<Ty<'tcx>, UnitEntryId>,
|
||||
}
|
||||
|
||||
/// Returns from the enclosing function if the type debuginfo node with the given
|
||||
/// unique ID can be found in the type map.
|
||||
macro_rules! return_if_type_created_in_meantime {
|
||||
($type_dbg:expr, $ty:expr) => {
|
||||
if let Some(&type_id) = $type_dbg.type_map.get(&$ty) {
|
||||
return type_id;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl DebugContext {
|
||||
pub(crate) fn debug_type<'tcx>(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
type_dbg: &mut TypeDebugContext<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> UnitEntryId {
|
||||
if let Some(&type_id) = type_dbg.type_map.get(&ty) {
|
||||
return type_id;
|
||||
}
|
||||
|
||||
let type_id = match ty.kind() {
|
||||
ty::Never | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => {
|
||||
self.basic_type(tcx, ty)
|
||||
}
|
||||
ty::Tuple(elems) if elems.is_empty() => self.basic_type(tcx, ty),
|
||||
ty::Array(elem_ty, len) => self.array_type(
|
||||
tcx,
|
||||
type_dbg,
|
||||
ty,
|
||||
*elem_ty,
|
||||
len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()),
|
||||
),
|
||||
// ty::Slice(_) | ty::Str
|
||||
// ty::Dynamic
|
||||
// ty::Foreign
|
||||
ty::RawPtr(pointee_type, _) | ty::Ref(_, pointee_type, _) => {
|
||||
self.pointer_type(tcx, type_dbg, ty, *pointee_type)
|
||||
}
|
||||
// ty::Adt(def, args) if def.is_box() && args.get(1).map_or(true, |arg| cx.layout_of(arg.expect_ty()).is_1zst())
|
||||
// ty::FnDef(..) | ty::FnPtr(..)
|
||||
// ty::Closure(..)
|
||||
// ty::Adt(def, ..)
|
||||
ty::Tuple(components) => self.tuple_type(tcx, type_dbg, ty, *components),
|
||||
// ty::Param(_)
|
||||
// FIXME implement remaining types and add unreachable!() to the fallback branch
|
||||
_ => self.placeholder_for_type(tcx, type_dbg, ty),
|
||||
};
|
||||
|
||||
type_dbg.type_map.insert(ty, type_id);
|
||||
|
||||
type_id
|
||||
}
|
||||
|
||||
fn basic_type<'tcx>(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> UnitEntryId {
|
||||
let (name, encoding) = match ty.kind() {
|
||||
ty::Never => ("!", gimli::DW_ATE_unsigned),
|
||||
ty::Tuple(elems) if elems.is_empty() => ("()", gimli::DW_ATE_unsigned),
|
||||
ty::Bool => ("bool", gimli::DW_ATE_boolean),
|
||||
ty::Char => ("char", gimli::DW_ATE_UTF),
|
||||
ty::Int(int_ty) => (int_ty.name_str(), gimli::DW_ATE_signed),
|
||||
ty::Uint(uint_ty) => (uint_ty.name_str(), gimli::DW_ATE_unsigned),
|
||||
ty::Float(float_ty) => (float_ty.name_str(), gimli::DW_ATE_float),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let type_id = self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_base_type);
|
||||
let type_entry = self.dwarf.unit.get_mut(type_id);
|
||||
type_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name)));
|
||||
type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(encoding));
|
||||
type_entry.set(
|
||||
gimli::DW_AT_byte_size,
|
||||
AttributeValue::Udata(RevealAllLayoutCx(tcx).layout_of(ty).size.bytes()),
|
||||
);
|
||||
|
||||
type_id
|
||||
}
|
||||
|
||||
fn array_type<'tcx>(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
type_dbg: &mut TypeDebugContext<'tcx>,
|
||||
array_ty: Ty<'tcx>,
|
||||
elem_ty: Ty<'tcx>,
|
||||
len: u64,
|
||||
) -> UnitEntryId {
|
||||
let elem_dw_ty = self.debug_type(tcx, type_dbg, elem_ty);
|
||||
|
||||
return_if_type_created_in_meantime!(type_dbg, array_ty);
|
||||
|
||||
let array_type_id = self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_array_type);
|
||||
let array_type_entry = self.dwarf.unit.get_mut(array_type_id);
|
||||
array_type_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(elem_dw_ty));
|
||||
|
||||
let subrange_id = self.dwarf.unit.add(array_type_id, gimli::DW_TAG_subrange_type);
|
||||
let subrange_entry = self.dwarf.unit.get_mut(subrange_id);
|
||||
subrange_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type));
|
||||
subrange_entry.set(gimli::DW_AT_lower_bound, AttributeValue::Udata(0));
|
||||
subrange_entry.set(gimli::DW_AT_count, AttributeValue::Udata(len));
|
||||
|
||||
array_type_id
|
||||
}
|
||||
|
||||
fn pointer_type<'tcx>(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
type_dbg: &mut TypeDebugContext<'tcx>,
|
||||
ptr_type: Ty<'tcx>,
|
||||
pointee_type: Ty<'tcx>,
|
||||
) -> UnitEntryId {
|
||||
let pointee_dw_ty = self.debug_type(tcx, type_dbg, pointee_type);
|
||||
|
||||
return_if_type_created_in_meantime!(type_dbg, ptr_type);
|
||||
|
||||
let name = type_names::compute_debuginfo_type_name(tcx, ptr_type, true);
|
||||
|
||||
if !has_ptr_meta(tcx, ptr_type) {
|
||||
let pointer_type_id =
|
||||
self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_pointer_type);
|
||||
let pointer_entry = self.dwarf.unit.get_mut(pointer_type_id);
|
||||
pointer_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(pointee_dw_ty));
|
||||
pointer_entry
|
||||
.set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name)));
|
||||
|
||||
pointer_type_id
|
||||
} else {
|
||||
// FIXME implement debuginfo for fat pointers
|
||||
self.placeholder_for_type(tcx, type_dbg, ptr_type)
|
||||
}
|
||||
}
|
||||
|
||||
fn tuple_type<'tcx>(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
type_dbg: &mut TypeDebugContext<'tcx>,
|
||||
tuple_type: Ty<'tcx>,
|
||||
components: &'tcx [Ty<'tcx>],
|
||||
) -> UnitEntryId {
|
||||
let components = components
|
||||
.into_iter()
|
||||
.map(|&ty| (ty, self.debug_type(tcx, type_dbg, ty)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
return_if_type_created_in_meantime!(type_dbg, tuple_type);
|
||||
|
||||
let name = type_names::compute_debuginfo_type_name(tcx, tuple_type, false);
|
||||
let layout = RevealAllLayoutCx(tcx).layout_of(tuple_type);
|
||||
|
||||
let tuple_type_id =
|
||||
self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_structure_type);
|
||||
let tuple_entry = self.dwarf.unit.get_mut(tuple_type_id);
|
||||
tuple_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name)));
|
||||
tuple_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes()));
|
||||
tuple_entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(layout.align.pref.bytes()));
|
||||
|
||||
for (i, (ty, dw_ty)) in components.into_iter().enumerate() {
|
||||
let member_id = self.dwarf.unit.add(tuple_type_id, gimli::DW_TAG_member);
|
||||
let member_entry = self.dwarf.unit.get_mut(member_id);
|
||||
member_entry.set(
|
||||
gimli::DW_AT_name,
|
||||
AttributeValue::StringRef(self.dwarf.strings.add(format!("__{i}"))),
|
||||
);
|
||||
member_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty));
|
||||
member_entry.set(
|
||||
gimli::DW_AT_alignment,
|
||||
AttributeValue::Udata(RevealAllLayoutCx(tcx).layout_of(ty).align.pref.bytes()),
|
||||
);
|
||||
member_entry.set(
|
||||
gimli::DW_AT_data_member_location,
|
||||
AttributeValue::Udata(layout.fields.offset(i).bytes()),
|
||||
);
|
||||
}
|
||||
|
||||
tuple_type_id
|
||||
}
|
||||
|
||||
fn placeholder_for_type<'tcx>(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
type_dbg: &mut TypeDebugContext<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> UnitEntryId {
|
||||
self.debug_type(
|
||||
tcx,
|
||||
type_dbg,
|
||||
Ty::new_array(tcx, tcx.types.u8, RevealAllLayoutCx(tcx).layout_of(ty).size.bytes()),
|
||||
)
|
||||
}
|
||||
}
|
@ -3,9 +3,10 @@
|
||||
use cranelift_codegen::ir::Endianness;
|
||||
use cranelift_codegen::isa::{unwind::UnwindInfo, TargetIsa};
|
||||
use cranelift_object::ObjectProduct;
|
||||
use gimli::write::{Address, CieId, EhFrame, FrameTable, Section};
|
||||
use gimli::write::{CieId, EhFrame, FrameTable, Section};
|
||||
use gimli::RunTimeEndian;
|
||||
|
||||
use super::emit::address_for_func;
|
||||
use super::object::WriteDebugInfo;
|
||||
use crate::prelude::*;
|
||||
|
||||
@ -47,11 +48,8 @@ impl UnwindContext {
|
||||
|
||||
match unwind_info {
|
||||
UnwindInfo::SystemV(unwind_info) => {
|
||||
self.frame_table.add_fde(
|
||||
self.cie_id.unwrap(),
|
||||
unwind_info
|
||||
.to_fde(Address::Symbol { symbol: func_id.as_u32() as usize, addend: 0 }),
|
||||
);
|
||||
self.frame_table
|
||||
.add_fde(self.cie_id.unwrap(), unwind_info.to_fde(address_for_func(func_id)));
|
||||
}
|
||||
UnwindInfo::WindowsX64(_) => {
|
||||
// FIXME implement this
|
||||
|
@ -1,25 +1,29 @@
|
||||
//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
|
||||
//! standalone executable.
|
||||
|
||||
use std::fs::File;
|
||||
use std::path::PathBuf;
|
||||
use std::fs::{self, File};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use std::thread::JoinHandle;
|
||||
|
||||
use cranelift_object::{ObjectBuilder, ObjectModule};
|
||||
use rustc_codegen_ssa::assert_module_sources::CguReuse;
|
||||
use rustc_codegen_ssa::back::link::ensure_removed;
|
||||
use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file;
|
||||
use rustc_codegen_ssa::base::determine_cgu_reuse;
|
||||
use rustc_codegen_ssa::errors as ssa_errors;
|
||||
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
|
||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_metadata::fs::copy_to_stdout;
|
||||
use rustc_metadata::EncodedMetadata;
|
||||
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
|
||||
use rustc_middle::mir::mono::{CodegenUnit, MonoItem};
|
||||
use rustc_session::config::{DebugInfo, OutputFilenames, OutputType};
|
||||
use rustc_session::config::{DebugInfo, OutFileName, OutputFilenames, OutputType};
|
||||
use rustc_session::Session;
|
||||
|
||||
use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken};
|
||||
use crate::debuginfo::TypeDebugContext;
|
||||
use crate::global_asm::GlobalAsmConfig;
|
||||
use crate::{prelude::*, BackendConfig};
|
||||
|
||||
@ -53,6 +57,7 @@ impl OngoingCodegen {
|
||||
pub(crate) fn join(
|
||||
self,
|
||||
sess: &Session,
|
||||
outputs: &OutputFilenames,
|
||||
backend_config: &BackendConfig,
|
||||
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
|
||||
let mut work_products = FxIndexMap::default();
|
||||
@ -110,19 +115,185 @@ impl OngoingCodegen {
|
||||
|
||||
sess.dcx().abort_if_errors();
|
||||
|
||||
(
|
||||
CodegenResults {
|
||||
modules,
|
||||
allocator_module: self.allocator_module,
|
||||
metadata_module: self.metadata_module,
|
||||
metadata: self.metadata,
|
||||
crate_info: self.crate_info,
|
||||
},
|
||||
work_products,
|
||||
)
|
||||
let codegen_results = CodegenResults {
|
||||
modules,
|
||||
allocator_module: self.allocator_module,
|
||||
metadata_module: self.metadata_module,
|
||||
metadata: self.metadata,
|
||||
crate_info: self.crate_info,
|
||||
};
|
||||
|
||||
produce_final_output_artifacts(sess, &codegen_results, outputs);
|
||||
|
||||
(codegen_results, work_products)
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from https://github.com/rust-lang/rust/blob/73476d49904751f8d90ce904e16dfbc278083d2c/compiler/rustc_codegen_ssa/src/back/write.rs#L547C1-L706C2
|
||||
fn produce_final_output_artifacts(
|
||||
sess: &Session,
|
||||
codegen_results: &CodegenResults,
|
||||
crate_output: &OutputFilenames,
|
||||
) {
|
||||
let user_wants_bitcode = false;
|
||||
let mut user_wants_objects = false;
|
||||
|
||||
// Produce final compile outputs.
|
||||
let copy_gracefully = |from: &Path, to: &OutFileName| match to {
|
||||
OutFileName::Stdout => {
|
||||
if let Err(e) = copy_to_stdout(from) {
|
||||
sess.dcx().emit_err(ssa_errors::CopyPath::new(from, to.as_path(), e));
|
||||
}
|
||||
}
|
||||
OutFileName::Real(path) => {
|
||||
if let Err(e) = fs::copy(from, path) {
|
||||
sess.dcx().emit_err(ssa_errors::CopyPath::new(from, path, e));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| {
|
||||
if codegen_results.modules.len() == 1 {
|
||||
// 1) Only one codegen unit. In this case it's no difficulty
|
||||
// to copy `foo.0.x` to `foo.x`.
|
||||
let module_name = Some(&codegen_results.modules[0].name[..]);
|
||||
let path = crate_output.temp_path(output_type, module_name);
|
||||
let output = crate_output.path(output_type);
|
||||
if !output_type.is_text_output() && output.is_tty() {
|
||||
sess.dcx()
|
||||
.emit_err(ssa_errors::BinaryOutputToTty { shorthand: output_type.shorthand() });
|
||||
} else {
|
||||
copy_gracefully(&path, &output);
|
||||
}
|
||||
if !sess.opts.cg.save_temps && !keep_numbered {
|
||||
// The user just wants `foo.x`, not `foo.#module-name#.x`.
|
||||
ensure_removed(sess.dcx(), &path);
|
||||
}
|
||||
} else {
|
||||
let extension = crate_output
|
||||
.temp_path(output_type, None)
|
||||
.extension()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
|
||||
if crate_output.outputs.contains_explicit_name(&output_type) {
|
||||
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
|
||||
// no good solution for this case, so warn the user.
|
||||
sess.dcx().emit_warn(ssa_errors::IgnoringEmitPath { extension });
|
||||
} else if crate_output.single_output_file.is_some() {
|
||||
// 3) Multiple codegen units, with `-o some_name`. We have
|
||||
// no good solution for this case, so warn the user.
|
||||
sess.dcx().emit_warn(ssa_errors::IgnoringOutput { extension });
|
||||
} else {
|
||||
// 4) Multiple codegen units, but no explicit name. We
|
||||
// just leave the `foo.0.x` files in place.
|
||||
// (We don't have to do any work in this case.)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Flag to indicate whether the user explicitly requested bitcode.
|
||||
// Otherwise, we produced it only as a temporary output, and will need
|
||||
// to get rid of it.
|
||||
for output_type in crate_output.outputs.keys() {
|
||||
match *output_type {
|
||||
OutputType::Bitcode => {
|
||||
// Cranelift doesn't have bitcode
|
||||
// user_wants_bitcode = true;
|
||||
// // Copy to .bc, but always keep the .0.bc. There is a later
|
||||
// // check to figure out if we should delete .0.bc files, or keep
|
||||
// // them for making an rlib.
|
||||
// copy_if_one_unit(OutputType::Bitcode, true);
|
||||
}
|
||||
OutputType::LlvmAssembly => {
|
||||
// Cranelift IR text already emitted during codegen
|
||||
// copy_if_one_unit(OutputType::LlvmAssembly, false);
|
||||
}
|
||||
OutputType::Assembly => {
|
||||
// Currently no support for emitting raw assembly files
|
||||
// copy_if_one_unit(OutputType::Assembly, false);
|
||||
}
|
||||
OutputType::Object => {
|
||||
user_wants_objects = true;
|
||||
copy_if_one_unit(OutputType::Object, true);
|
||||
}
|
||||
OutputType::Mir | OutputType::Metadata | OutputType::Exe | OutputType::DepInfo => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up unwanted temporary files.
|
||||
|
||||
// We create the following files by default:
|
||||
// - #crate#.#module-name#.bc
|
||||
// - #crate#.#module-name#.o
|
||||
// - #crate#.crate.metadata.bc
|
||||
// - #crate#.crate.metadata.o
|
||||
// - #crate#.o (linked from crate.##.o)
|
||||
// - #crate#.bc (copied from crate.##.bc)
|
||||
// We may create additional files if requested by the user (through
|
||||
// `-C save-temps` or `--emit=` flags).
|
||||
|
||||
if !sess.opts.cg.save_temps {
|
||||
// Remove the temporary .#module-name#.o objects. If the user didn't
|
||||
// explicitly request bitcode (with --emit=bc), and the bitcode is not
|
||||
// needed for building an rlib, then we must remove .#module-name#.bc as
|
||||
// well.
|
||||
|
||||
// Specific rules for keeping .#module-name#.bc:
|
||||
// - If the user requested bitcode (`user_wants_bitcode`), and
|
||||
// codegen_units > 1, then keep it.
|
||||
// - If the user requested bitcode but codegen_units == 1, then we
|
||||
// can toss .#module-name#.bc because we copied it to .bc earlier.
|
||||
// - If we're not building an rlib and the user didn't request
|
||||
// bitcode, then delete .#module-name#.bc.
|
||||
// If you change how this works, also update back::link::link_rlib,
|
||||
// where .#module-name#.bc files are (maybe) deleted after making an
|
||||
// rlib.
|
||||
let needs_crate_object = crate_output.outputs.contains_key(&OutputType::Exe);
|
||||
|
||||
let keep_numbered_bitcode = user_wants_bitcode && sess.codegen_units().as_usize() > 1;
|
||||
|
||||
let keep_numbered_objects =
|
||||
needs_crate_object || (user_wants_objects && sess.codegen_units().as_usize() > 1);
|
||||
|
||||
for module in codegen_results.modules.iter() {
|
||||
if let Some(ref path) = module.object {
|
||||
if !keep_numbered_objects {
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref path) = module.dwarf_object {
|
||||
if !keep_numbered_objects {
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref path) = module.bytecode {
|
||||
if !keep_numbered_bitcode {
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !user_wants_bitcode {
|
||||
if let Some(ref allocator_module) = codegen_results.allocator_module {
|
||||
if let Some(ref path) = allocator_module.bytecode {
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We leave the following files around by default:
|
||||
// - #crate#.o
|
||||
// - #crate#.crate.metadata.o
|
||||
// - #crate#.bc
|
||||
// These are used in linking steps and will be cleaned up afterward.
|
||||
}
|
||||
|
||||
fn make_module(sess: &Session, backend_config: &BackendConfig, name: String) -> ObjectModule {
|
||||
let isa = crate::build_isa(sess, backend_config);
|
||||
|
||||
@ -290,6 +461,7 @@ fn module_codegen(
|
||||
tcx.sess.opts.debuginfo != DebugInfo::None,
|
||||
cgu_name,
|
||||
);
|
||||
let mut type_dbg = TypeDebugContext::default();
|
||||
super::predefine_mono_items(tcx, &mut module, &mono_items);
|
||||
let mut codegened_functions = vec![];
|
||||
for (mono_item, _) in mono_items {
|
||||
@ -298,6 +470,7 @@ fn module_codegen(
|
||||
let codegened_function = crate::base::codegen_fn(
|
||||
tcx,
|
||||
&mut cx,
|
||||
&mut type_dbg,
|
||||
Function::new(),
|
||||
&mut module,
|
||||
inst,
|
||||
@ -305,7 +478,10 @@ fn module_codegen(
|
||||
codegened_functions.push(codegened_function);
|
||||
}
|
||||
MonoItem::Static(def_id) => {
|
||||
crate::constant::codegen_static(tcx, &mut module, def_id)
|
||||
let data_id = crate::constant::codegen_static(tcx, &mut module, def_id);
|
||||
if let Some(debug_context) = &mut cx.debug_context {
|
||||
debug_context.define_static(tcx, &mut type_dbg, def_id, data_id);
|
||||
}
|
||||
}
|
||||
MonoItem::GlobalAsm(item_id) => {
|
||||
crate::global_asm::codegen_global_asm_item(
|
||||
|
@ -12,6 +12,7 @@ use rustc_middle::mir::mono::MonoItem;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use crate::debuginfo::TypeDebugContext;
|
||||
use crate::{prelude::*, BackendConfig};
|
||||
use crate::{CodegenCx, CodegenMode};
|
||||
|
||||
@ -229,7 +230,14 @@ pub(crate) fn codegen_and_compile_fn<'tcx>(
|
||||
crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name));
|
||||
|
||||
let cached_func = std::mem::replace(&mut cached_context.func, Function::new());
|
||||
let codegened_func = crate::base::codegen_fn(tcx, cx, cached_func, module, instance);
|
||||
let codegened_func = crate::base::codegen_fn(
|
||||
tcx,
|
||||
cx,
|
||||
&mut TypeDebugContext::default(),
|
||||
cached_func,
|
||||
module,
|
||||
instance,
|
||||
);
|
||||
|
||||
crate::base::compile_fn(cx, cached_context, module, codegened_func);
|
||||
});
|
||||
|
@ -8,6 +8,7 @@ use std::sync::Arc;
|
||||
|
||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_hir::{InlineAsmOperand, ItemId};
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_session::config::{OutputFilenames, OutputType};
|
||||
use rustc_target::asm::InlineAsmArch;
|
||||
|
||||
@ -32,18 +33,27 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
|
||||
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: op_sp } => {
|
||||
match asm.operands[operand_idx].0 {
|
||||
InlineAsmOperand::Const { ref anon_const } => {
|
||||
let const_value =
|
||||
tcx.const_eval_poly(anon_const.def_id.to_def_id()).unwrap_or_else(
|
||||
|_| span_bug!(op_sp, "asm const cannot be resolved"),
|
||||
);
|
||||
let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
|
||||
let string = rustc_codegen_ssa::common::asm_const_to_str(
|
||||
tcx,
|
||||
op_sp,
|
||||
const_value,
|
||||
RevealAllLayoutCx(tcx).layout_of(ty),
|
||||
);
|
||||
global_asm.push_str(&string);
|
||||
match tcx.const_eval_poly(anon_const.def_id.to_def_id()) {
|
||||
Ok(const_value) => {
|
||||
let ty = tcx
|
||||
.typeck_body(anon_const.body)
|
||||
.node_type(anon_const.hir_id);
|
||||
let string = rustc_codegen_ssa::common::asm_const_to_str(
|
||||
tcx,
|
||||
op_sp,
|
||||
const_value,
|
||||
RevealAllLayoutCx(tcx).layout_of(ty),
|
||||
);
|
||||
global_asm.push_str(&string);
|
||||
}
|
||||
Err(ErrorHandled::Reported { .. }) => {
|
||||
// An error has already been reported and compilation is
|
||||
// guaranteed to fail if execution hits this path.
|
||||
}
|
||||
Err(ErrorHandled::TooGeneric(_)) => {
|
||||
span_bug!(op_sp, "asm const cannot be resolved; too generic");
|
||||
}
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::SymFn { anon_const } => {
|
||||
if cfg!(not(feature = "inline_asm_sym")) {
|
||||
|
@ -341,6 +341,8 @@ fn codegen_float_intrinsic_call<'tcx>(
|
||||
sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::roundevenf32 => ("roundevenf", 1, fx.tcx.types.f32, types::F32),
|
||||
sym::roundevenf64 => ("roundeven", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::nearbyintf32 => ("nearbyintf", 1, fx.tcx.types.f32, types::F32),
|
||||
sym::nearbyintf64 => ("nearbyint", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32),
|
||||
sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32),
|
||||
@ -392,6 +394,8 @@ fn codegen_float_intrinsic_call<'tcx>(
|
||||
| sym::ceilf64
|
||||
| sym::truncf32
|
||||
| sym::truncf64
|
||||
| sym::nearbyintf32
|
||||
| sym::nearbyintf64
|
||||
| sym::sqrtf32
|
||||
| sym::sqrtf64 => {
|
||||
let val = match intrinsic {
|
||||
@ -399,6 +403,7 @@ fn codegen_float_intrinsic_call<'tcx>(
|
||||
sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]),
|
||||
sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]),
|
||||
sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]),
|
||||
sym::nearbyintf32 | sym::nearbyintf64 => fx.bcx.ins().nearest(args[0]),
|
||||
sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
@ -148,7 +148,7 @@ impl CodegenCx {
|
||||
let unwind_context =
|
||||
UnwindContext::new(isa, matches!(backend_config.codegen_mode, CodegenMode::Aot));
|
||||
let debug_context = if debug_info && !tcx.sess.target.options.is_like_windows {
|
||||
Some(DebugContext::new(tcx, isa))
|
||||
Some(DebugContext::new(tcx, isa, cgu_name.as_str()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -233,12 +233,13 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
||||
&self,
|
||||
ongoing_codegen: Box<dyn Any>,
|
||||
sess: &Session,
|
||||
_outputs: &OutputFilenames,
|
||||
outputs: &OutputFilenames,
|
||||
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
|
||||
ongoing_codegen
|
||||
.downcast::<driver::aot::OngoingCodegen>()
|
||||
.unwrap()
|
||||
.join(sess, self.config.borrow().as_ref().unwrap())
|
||||
ongoing_codegen.downcast::<driver::aot::OngoingCodegen>().unwrap().join(
|
||||
sess,
|
||||
outputs,
|
||||
self.config.borrow().as_ref().unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
fn link(
|
||||
|
@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! See `rustc_codegen_ssa/src/meth.rs` for reference.
|
||||
|
||||
use crate::constant::data_id_for_alloc_id;
|
||||
use crate::constant::data_id_for_vtable;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) fn vtable_memflags() -> MemFlags {
|
||||
@ -92,12 +92,10 @@ pub(crate) fn get_vtable<'tcx>(
|
||||
ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
|
||||
) -> Value {
|
||||
let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref));
|
||||
let data_id =
|
||||
data_id_for_alloc_id(&mut fx.constants_cx, &mut *fx.module, alloc_id, Mutability::Not);
|
||||
let data_id = data_id_for_vtable(fx.tcx, &mut fx.constants_cx, fx.module, ty, trait_ref);
|
||||
let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func);
|
||||
if fx.clif_comments.enabled() {
|
||||
fx.add_comment(local_data_id, format!("vtable: {:?}", alloc_id));
|
||||
fx.add_comment(local_data_id, "vtable");
|
||||
}
|
||||
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user