Skip to content

Commit 679d82c

Browse files
authored
Gate accumulator feature behind a feature flag (#946)
1 parent f303b6d commit 679d82c

25 files changed

+215
-89
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,10 @@ jobs:
5555
run: cargo clippy --workspace --all-targets -- -D warnings
5656
- name: Test
5757
run: cargo nextest run --workspace --all-targets --no-fail-fast
58-
- name: Test Manual Registration
58+
- name: Test Manual Registration / no-default-features
5959
run: cargo nextest run --workspace --tests --no-fail-fast --no-default-features --features macros
6060
- name: Test docs
6161
run: cargo test --workspace --doc
62-
- name: Check (without default features)
63-
run: cargo check --workspace --no-default-features
6462

6563
miri:
6664
name: Miri

Cargo.toml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ thin-vec = "0.2.13"
3838
shuttle = { version = "0.8.0", optional = true }
3939

4040
[features]
41-
default = ["salsa_unstable", "rayon", "macros", "inventory"]
41+
default = ["salsa_unstable", "rayon", "macros", "inventory", "accumulator"]
4242
inventory = ["dep:inventory"]
4343
shuttle = ["dep:shuttle"]
44+
accumulator = ["salsa-macro-rules/accumulator"]
4445
# FIXME: remove `salsa_unstable` before 1.0.
4546
salsa_unstable = []
4647
macros = ["dep:salsa-macros"]
@@ -82,11 +83,20 @@ harness = false
8283
[[bench]]
8384
name = "accumulator"
8485
harness = false
86+
required-features = ["accumulator"]
8587

8688
[[bench]]
8789
name = "dataflow"
8890
harness = false
8991

92+
[[example]]
93+
name = "lazy-input"
94+
required-features = ["accumulator"]
95+
96+
[[example]]
97+
name = "calc"
98+
required-features = ["accumulator"]
99+
90100
[workspace]
91101
members = ["components/salsa-macro-rules", "components/salsa-macros"]
92102

components/salsa-macro-rules/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ rust-version.workspace = true
99
description = "Declarative macros for the salsa crate"
1010

1111
[dependencies]
12+
13+
[features]
14+
accumulator = []
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#[cfg(feature = "accumulator")]
2+
#[macro_export]
3+
macro_rules! gate_accumulated {
4+
($($body:tt)*) => {
5+
$($body)*
6+
};
7+
}
8+
9+
#[cfg(not(feature = "accumulator"))]
10+
#[macro_export]
11+
macro_rules! gate_accumulated {
12+
($($body:tt)*) => {};
13+
}

components/salsa-macro-rules/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
//! from a submodule is to use multiple crates, hence the existence
1313
//! of this crate.
1414
15+
mod gate_accumulated;
1516
mod macro_if;
1617
mod maybe_backdate;
1718
mod maybe_default;
1819
mod return_mode;
20+
#[cfg(feature = "accumulator")]
1921
mod setup_accumulator_impl;
2022
mod setup_input_struct;
2123
mod setup_interned_struct;

components/salsa-macro-rules/src/setup_tracked_fn.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -343,21 +343,23 @@ macro_rules! setup_tracked_fn {
343343

344344
#[allow(non_local_definitions)]
345345
impl $fn_name {
346-
pub fn accumulated<$db_lt, A: salsa::Accumulator>(
347-
$db: &$db_lt dyn $Db,
348-
$($input_id: $interned_input_ty,)*
349-
) -> Vec<&$db_lt A> {
350-
use salsa::plumbing as $zalsa;
351-
let key = $zalsa::macro_if! {
352-
if $needs_interner {{
353-
let (zalsa, zalsa_local) = $db.zalsas();
354-
$Configuration::intern_ingredient($db).intern_id(zalsa, zalsa_local, ($($input_id),*), |_, data| data)
355-
}} else {
356-
$zalsa::AsId::as_id(&($($input_id),*))
357-
}
358-
};
346+
$zalsa::gate_accumulated! {
347+
pub fn accumulated<$db_lt, A: salsa::Accumulator>(
348+
$db: &$db_lt dyn $Db,
349+
$($input_id: $interned_input_ty,)*
350+
) -> Vec<&$db_lt A> {
351+
use salsa::plumbing as $zalsa;
352+
let key = $zalsa::macro_if! {
353+
if $needs_interner {{
354+
let (zalsa, zalsa_local) = $db.zalsas();
355+
$Configuration::intern_ingredient($db).intern_id(zalsa, zalsa_local, ($($input_id),*), |_, data| data)
356+
}} else {
357+
$zalsa::AsId::as_id(&($($input_id),*))
358+
}
359+
};
359360

360-
$Configuration::fn_ingredient($db).accumulated_by::<A>($db, key)
361+
$Configuration::fn_ingredient($db).accumulated_by::<A>($db, key)
362+
}
361363
}
362364

363365
$zalsa::macro_if! { $is_specifiable =>

src/active_query.rs

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use std::{fmt, mem, ops};
22

3-
use crate::accumulator::accumulated_map::{
4-
AccumulatedMap, AtomicInputAccumulatedValues, InputAccumulatedValues,
3+
#[cfg(feature = "accumulator")]
4+
use crate::accumulator::{
5+
accumulated_map::{AccumulatedMap, AtomicInputAccumulatedValues, InputAccumulatedValues},
6+
Accumulator,
57
};
68
use crate::cycle::{CycleHeads, IterationCount};
79
use crate::durability::Durability;
@@ -11,7 +13,7 @@ use crate::runtime::Stamp;
1113
use crate::sync::atomic::AtomicBool;
1214
use crate::tracked_struct::{Disambiguator, DisambiguatorMap, IdentityHash, IdentityMap};
1315
use crate::zalsa_local::{QueryEdge, QueryOrigin, QueryRevisions, QueryRevisionsExtra};
14-
use crate::{Accumulator, IngredientIndex, Revision};
16+
use crate::Revision;
1517

1618
#[derive(Debug)]
1719
pub(crate) struct ActiveQuery {
@@ -51,10 +53,12 @@ pub(crate) struct ActiveQuery {
5153

5254
/// Stores the values accumulated to the given ingredient.
5355
/// The type of accumulated value is erased but known to the ingredient.
56+
#[cfg(feature = "accumulator")]
5457
accumulated: AccumulatedMap,
5558

5659
/// [`InputAccumulatedValues::Empty`] if any input read during the query's execution
5760
/// has any accumulated values.
61+
#[cfg(feature = "accumulator")]
5862
accumulated_inputs: InputAccumulatedValues,
5963

6064
/// Provisional cycle results that this query depends on.
@@ -84,18 +88,21 @@ impl ActiveQuery {
8488
input: DatabaseKeyIndex,
8589
durability: Durability,
8690
changed_at: Revision,
87-
has_accumulated: bool,
88-
accumulated_inputs: &AtomicInputAccumulatedValues,
8991
cycle_heads: &CycleHeads,
92+
#[cfg(feature = "accumulator")] has_accumulated: bool,
93+
#[cfg(feature = "accumulator")] accumulated_inputs: &AtomicInputAccumulatedValues,
9094
) {
9195
self.durability = self.durability.min(durability);
9296
self.changed_at = self.changed_at.max(changed_at);
9397
self.input_outputs.insert(QueryEdge::input(input));
94-
self.accumulated_inputs = self.accumulated_inputs.or_else(|| match has_accumulated {
95-
true => InputAccumulatedValues::Any,
96-
false => accumulated_inputs.load(),
97-
});
9898
self.cycle_heads.extend(cycle_heads);
99+
#[cfg(feature = "accumulator")]
100+
{
101+
self.accumulated_inputs = self.accumulated_inputs.or_else(|| match has_accumulated {
102+
true => InputAccumulatedValues::Any,
103+
false => accumulated_inputs.load(),
104+
});
105+
}
99106
}
100107

101108
pub(super) fn add_read_simple(
@@ -121,7 +128,8 @@ impl ActiveQuery {
121128
self.changed_at = self.changed_at.max(revision);
122129
}
123130

124-
pub(super) fn accumulate(&mut self, index: IngredientIndex, value: impl Accumulator) {
131+
#[cfg(feature = "accumulator")]
132+
pub(super) fn accumulate(&mut self, index: crate::IngredientIndex, value: impl Accumulator) {
125133
self.accumulated.accumulate(index, value);
126134
}
127135

@@ -169,10 +177,12 @@ impl ActiveQuery {
169177
untracked_read: false,
170178
disambiguator_map: Default::default(),
171179
tracked_struct_ids: Default::default(),
172-
accumulated: Default::default(),
173-
accumulated_inputs: Default::default(),
174180
cycle_heads: Default::default(),
175181
iteration_count,
182+
#[cfg(feature = "accumulator")]
183+
accumulated: Default::default(),
184+
#[cfg(feature = "accumulator")]
185+
accumulated_inputs: Default::default(),
176186
}
177187
}
178188

@@ -185,10 +195,12 @@ impl ActiveQuery {
185195
untracked_read,
186196
ref mut disambiguator_map,
187197
ref mut tracked_struct_ids,
188-
ref mut accumulated,
189-
accumulated_inputs,
190198
ref mut cycle_heads,
191199
iteration_count,
200+
#[cfg(feature = "accumulator")]
201+
ref mut accumulated,
202+
#[cfg(feature = "accumulator")]
203+
accumulated_inputs,
192204
} = self;
193205

194206
let origin = if untracked_read {
@@ -198,19 +210,22 @@ impl ActiveQuery {
198210
};
199211
disambiguator_map.clear();
200212

213+
#[cfg(feature = "accumulator")]
214+
let accumulated_inputs = AtomicInputAccumulatedValues::new(accumulated_inputs);
201215
let verified_final = cycle_heads.is_empty();
202216
let extra = QueryRevisionsExtra::new(
217+
#[cfg(feature = "accumulator")]
203218
mem::take(accumulated),
204219
mem::take(tracked_struct_ids),
205220
mem::take(cycle_heads),
206221
iteration_count,
207222
);
208-
let accumulated_inputs = AtomicInputAccumulatedValues::new(accumulated_inputs);
209223

210224
QueryRevisions {
211225
changed_at,
212226
durability,
213227
origin,
228+
#[cfg(feature = "accumulator")]
214229
accumulated_inputs,
215230
verified_final: AtomicBool::new(verified_final),
216231
extra,
@@ -226,17 +241,20 @@ impl ActiveQuery {
226241
untracked_read: _,
227242
disambiguator_map,
228243
tracked_struct_ids,
229-
accumulated,
230-
accumulated_inputs: _,
231244
cycle_heads,
232245
iteration_count,
246+
#[cfg(feature = "accumulator")]
247+
accumulated,
248+
#[cfg(feature = "accumulator")]
249+
accumulated_inputs: _,
233250
} = self;
234251
input_outputs.clear();
235252
disambiguator_map.clear();
236253
tracked_struct_ids.clear();
237-
accumulated.clear();
238254
*cycle_heads = Default::default();
239255
*iteration_count = IterationCount::initial();
256+
#[cfg(feature = "accumulator")]
257+
accumulated.clear();
240258
}
241259

242260
fn reset_for(
@@ -252,16 +270,17 @@ impl ActiveQuery {
252270
untracked_read,
253271
disambiguator_map,
254272
tracked_struct_ids,
255-
accumulated,
256-
accumulated_inputs,
257273
cycle_heads,
258274
iteration_count,
275+
#[cfg(feature = "accumulator")]
276+
accumulated,
277+
#[cfg(feature = "accumulator")]
278+
accumulated_inputs,
259279
} = self;
260280
*database_key_index = new_database_key_index;
261281
*durability = Durability::MAX;
262282
*changed_at = Revision::start();
263283
*untracked_read = false;
264-
*accumulated_inputs = Default::default();
265284
*iteration_count = new_iteration_count;
266285
debug_assert!(
267286
input_outputs.is_empty(),
@@ -279,10 +298,14 @@ impl ActiveQuery {
279298
cycle_heads.is_empty(),
280299
"`ActiveQuery::clear` or `ActiveQuery::into_revisions` should've been called"
281300
);
282-
debug_assert!(
283-
accumulated.is_empty(),
284-
"`ActiveQuery::clear` or `ActiveQuery::into_revisions` should've been called"
285-
);
301+
#[cfg(feature = "accumulator")]
302+
{
303+
*accumulated_inputs = Default::default();
304+
debug_assert!(
305+
accumulated.is_empty(),
306+
"`ActiveQuery::clear` or `ActiveQuery::into_revisions` should've been called"
307+
);
308+
}
286309
}
287310
}
288311

src/function.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use std::sync::atomic::Ordering;
66
use std::sync::OnceLock;
77
pub(crate) use sync::SyncGuard;
88

9-
use crate::accumulator::accumulated_map::{AccumulatedMap, InputAccumulatedValues};
109
use crate::cycle::{
1110
empty_cycle_heads, CycleHeads, CycleRecoveryAction, CycleRecoveryStrategy, ProvisionalStatus,
1211
};
@@ -25,6 +24,7 @@ use crate::zalsa::{IngredientIndex, MemoIngredientIndex, Zalsa};
2524
use crate::zalsa_local::QueryOriginRef;
2625
use crate::{Id, Revision};
2726

27+
#[cfg(feature = "accumulator")]
2828
mod accumulated;
2929
mod backdate;
3030
mod delete;
@@ -371,11 +371,15 @@ where
371371
C::CYCLE_STRATEGY
372372
}
373373

374+
#[cfg(feature = "accumulator")]
374375
unsafe fn accumulated<'db>(
375376
&'db self,
376377
db: RawDatabase<'db>,
377378
key_index: Id,
378-
) -> (Option<&'db AccumulatedMap>, InputAccumulatedValues) {
379+
) -> (
380+
Option<&'db crate::accumulator::accumulated_map::AccumulatedMap>,
381+
crate::accumulator::accumulated_map::InputAccumulatedValues,
382+
) {
379383
// SAFETY: The `db` belongs to the ingredient as per caller invariant
380384
let db = unsafe { self.view_caster().downcast_unchecked(db) };
381385
self.accumulated_map(db, key_index)

src/function/fetch.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ where
3535
database_key_index,
3636
memo.revisions.durability,
3737
memo.revisions.changed_at,
38+
memo.cycle_heads(),
39+
#[cfg(feature = "accumulator")]
3840
memo.revisions.accumulated().is_some(),
41+
#[cfg(feature = "accumulator")]
3942
&memo.revisions.accumulated_inputs,
40-
memo.cycle_heads(),
4143
);
4244

4345
memo_value
@@ -221,7 +223,7 @@ where
221223
if let Some(old_memo) = opt_old_memo {
222224
if old_memo.value.is_some() {
223225
let mut cycle_heads = CycleHeads::default();
224-
if let VerifyResult::Unchanged(_) =
226+
if let VerifyResult::Unchanged { .. } =
225227
self.deep_verify_memo(db, zalsa, old_memo, database_key_index, &mut cycle_heads)
226228
{
227229
if cycle_heads.is_empty() {

0 commit comments

Comments
 (0)