Skip to content

Commit e9f937d

Browse files
authored
Revert "Allow merging local variable even if empty." (#3361)
1 parent c144871 commit e9f937d

File tree

6 files changed

+32
-122
lines changed

6 files changed

+32
-122
lines changed

crates/cairo-lang-sierra-to-casm/src/annotations.rs

Lines changed: 14 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use cairo_lang_casm::ap_change::{ApChangeError, ApplyApChange};
55
use cairo_lang_sierra::edit_state::{put_results, take_args};
66
use cairo_lang_sierra::ids::{FunctionId, VarId};
77
use cairo_lang_sierra::program::{BranchInfo, Function, StatementIdx};
8-
use cairo_lang_utils::try_extract_matches;
98
use cairo_lang_utils::unordered_hash_set::UnorderedHashSet;
109
use itertools::zip_eq;
1110
use thiserror::Error;
@@ -22,7 +21,6 @@ use crate::metadata::Metadata;
2221
use crate::references::{
2322
build_function_parameters_refs, check_types_match, IntroductionPoint,
2423
OutputReferenceValueIntroductionPoint, ReferenceValue, ReferencesError, StatementRefs,
25-
VariableApIndependentLocationInfo,
2624
};
2725
use crate::type_sizes::TypeSizeMap;
2826

@@ -205,8 +203,7 @@ impl ProgramAnnotations {
205203
// Check if the variable doesn't match on type, expression or stack information.
206204
if !(actual_ref.ty == expected_ref.ty
207205
&& actual_ref.expression == expected_ref.expression
208-
&& actual_ref.ap_independent_location_info
209-
== expected_ref.ap_independent_location_info)
206+
&& actual_ref.stack_idx == expected_ref.stack_idx)
210207
{
211208
return false;
212209
}
@@ -273,13 +270,10 @@ impl ProgramAnnotations {
273270
error,
274271
})?,
275272
ty: ref_value.ty.clone(),
276-
ap_independent_location_info: match &ref_value.ap_independent_location_info {
277-
VariableApIndependentLocationInfo::ContinuousStack(_)
278-
if branch_changes.clear_old_stack =>
279-
{
280-
VariableApIndependentLocationInfo::Other
281-
}
282-
other => other.clone(),
273+
stack_idx: if branch_changes.clear_old_stack {
274+
None
275+
} else {
276+
ref_value.stack_idx
283277
},
284278
introduction_point: ref_value.introduction_point.clone(),
285279
},
@@ -292,7 +286,7 @@ impl ProgramAnnotations {
292286
branch_changes.refs.into_iter().map(|value| ReferenceValue {
293287
expression: value.expression,
294288
ty: value.ty,
295-
ap_independent_location_info: value.ap_independent_location_info,
289+
stack_idx: value.stack_idx,
296290
introduction_point: match value.introduction_point {
297291
OutputReferenceValueIntroductionPoint::New(output_idx) => {
298292
IntroductionPoint {
@@ -317,34 +311,18 @@ impl ProgramAnnotations {
317311
// Since some variables on the stack may have been consumed by the libfunc, we need to
318312
// find the new stack size. This is done by searching from the bottom of the stack until we
319313
// find a missing variable.
320-
let available_stack_indices: UnorderedHashSet<_> = refs
321-
.values()
322-
.flat_map(|r| {
323-
try_extract_matches!(
324-
r.ap_independent_location_info,
325-
VariableApIndependentLocationInfo::ContinuousStack
326-
)
327-
})
328-
.collect();
314+
let available_stack_indices: UnorderedHashSet<_> =
315+
refs.values().flat_map(|r| r.stack_idx).collect();
329316
let new_stack_size_opt = (0..branch_changes.new_stack_size)
330317
.find(|i| !available_stack_indices.contains(&(branch_changes.new_stack_size - 1 - i)));
331318
let stack_size = if let Some(new_stack_size) = new_stack_size_opt {
332319
// The number of stack elements which were removed.
333320
let stack_removal = branch_changes.new_stack_size - new_stack_size;
334321
for r in refs.values_mut() {
335-
r.ap_independent_location_info = match &r.ap_independent_location_info {
336-
VariableApIndependentLocationInfo::ContinuousStack(stack_idx) => {
337-
// Subtract the number of stack elements removed. If the result is negative,
338-
// `stack_idx` is set to `None` and the variable is removed from the stack.
339-
match stack_idx.checked_sub(stack_removal) {
340-
Some(new_stack_idx) => {
341-
VariableApIndependentLocationInfo::ContinuousStack(new_stack_idx)
342-
}
343-
None => VariableApIndependentLocationInfo::Other,
344-
}
345-
}
346-
other => other.clone(),
347-
};
322+
// Subtract the number of stack elements removed. If the result is negative,
323+
// `stack_idx` is set to `None` and the variable is removed from the stack.
324+
r.stack_idx =
325+
r.stack_idx.and_then(|stack_idx| stack_idx.checked_sub(stack_removal));
348326
}
349327
new_stack_size
350328
} else {
@@ -456,12 +434,8 @@ fn test_var_consistency(
456434
expected: &ReferenceValue,
457435
ap_tracking_enabled: bool,
458436
) -> bool {
459-
// If the variable is on the stack, or is local, it can always be merged.
460-
if matches!(
461-
actual.ap_independent_location_info,
462-
VariableApIndependentLocationInfo::ContinuousStack(_)
463-
| VariableApIndependentLocationInfo::Local
464-
) {
437+
// If the variable is on the stack, it can always be merged.
438+
if actual.stack_idx.is_some() {
465439
return true;
466440
}
467441
// If the variable is not ap-dependent it can always be merged.

crates/cairo-lang-sierra-to-casm/src/invocations/mod.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::environment::Environment;
2525
use crate::metadata::Metadata;
2626
use crate::references::{
2727
OutputReferenceValue, OutputReferenceValueIntroductionPoint, ReferenceExpression,
28-
ReferenceValue, VariableApIndependentLocationInfo,
28+
ReferenceValue,
2929
};
3030
use crate::relocations::{InstructionsWithRelocations, Relocation, RelocationEntry};
3131
use crate::type_sizes::TypeSizeMap;
@@ -136,15 +136,13 @@ impl BranchChanges {
136136
.enumerate()
137137
.map(|(output_idx, (expression, OutputVarInfo { ref_info, ty }))| {
138138
validate_output_var_refs(ref_info, &expression);
139-
let ap_independent_location_info = calc_output_ap_independent_location_info(
139+
let stack_idx = calc_output_var_stack_idx(
140140
ref_info,
141141
stack_base,
142142
clear_old_stack,
143143
&param_ref,
144144
);
145-
if let VariableApIndependentLocationInfo::ContinuousStack(stack_idx) =
146-
ap_independent_location_info
147-
{
145+
if let Some(stack_idx) = stack_idx {
148146
new_stack_size = new_stack_size.max(stack_idx + 1);
149147
}
150148
let introduction_point =
@@ -159,7 +157,7 @@ impl BranchChanges {
159157
OutputReferenceValue {
160158
expression,
161159
ty: ty.clone(),
162-
ap_independent_location_info,
160+
stack_idx,
163161
introduction_point,
164162
}
165163
})
@@ -200,24 +198,22 @@ fn validate_output_var_refs(ref_info: &OutputVarReferenceInfo, expression: &Refe
200198

201199
/// Calculates the continuous stack index for an output var of a branch.
202200
/// `param_ref` is used to fetch the reference value of a param of the libfunc.
203-
fn calc_output_ap_independent_location_info<'a, ParamRef: Fn(usize) -> &'a ReferenceValue>(
201+
fn calc_output_var_stack_idx<'a, ParamRef: Fn(usize) -> &'a ReferenceValue>(
204202
ref_info: &OutputVarReferenceInfo,
205203
stack_base: usize,
206204
clear_old_stack: bool,
207205
param_ref: &ParamRef,
208-
) -> VariableApIndependentLocationInfo {
206+
) -> Option<usize> {
209207
match ref_info {
210-
OutputVarReferenceInfo::NewTempVar { idx } => {
211-
VariableApIndependentLocationInfo::ContinuousStack(stack_base + idx)
212-
}
213-
OutputVarReferenceInfo::NewLocalVar => VariableApIndependentLocationInfo::Local,
208+
OutputVarReferenceInfo::NewTempVar { idx } => Some(stack_base + idx),
214209
OutputVarReferenceInfo::SameAsParam { param_idx } if !clear_old_stack => {
215-
param_ref(*param_idx).ap_independent_location_info.clone()
210+
param_ref(*param_idx).stack_idx
216211
}
217212
OutputVarReferenceInfo::SameAsParam { .. }
218213
| OutputVarReferenceInfo::SimpleDerefs
214+
| OutputVarReferenceInfo::NewLocalVar
219215
| OutputVarReferenceInfo::PartialParam { .. }
220-
| OutputVarReferenceInfo::Deferred(_) => VariableApIndependentLocationInfo::Other,
216+
| OutputVarReferenceInfo::Deferred(_) => None,
221217
}
222218
}
223219

crates/cairo-lang-sierra-to-casm/src/invocations/test_utils.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ use super::{compile_invocation, CompiledInvocation, ProgramInfo};
2121
use crate::environment::gas_wallet::GasWallet;
2222
use crate::environment::Environment;
2323
use crate::metadata::Metadata;
24-
use crate::references::{
25-
IntroductionPoint, ReferenceExpression, ReferenceValue, VariableApIndependentLocationInfo,
26-
};
24+
use crate::references::{IntroductionPoint, ReferenceExpression, ReferenceValue};
2725
use crate::relocations::RelocationEntry;
2826

2927
/// Creates a Felt252BinaryOperator from a token operator.
@@ -269,7 +267,7 @@ pub fn compile_libfunc(libfunc: &str, refs: Vec<ReferenceExpression>) -> Reduced
269267
.map(|(expression, param)| ReferenceValue {
270268
expression,
271269
ty: param.ty.clone(),
272-
ap_independent_location_info: VariableApIndependentLocationInfo::Other,
270+
stack_idx: None,
273271
introduction_point: IntroductionPoint {
274272
source_statement_idx: None,
275273
destination_statement_idx: StatementIdx(0),

crates/cairo-lang-sierra-to-casm/src/references.rs

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,15 @@ pub enum ReferencesError {
2626

2727
pub type StatementRefs = HashMap<VarId, ReferenceValue>;
2828

29-
/// Information about the location of a variable that is not dependent on the actual AP values.
30-
/// Used for recompilability checks.
31-
#[derive(Clone, Debug, Eq, PartialEq)]
32-
pub enum VariableApIndependentLocationInfo {
33-
/// The variable is on the continuous-stack, with the given index. 0 represents the oldest
34-
/// element on the stack.
35-
ContinuousStack(usize),
36-
/// The variable was defined as a local variable. May be a function param, or an explicitly
37-
/// defined local.
38-
Local,
39-
/// Any other case.
40-
Other,
41-
}
42-
4329
/// A Sierra reference to a value.
4430
/// Corresponds to an argument or return value of a Sierra statement.
4531
#[derive(Clone, Debug)]
4632
pub struct ReferenceValue {
4733
pub expression: ReferenceExpression,
4834
pub ty: ConcreteTypeId,
49-
/// Location information for the variable that does not depend on AP.
50-
pub ap_independent_location_info: VariableApIndependentLocationInfo,
35+
/// The index of the variable on the continuous-stack. 0 represents the oldest element on the
36+
/// stack.
37+
pub stack_idx: Option<usize>,
5138
/// The location the value was introduced.
5239
pub introduction_point: IntroductionPoint,
5340
}
@@ -78,8 +65,8 @@ pub struct IntroductionPoint {
7865
pub struct OutputReferenceValue {
7966
pub expression: ReferenceExpression,
8067
pub ty: ConcreteTypeId,
81-
/// Location information for the variable that does not depend on AP.
82-
pub ap_independent_location_info: VariableApIndependentLocationInfo,
68+
/// The index of the variable on the continuous-stack.
69+
pub stack_idx: Option<usize>,
8370
/// The statememt and output index where the value was introduced.
8471
/// Statement may be New if it is to be populated later.
8572
pub introduction_point: OutputReferenceValueIntroductionPoint,
@@ -159,7 +146,7 @@ pub fn build_function_parameters_refs(
159146
.collect(),
160147
},
161148
ty: param.ty.clone(),
162-
ap_independent_location_info: VariableApIndependentLocationInfo::Local,
149+
stack_idx: None,
163150
introduction_point: IntroductionPoint {
164151
source_statement_idx: None,
165152
destination_statement_idx: func.entry_point,

tests/bug_samples/issue3345.cairo

Lines changed: 0 additions & 44 deletions
This file was deleted.

tests/bug_samples/lib.cairo

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ mod issue2995;
1919
mod issue3153;
2020
mod issue3192;
2121
mod issue3211;
22-
mod issue3345;
2322
mod loop_only_change;
2423
mod inconsistent_gas;
2524
mod partial_param_local;

0 commit comments

Comments
 (0)