diff --git a/src/cache/cache.rs b/src/cache/cache.rs index 688d2a9cc..218d2b87d 100644 --- a/src/cache/cache.rs +++ b/src/cache/cache.rs @@ -101,6 +101,8 @@ pub enum Cache { Hit(CacheRead), /// Result was not found in cache. Miss, + /// Do not cache the results of the compilation. + None, /// Cache entry should be ignored, force compilation. Recache, } @@ -110,6 +112,7 @@ impl fmt::Debug for Cache { match *self { Cache::Hit(_) => write!(f, "Cache::Hit(...)"), Cache::Miss => write!(f, "Cache::Miss"), + Cache::None => write!(f, "Cache::None"), Cache::Recache => write!(f, "Cache::Recache"), } } diff --git a/src/compiler/c.rs b/src/compiler/c.rs index 5af27d01a..71fc5e1eb 100644 --- a/src/compiler/c.rs +++ b/src/compiler/c.rs @@ -1165,24 +1165,14 @@ impl Compilation for CCompilation .. } = *self; - let (command, dist_command, cacheable) = compiler.generate_compile_commands( + compiler.generate_compile_commands( path_transformer, executable, parsed_args, cwd, env_vars, rewrite_includes_only, - )?; - - let force_no_cache = env_vars - .iter() - .any(|(k, _v)| k.as_os_str() == "SCCACHE_NO_CACHE"); - - if force_no_cache { - Ok((command, dist_command, Cacheable::No)) - } else { - Ok((command, dist_command, cacheable)) - } + ) } #[cfg(feature = "dist-client")] diff --git a/src/compiler/compiler.rs b/src/compiler/compiler.rs index 113663861..35434571c 100644 --- a/src/compiler/compiler.rs +++ b/src/compiler/compiler.rs @@ -459,7 +459,9 @@ where // If `ForceRecache` is enabled, we won't check the cache. let start = Instant::now(); let cache_status = async { - if cache_control == CacheControl::ForceRecache { + if cache_control == CacheControl::ForceNoCache { + Ok(Cache::None) + } else if cache_control == CacheControl::ForceRecache { Ok(Cache::Recache) } else { storage.get(&key).await @@ -519,6 +521,14 @@ where ); Ok(CacheLookupResult::Miss(MissType::Normal)) } + (Ok(Ok(Cache::None)), duration) => { + debug!( + "[{}]: Cache none in {}", + out_pretty, + fmt_duration_as_secs(&duration) + ); + Ok(CacheLookupResult::Miss(MissType::ForcedNoCache)) + } (Ok(Ok(Cache::Recache)), duration) => { debug!( "[{}]: Cache recache in {}", @@ -573,6 +583,15 @@ where ); return Ok((CompileResult::CompileFailed, compiler_result)); } + if miss_type == MissType::ForcedNoCache { + // Do not cache + debug!( + "[{}]: Compiled in {}, but not caching", + out_pretty, + fmt_duration_as_secs(&duration_compilation) + ); + return Ok((CompileResult::NotCached, compiler_result)); + } if cacheable != Cacheable::Yes { // Not cacheable debug!( @@ -991,6 +1010,8 @@ pub enum DistType { pub enum MissType { /// The compilation was not found in the cache, nothing more. Normal, + /// Do not cache the results of the compilation. + ForcedNoCache, /// Cache lookup was overridden, recompilation was forced. ForcedRecache, /// Cache took too long to respond. @@ -1021,6 +1042,8 @@ pub enum CompileResult { Duration, // Compilation time Pin> + Send>>, ), + /// Not in cache and do not cache the results of the compilation. + NotCached, /// Not in cache, but the compilation result was determined to be not cacheable. NotCacheable, /// Not in cache, but compilation failed. @@ -1045,6 +1068,7 @@ impl fmt::Debug for CompileResult { CompileResult::CacheMiss(ref m, ref dt, ref d, _) => { write!(f, "CompileResult::CacheMiss({:?}, {:?}, {:?}, _)", d, m, dt) } + CompileResult::NotCached => write!(f, "CompileResult::NotCached"), CompileResult::NotCacheable => write!(f, "CompileResult::NotCacheable"), CompileResult::CompileFailed => write!(f, "CompileResult::CompileFailed"), } @@ -1060,6 +1084,7 @@ impl PartialEq for CompileResult { (CompileResult::CacheMiss(m, dt, _, _), CompileResult::CacheMiss(n, dt2, _, _)) => { m == n && dt == dt2 } + (&CompileResult::NotCached, &CompileResult::NotCached) => true, (&CompileResult::NotCacheable, &CompileResult::NotCacheable) => true, (&CompileResult::CompileFailed, &CompileResult::CompileFailed) => true, _ => false, @@ -1079,6 +1104,8 @@ pub enum Cacheable { pub enum CacheControl { /// Default caching behavior. Default, + /// Do not cache the results of the compilation. + ForceNoCache, /// Ignore existing cache entries, force recompilation. ForceRecache, } diff --git a/src/compiler/rust.rs b/src/compiler/rust.rs index d26e3cac9..8aa7dfda3 100644 --- a/src/compiler/rust.rs +++ b/src/compiler/rust.rs @@ -1746,15 +1746,7 @@ impl Compilation for RustCompilation { }) })(); - let force_no_cache = env_vars - .iter() - .any(|(k, _v)| k.as_os_str() == "SCCACHE_NO_CACHE"); - - if force_no_cache { - Ok((CCompileCommand::new(command), dist_command, Cacheable::No)) - } else { - Ok((CCompileCommand::new(command), dist_command, Cacheable::Yes)) - } + Ok((CCompileCommand::new(command), dist_command, Cacheable::Yes)) } #[cfg(feature = "dist-client")] diff --git a/src/server.rs b/src/server.rs index 278221e2e..4a9a00c03 100644 --- a/src/server.rs +++ b/src/server.rs @@ -40,7 +40,7 @@ use serde::{Deserialize, Serialize}; use std::cell::Cell; use std::collections::{HashMap, HashSet}; use std::env; -use std::ffi::{OsStr, OsString}; +use std::ffi::OsString; use std::future::Future; use std::io::{self, Write}; use std::marker::Unpin; @@ -1320,11 +1320,13 @@ where ) -> Result { self.stats.lock().await.requests_executed += 1; - let force_recache = env_vars - .iter() - .any(|(k, _v)| k.as_os_str() == OsStr::new("SCCACHE_RECACHE")); + let force_recache = env_vars.iter().any(|(k, _v)| k == "SCCACHE_RECACHE"); - let cache_control = if force_recache { + let force_no_cache = env_vars.iter().any(|(k, _v)| k == "SCCACHE_NO_CACHE"); + + let cache_control = if force_no_cache { + CacheControl::ForceNoCache + } else if force_recache { CacheControl::ForceRecache } else { CacheControl::Default @@ -1389,6 +1391,7 @@ where } match miss_type { MissType::Normal => {} + MissType::ForcedNoCache => {} MissType::ForcedRecache => { stats.forced_recaches += 1; } @@ -1404,6 +1407,9 @@ where debug!("stats after compile result: {stats:?}"); cache_write = Some(future); } + CompileResult::NotCached => { + debug!("[{}]: compile result: not cached", out_pretty); + } CompileResult::NotCacheable => { debug!("compile result: not cacheable"); diff --git a/tests/system.rs b/tests/system.rs index be64a57f7..424a321c3 100644 --- a/tests/system.rs +++ b/tests/system.rs @@ -601,11 +601,11 @@ fn test_nvcc_cuda_compiles(compiler: &Compiler, tempdir: &Path) { assert_eq!(1, info.stats.compile_requests); assert_eq!(4, info.stats.requests_executed); assert_eq!(0, info.stats.cache_hits.all()); - assert_eq!(4, info.stats.cache_misses.all()); + assert_eq!(3, info.stats.cache_misses.all()); assert_eq!(&1, info.stats.cache_misses.get("CUDA").unwrap()); assert_eq!(&1, info.stats.cache_misses.get("PTX").unwrap()); assert_eq!(&1, info.stats.cache_misses.get("CUBIN").unwrap()); - assert_eq!(&1, info.stats.cache_misses.get("C/C++").unwrap()); + assert!(info.stats.cache_misses.get("C/C++").is_none()); let adv_cuda_key = adv_key_kind("cuda", compiler.name); let adv_ptx_key = adv_key_kind("ptx", compiler.name); let adv_cubin_key = adv_key_kind("cubin", compiler.name); @@ -637,14 +637,14 @@ fn test_nvcc_cuda_compiles(compiler: &Compiler, tempdir: &Path) { assert_eq!(2, info.stats.compile_requests); assert_eq!(5, info.stats.requests_executed); assert_eq!(1, info.stats.cache_hits.all()); - assert_eq!(4, info.stats.cache_misses.all()); + assert_eq!(3, info.stats.cache_misses.all()); assert_eq!(&1, info.stats.cache_hits.get("CUDA").unwrap()); assert!(info.stats.cache_hits.get("PTX").is_none()); assert!(info.stats.cache_hits.get("CUBIN").is_none()); assert_eq!(&1, info.stats.cache_misses.get("CUDA").unwrap()); assert_eq!(&1, info.stats.cache_misses.get("PTX").unwrap()); assert_eq!(&1, info.stats.cache_misses.get("CUBIN").unwrap()); - assert_eq!(&1, info.stats.cache_misses.get("C/C++").unwrap()); + assert!(info.stats.cache_misses.get("C/C++").is_none()); let adv_cuda_key = adv_key_kind("cuda", compiler.name); let adv_ptx_key = adv_key_kind("ptx", compiler.name); let adv_cubin_key = adv_key_kind("cubin", compiler.name); @@ -681,14 +681,14 @@ fn test_nvcc_cuda_compiles(compiler: &Compiler, tempdir: &Path) { assert_eq!(3, info.stats.compile_requests); assert_eq!(9, info.stats.requests_executed); assert_eq!(2, info.stats.cache_hits.all()); - assert_eq!(7, info.stats.cache_misses.all()); + assert_eq!(5, info.stats.cache_misses.all()); assert_eq!(&1, info.stats.cache_hits.get("CUDA").unwrap()); assert!(info.stats.cache_hits.get("PTX").is_none()); assert_eq!(&1, info.stats.cache_hits.get("CUBIN").unwrap()); assert_eq!(&2, info.stats.cache_misses.get("CUDA").unwrap()); assert_eq!(&2, info.stats.cache_misses.get("PTX").unwrap()); assert_eq!(&1, info.stats.cache_misses.get("CUBIN").unwrap()); - assert_eq!(&2, info.stats.cache_misses.get("C/C++").unwrap()); + assert!(info.stats.cache_misses.get("C/C++").is_none()); let adv_cuda_key = adv_key_kind("cuda", compiler.name); let adv_ptx_key = adv_key_kind("ptx", compiler.name); let adv_cubin_key = adv_key_kind("cubin", compiler.name); @@ -723,14 +723,14 @@ fn test_nvcc_cuda_compiles(compiler: &Compiler, tempdir: &Path) { assert_eq!(4, info.stats.compile_requests); assert_eq!(11, info.stats.requests_executed); assert_eq!(3, info.stats.cache_hits.all()); - assert_eq!(8, info.stats.cache_misses.all()); + assert_eq!(6, info.stats.cache_misses.all()); assert_eq!(&1, info.stats.cache_hits.get("CUDA").unwrap()); assert_eq!(&1, info.stats.cache_hits.get("PTX").unwrap()); assert_eq!(&1, info.stats.cache_hits.get("CUBIN").unwrap()); assert_eq!(&3, info.stats.cache_misses.get("CUDA").unwrap()); assert_eq!(&2, info.stats.cache_misses.get("PTX").unwrap()); assert_eq!(&1, info.stats.cache_misses.get("CUBIN").unwrap()); - assert_eq!(&2, info.stats.cache_misses.get("C/C++").unwrap()); + assert!(info.stats.cache_misses.get("C/C++").is_none()); let adv_cuda_key = adv_key_kind("cuda", compiler.name); let adv_ptx_key = adv_key_kind("ptx", compiler.name); let adv_cubin_key = adv_key_kind("cubin", compiler.name); @@ -765,14 +765,14 @@ fn test_nvcc_cuda_compiles(compiler: &Compiler, tempdir: &Path) { assert_eq!(5, info.stats.compile_requests); assert_eq!(14, info.stats.requests_executed); assert_eq!(5, info.stats.cache_hits.all()); - assert_eq!(9, info.stats.cache_misses.all()); + assert_eq!(7, info.stats.cache_misses.all()); assert_eq!(&1, info.stats.cache_hits.get("CUDA").unwrap()); assert_eq!(&2, info.stats.cache_hits.get("PTX").unwrap()); assert_eq!(&2, info.stats.cache_hits.get("CUBIN").unwrap()); assert_eq!(&4, info.stats.cache_misses.get("CUDA").unwrap()); assert_eq!(&2, info.stats.cache_misses.get("PTX").unwrap()); assert_eq!(&1, info.stats.cache_misses.get("CUBIN").unwrap()); - assert_eq!(&2, info.stats.cache_misses.get("C/C++").unwrap()); + assert!(info.stats.cache_misses.get("C/C++").is_none()); let adv_cuda_key = adv_key_kind("cuda", compiler.name); let adv_ptx_key = adv_key_kind("ptx", compiler.name); let adv_cubin_key = adv_key_kind("cubin", compiler.name); @@ -831,7 +831,6 @@ fn test_nvcc_proper_lang_stat_tracking(compiler: Compiler, tempdir: &Path) { .args(compile_cmdline(name, &exe, INPUT, OUTPUT, Vec::new())) .current_dir(tempdir) .envs(env_vars.clone()) - .env("SCCACHE_LOG", "trace") .assert() .success(); fs::remove_file(&out_file).unwrap(); @@ -849,11 +848,11 @@ fn test_nvcc_proper_lang_stat_tracking(compiler: Compiler, tempdir: &Path) { assert_eq!(4, info.stats.compile_requests); assert_eq!(8, info.stats.requests_executed); assert_eq!(3, info.stats.cache_hits.all()); - assert_eq!(5, info.stats.cache_misses.all()); + assert_eq!(3, info.stats.cache_misses.all()); assert_eq!(&1, info.stats.cache_hits.get("C/C++").unwrap()); assert_eq!(&1, info.stats.cache_hits.get("CUDA").unwrap()); assert_eq!(&1, info.stats.cache_hits.get("CUBIN").unwrap()); - assert_eq!(&3, info.stats.cache_misses.get("C/C++").unwrap()); + assert_eq!(&1, info.stats.cache_misses.get("C/C++").unwrap()); assert_eq!(&1, info.stats.cache_misses.get("CUDA").unwrap()); assert_eq!(&1, info.stats.cache_misses.get("PTX").unwrap()); });