From 3c39c2fbd4f367502fc036d658c0e2ccb30072a9 Mon Sep 17 00:00:00 2001 From: pmq_2 Date: Sat, 18 Oct 2025 01:05:27 -0500 Subject: [PATCH 1/5] threshold warning + notify how much constant memory is used + constant memory spill warnings --- crates/rustc_codegen_nvvm/src/context.rs | 54 ++++++++++++++++++++---- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/crates/rustc_codegen_nvvm/src/context.rs b/crates/rustc_codegen_nvvm/src/context.rs index ab89818f..92315acc 100644 --- a/crates/rustc_codegen_nvvm/src/context.rs +++ b/crates/rustc_codegen_nvvm/src/context.rs @@ -44,6 +44,9 @@ use tracing::{debug, trace}; /// const CONSTANT_MEMORY_SIZE_LIMIT_BYTES: u64 = 64 * 1024; +/// Threshold for warning when approaching 80% of constant memory limit +const CONSTANT_MEMORY_WARNING_THRESHOLD_BYTES: u64 = (CONSTANT_MEMORY_SIZE_LIMIT_BYTES * 80) / 100; + pub(crate) struct CodegenCx<'ll, 'tcx> { pub tcx: TyCtxt<'tcx>, @@ -104,6 +107,9 @@ pub(crate) struct CodegenCx<'ll, 'tcx> { pub codegen_args: CodegenArgs, // the value of the last call instruction. Needed for return type remapping. pub last_call_llfn: Cell>, + + /// Tracks cumulative constant memory usage in bytes for compile-time diagnostics + constant_memory_usage: Cell, } impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { @@ -174,6 +180,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { dbg_cx, codegen_args: CodegenArgs::from_session(tcx.sess()), last_call_llfn: Cell::new(None), + constant_memory_usage: Cell::new(0), }; cx.build_intrinsics_map(); cx @@ -281,16 +288,47 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { // static and many small ones, you might want the small ones to all be // in constant memory or just the big one depending on your workload. let layout = self.layout_of(ty); - if layout.size.bytes() > CONSTANT_MEMORY_SIZE_LIMIT_BYTES { + let size_bytes = layout.size.bytes(); + let current_usage = self.constant_memory_usage.get(); + let new_usage = current_usage + size_bytes; + + // Check if this single static is too large for constant memory + if size_bytes > CONSTANT_MEMORY_SIZE_LIMIT_BYTES { self.tcx.sess.dcx().warn(format!( - "static `{instance}` exceeds the constant memory limit; placing in global memory (performance may be reduced)" - )); - // Place instance in global memory if it is too big for constant memory. - AddressSpace(1) - } else { - // Place instance in constant memory if it fits. - AddressSpace(4) + "static `{instance}` is {size_bytes} bytes, exceeds the constant memory limit of {} bytes; placing in global memory (performance may be reduced)", + CONSTANT_MEMORY_SIZE_LIMIT_BYTES + )); + return AddressSpace(1); + } + + // Check if adding this static would exceed the cumulative limit + if new_usage > CONSTANT_MEMORY_SIZE_LIMIT_BYTES { + self.tcx.sess.dcx().emit_err(format!( + "cannot place static `{instance}` ({size_bytes} bytes) in constant memory: \ + cumulative constant memory usage would be {new_usage} bytes, exceeding the {} byte limit. \ + Current usage: {current_usage} bytes. \ + Consider: (1) using `#[cuda_std::address_space(global)]` on less frequently accessed statics, \ + (2) reducing static data sizes, or (3) disabling automatic constant memory placement", + CONSTANT_MEMORY_SIZE_LIMIT_BYTES + )); + return AddressSpace(1); } + + // If successfully placed in constant memory: update cumulative usage + self.constant_memory_usage.set(new_usage); + + // If approaching the threshold: warns + if new_usage > CONSTANT_MEMORY_WARNING_THRESHOLD_BYTES && + current_usage <= CONSTANT_MEMORY_WARNING_THRESHOLD_BYTES { + self.tcx.sess.dcx().warn(format!( + "constant memory usage is approaching the limit: {new_usage} / {} bytes ({:.1}% used)", + CONSTANT_MEMORY_SIZE_LIMIT_BYTES, + (new_usage as f64 / CONSTANT_MEMORY_SIZE_LIMIT_BYTES as f64) * 100.0 + )); + } + + trace!("Placing static `{instance}` ({size_bytes} bytes) in constant memory. Total usage: {new_usage} bytes"); + AddressSpace(4) } } else { AddressSpace::ZERO From 25d8ac1a00cd73212341db9afab0e1b2f2ab693f Mon Sep 17 00:00:00 2001 From: pmq_2 Date: Mon, 20 Oct 2025 22:45:51 -0500 Subject: [PATCH 2/5] minor rustfmt issue --- crates/rustc_codegen_nvvm/src/context.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/rustc_codegen_nvvm/src/context.rs b/crates/rustc_codegen_nvvm/src/context.rs index 92315acc..582375dc 100644 --- a/crates/rustc_codegen_nvvm/src/context.rs +++ b/crates/rustc_codegen_nvvm/src/context.rs @@ -303,12 +303,12 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { // Check if adding this static would exceed the cumulative limit if new_usage > CONSTANT_MEMORY_SIZE_LIMIT_BYTES { - self.tcx.sess.dcx().emit_err(format!( + self.tcx.sess.dcx().err(format!( "cannot place static `{instance}` ({size_bytes} bytes) in constant memory: \ - cumulative constant memory usage would be {new_usage} bytes, exceeding the {} byte limit. \ - Current usage: {current_usage} bytes. \ - Consider: (1) using `#[cuda_std::address_space(global)]` on less frequently accessed statics, \ - (2) reducing static data sizes, or (3) disabling automatic constant memory placement", + cumulative constant memory usage would be {new_usage} bytes, exceeding the {} byte limit. \ + Current usage: {current_usage} bytes. \ + Consider: (1) using `#[cuda_std::address_space(global)]` on less frequently accessed statics, \ + (2) reducing static data sizes, or (3) disabling automatic constant memory placement", CONSTANT_MEMORY_SIZE_LIMIT_BYTES )); return AddressSpace(1); @@ -318,8 +318,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { self.constant_memory_usage.set(new_usage); // If approaching the threshold: warns - if new_usage > CONSTANT_MEMORY_WARNING_THRESHOLD_BYTES && - current_usage <= CONSTANT_MEMORY_WARNING_THRESHOLD_BYTES { + if new_usage > CONSTANT_MEMORY_WARNING_THRESHOLD_BYTES + && current_usage <= CONSTANT_MEMORY_WARNING_THRESHOLD_BYTES + { self.tcx.sess.dcx().warn(format!( "constant memory usage is approaching the limit: {new_usage} / {} bytes ({:.1}% used)", CONSTANT_MEMORY_SIZE_LIMIT_BYTES, @@ -327,7 +328,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { )); } - trace!("Placing static `{instance}` ({size_bytes} bytes) in constant memory. Total usage: {new_usage} bytes"); + trace!( + "Placing static `{instance}` ({size_bytes} bytes) in constant memory. Total usage: {new_usage} bytes" + ); AddressSpace(4) } } else { From b48988dc9a42406e8017beb15edb615608872ab8 Mon Sep 17 00:00:00 2001 From: Quang Pham Date: Wed, 22 Oct 2025 15:08:49 -0500 Subject: [PATCH 3/5] stop compilation when static memory exceeds limits + add hints --- crates/rustc_codegen_nvvm/src/context.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/rustc_codegen_nvvm/src/context.rs b/crates/rustc_codegen_nvvm/src/context.rs index 582375dc..53e2208a 100644 --- a/crates/rustc_codegen_nvvm/src/context.rs +++ b/crates/rustc_codegen_nvvm/src/context.rs @@ -303,15 +303,17 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { // Check if adding this static would exceed the cumulative limit if new_usage > CONSTANT_MEMORY_SIZE_LIMIT_BYTES { - self.tcx.sess.dcx().err(format!( + self.fatal(format!( "cannot place static `{instance}` ({size_bytes} bytes) in constant memory: \ cumulative constant memory usage would be {new_usage} bytes, exceeding the {} byte limit. \ Current usage: {current_usage} bytes. \ - Consider: (1) using `#[cuda_std::address_space(global)]` on less frequently accessed statics, \ - (2) reducing static data sizes, or (3) disabling automatic constant memory placement", + \n\ + = help: use `#[cuda_std::address_space(global)]` on less frequently accessed statics\n\ + = help: reducing static data size\n\ + = help: disabling automatic constant memory placement by calling `.use_constant_memory_space(false)` \ + on your `CudaBuilder` in build.rs", CONSTANT_MEMORY_SIZE_LIMIT_BYTES )); - return AddressSpace(1); } // If successfully placed in constant memory: update cumulative usage From d841974a67976d74b915c5f0e8f86cf173642128 Mon Sep 17 00:00:00 2001 From: Quang Pham Date: Thu, 23 Oct 2025 20:42:09 -0500 Subject: [PATCH 4/5] use error message api --- crates/rustc_codegen_nvvm/src/context.rs | 80 ++++++++++++++++++------ 1 file changed, 62 insertions(+), 18 deletions(-) diff --git a/crates/rustc_codegen_nvvm/src/context.rs b/crates/rustc_codegen_nvvm/src/context.rs index 53e2208a..a5f2afd8 100644 --- a/crates/rustc_codegen_nvvm/src/context.rs +++ b/crates/rustc_codegen_nvvm/src/context.rs @@ -294,26 +294,54 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { // Check if this single static is too large for constant memory if size_bytes > CONSTANT_MEMORY_SIZE_LIMIT_BYTES { - self.tcx.sess.dcx().warn(format!( - "static `{instance}` is {size_bytes} bytes, exceeds the constant memory limit of {} bytes; placing in global memory (performance may be reduced)", - CONSTANT_MEMORY_SIZE_LIMIT_BYTES - )); + let def_id = instance.def_id(); + let span = self.tcx.def_span(def_id); + let mut diag = self.tcx.sess.dcx().struct_span_warn( + span, + format!( + "static `{instance}` is {size_bytes} bytes, exceeds the constant memory limit of {} bytes", + CONSTANT_MEMORY_SIZE_LIMIT_BYTES + ), + ); + diag.span_label(span, "static exceeds constant memory limit"); + diag.note("placing in global memory (performance may be reduced)"); + diag.help("use `#[cuda_std::address_space(global)]` to explicitly place this static in global memory"); + diag.emit(); return AddressSpace(1); } // Check if adding this static would exceed the cumulative limit if new_usage > CONSTANT_MEMORY_SIZE_LIMIT_BYTES { - self.fatal(format!( - "cannot place static `{instance}` ({size_bytes} bytes) in constant memory: \ - cumulative constant memory usage would be {new_usage} bytes, exceeding the {} byte limit. \ - Current usage: {current_usage} bytes. \ - \n\ - = help: use `#[cuda_std::address_space(global)]` on less frequently accessed statics\n\ - = help: reducing static data size\n\ - = help: disabling automatic constant memory placement by calling `.use_constant_memory_space(false)` \ - on your `CudaBuilder` in build.rs", - CONSTANT_MEMORY_SIZE_LIMIT_BYTES + let def_id = instance.def_id(); + let span = self.tcx.def_span(def_id); + let mut diag = self.tcx.sess.dcx().struct_span_err( + span, + format!( + "cannot place static `{instance}` ({size_bytes} bytes) in constant memory: \ + cumulative constant memory usage would be {new_usage} bytes, exceeding the {} byte limit", + CONSTANT_MEMORY_SIZE_LIMIT_BYTES + ), + ); + diag.span_label( + span, + format!( + "this static would cause total usage to exceed {} bytes", + CONSTANT_MEMORY_SIZE_LIMIT_BYTES + ), + ); + diag.note(format!( + "current constant memory usage: {current_usage} bytes" )); + diag.note(format!("static size: {size_bytes} bytes")); + diag.note(format!("would result in: {new_usage} bytes total")); + + diag.help("move this or other statics to global memory using `#[cuda_std::address_space(global)]`"); + diag.help("reduce the total size of static data"); + diag.help("disable automatic constant memory placement by setting `.use_constant_memory_space(false)` on `CudaBuilder` in build.rs"); + + diag.emit(); + self.tcx.sess.dcx().abort_if_errors(); + unreachable!() } // If successfully placed in constant memory: update cumulative usage @@ -323,11 +351,27 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { if new_usage > CONSTANT_MEMORY_WARNING_THRESHOLD_BYTES && current_usage <= CONSTANT_MEMORY_WARNING_THRESHOLD_BYTES { - self.tcx.sess.dcx().warn(format!( - "constant memory usage is approaching the limit: {new_usage} / {} bytes ({:.1}% used)", - CONSTANT_MEMORY_SIZE_LIMIT_BYTES, - (new_usage as f64 / CONSTANT_MEMORY_SIZE_LIMIT_BYTES as f64) * 100.0 + let def_id = instance.def_id(); + let span = self.tcx.def_span(def_id); + let usage_percent = + (new_usage as f64 / CONSTANT_MEMORY_SIZE_LIMIT_BYTES as f64) * 100.0; + let mut diag = self.tcx.sess.dcx().struct_span_warn( + span, + format!( + "constant memory usage is approaching the limit: {new_usage} / {} bytes ({usage_percent:.1}% used)", + CONSTANT_MEMORY_SIZE_LIMIT_BYTES + ), + ); + diag.span_label( + span, + "this placement brought you over 80% of constant memory capacity", + ); + diag.note(format!( + "only {} bytes of constant memory remain", + CONSTANT_MEMORY_SIZE_LIMIT_BYTES - new_usage )); + diag.help("to prevent constant memory overflow, consider moving some statics to global memory using `#[cuda_std::address_space(global)]`"); + diag.emit(); } trace!( From 91170fbeea6300f49d999edac80b988114ec2e22 Mon Sep 17 00:00:00 2001 From: Quang Pham Date: Wed, 29 Oct 2025 00:32:40 -0500 Subject: [PATCH 5/5] add missing --use-constant-memory-space flag --- crates/cuda_builder/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/cuda_builder/src/lib.rs b/crates/cuda_builder/src/lib.rs index 8dae443c..47df458d 100644 --- a/crates/cuda_builder/src/lib.rs +++ b/crates/cuda_builder/src/lib.rs @@ -761,6 +761,10 @@ fn invoke_rustc(builder: &CudaBuilder) -> Result { llvm_args.push("--override-libm".to_string()); } + if builder.use_constant_memory_space { + llvm_args.push("--use-constant-memory-space".to_string()); + } + if let Some(path) = &builder.final_module_path { llvm_args.push("--final-module-path".to_string()); llvm_args.push(path.to_str().unwrap().to_string());