Skip to main content

torsh_jit/abstract_interpretation/
framework_config.rs

1//! Configuration and result types for the Abstract Interpretation Framework.
2//!
3//! This module contains all configuration structs, result types, analysis
4//! data structures, and supporting enums used by the core [`super::AbstractInterpreter`]
5//! engine. Extracted here to keep file sizes under policy limits.
6
7use super::super::domains::{AbstractDomainType, AbstractValue};
8use crate::NodeId;
9use std::collections::HashMap;
10use std::time::Duration;
11
12/// Abstract interpretation configuration
13#[derive(Debug, Clone)]
14pub struct AbstractInterpretationConfig {
15    /// Type of abstract domain to use
16    pub domain_type: AbstractDomainType,
17    /// Maximum number of fixpoint iterations
18    pub max_iterations: usize,
19    /// Number of iterations before applying widening
20    pub widening_delay: usize,
21    /// Enable narrowing after widening
22    pub enable_narrowing: bool,
23    /// Enable backward analysis in addition to forward analysis
24    pub enable_backward_analysis: bool,
25    /// Properties to check during analysis
26    pub properties: Vec<Property>,
27    /// Minimum precision threshold for analysis quality
28    pub precision_threshold: f64,
29}
30
31impl Default for AbstractInterpretationConfig {
32    fn default() -> Self {
33        Self {
34            domain_type: AbstractDomainType::Intervals,
35            max_iterations: 100,
36            widening_delay: 3,
37            enable_narrowing: true,
38            enable_backward_analysis: false,
39            properties: Vec::new(),
40            precision_threshold: 0.8,
41        }
42    }
43}
44
45/// Properties to verify during abstract interpretation
46#[derive(Debug, Clone)]
47pub enum Property {
48    /// Value is always non-negative
49    NonNegative(NodeId),
50    /// Value is always positive
51    Positive(NodeId),
52    /// Value is within specified bounds
53    BoundedValue(NodeId, f64, f64),
54    /// No division by zero
55    NoDivisionByZero(NodeId),
56    /// No overflow
57    NoOverflow(NodeId),
58    /// Custom safety property
59    SafetyProperty(String, NodeId),
60}
61
62/// Safety check types for verification
63#[derive(Debug, Clone)]
64pub enum SafetyCheck {
65    /// Bounds checking
66    BoundsCheck,
67    /// Null pointer check
68    NullCheck,
69    /// Division by zero check
70    DivisionByZeroCheck,
71    /// Overflow check
72    OverflowCheck,
73    /// Array access bounds
74    ArrayBoundsCheck,
75}
76
77/// Result of a safety check
78#[derive(Debug, Clone)]
79pub enum SafetyCheckResult {
80    /// Property definitely holds
81    Safe,
82    /// Property definitely violated
83    Unsafe,
84    /// Property may or may not hold (imprecise analysis)
85    Unknown,
86}
87
88/// Invariant detected during analysis
89#[derive(Debug, Clone)]
90pub struct Invariant {
91    /// Type of invariant
92    pub invariant_type: InvariantType,
93    /// Human-readable description
94    pub description: String,
95    /// Confidence level (0.0 to 1.0)
96    pub confidence: f64,
97    /// Location where invariant holds
98    pub location: String,
99}
100
101/// Types of invariants that can be detected
102#[derive(Debug, Clone)]
103pub enum InvariantType {
104    /// Value range invariant
105    ValueRange,
106    /// Loop invariant
107    LoopInvariant,
108    /// Conditional invariant
109    ConditionalInvariant,
110    /// Memory safety invariant
111    MemorySafety,
112    /// Numerical property
113    NumericalProperty,
114}
115
116/// Function-level invariant
117#[derive(Debug, Clone)]
118pub struct FunctionInvariant {
119    pub invariant_type: InvariantType,
120    pub description: String,
121    pub confidence: f64,
122    pub location: String,
123}
124
125/// Module-level invariant
126#[derive(Debug, Clone)]
127pub struct ModuleInvariant {
128    pub invariant_type: InvariantType,
129    pub description: String,
130    pub confidence: f64,
131    pub scope: String,
132}
133
134/// Analysis statistics tracking
135#[derive(Debug, Clone)]
136pub struct AnalysisStatistics {
137    /// Total analysis time
138    pub analysis_time: Duration,
139    /// Number of fixpoint iterations
140    pub fixpoint_iterations: usize,
141    /// Number of abstract states computed
142    pub abstract_states_computed: usize,
143    /// Cache hit count
144    pub cache_hits: usize,
145    /// Cache miss count
146    pub cache_misses: usize,
147}
148
149/// Forward analysis result
150#[derive(Debug, Clone)]
151pub struct ForwardAnalysisResult {
152    /// Pre-states for each node
153    pub pre_states: HashMap<NodeId, AbstractValue>,
154    /// Post-states for each node
155    pub post_states: HashMap<NodeId, AbstractValue>,
156    /// Number of iterations until convergence
157    pub iterations: usize,
158    /// Whether analysis converged
159    pub converged: bool,
160}
161
162impl ForwardAnalysisResult {
163    pub fn new() -> Self {
164        Self {
165            pre_states: HashMap::new(),
166            post_states: HashMap::new(),
167            iterations: 0,
168            converged: false,
169        }
170    }
171}
172
173impl Default for ForwardAnalysisResult {
174    fn default() -> Self {
175        Self::new()
176    }
177}
178
179/// Backward analysis result
180#[derive(Debug, Clone)]
181pub struct BackwardAnalysisResult {
182    /// Pre-states for each node (computed backwards)
183    pub pre_states: HashMap<NodeId, AbstractValue>,
184    /// Post-states for each node (computed backwards)
185    pub post_states: HashMap<NodeId, AbstractValue>,
186    /// Number of iterations until convergence
187    pub iterations: usize,
188    /// Whether analysis converged
189    pub converged: bool,
190}
191
192impl BackwardAnalysisResult {
193    pub fn new() -> Self {
194        Self {
195            pre_states: HashMap::new(),
196            post_states: HashMap::new(),
197            iterations: 0,
198            converged: false,
199        }
200    }
201}
202
203impl Default for BackwardAnalysisResult {
204    fn default() -> Self {
205        Self::new()
206    }
207}
208
209/// Function-specific analysis results
210#[derive(Debug, Clone)]
211pub struct AbstractFunctionResult {
212    /// Forward analysis result
213    pub forward_result: FunctionForwardResult,
214    /// Backward analysis result (if enabled)
215    pub backward_result: Option<FunctionBackwardResult>,
216    /// Function-level invariants
217    pub invariants: Vec<FunctionInvariant>,
218}
219
220/// Forward analysis result for a function
221#[derive(Debug, Clone)]
222pub struct FunctionForwardResult {
223    /// Whether analysis converged
224    pub converged: bool,
225    /// Number of iterations
226    pub iterations: usize,
227    /// Function entry state
228    pub entry_state: Option<AbstractValue>,
229    /// Function exit state
230    pub exit_state: Option<AbstractValue>,
231}
232
233impl FunctionForwardResult {
234    pub fn new() -> Self {
235        Self {
236            converged: false,
237            iterations: 0,
238            entry_state: None,
239            exit_state: None,
240        }
241    }
242}
243
244impl Default for FunctionForwardResult {
245    fn default() -> Self {
246        Self::new()
247    }
248}
249
250/// Backward analysis result for a function
251#[derive(Debug, Clone)]
252pub struct FunctionBackwardResult {
253    /// Whether analysis converged
254    pub converged: bool,
255    /// Number of iterations
256    pub iterations: usize,
257    /// Function entry state (computed backwards)
258    pub entry_state: Option<AbstractValue>,
259    /// Function exit state (computed backwards)
260    pub exit_state: Option<AbstractValue>,
261}
262
263impl FunctionBackwardResult {
264    pub fn new() -> Self {
265        Self {
266            converged: false,
267            iterations: 0,
268            entry_state: None,
269            exit_state: None,
270        }
271    }
272}
273
274impl Default for FunctionBackwardResult {
275    fn default() -> Self {
276        Self::new()
277    }
278}
279
280/// Interprocedural analysis result
281#[derive(Debug, Clone)]
282pub struct InterproceduralAnalysisResult {
283    /// Call graph representation
284    pub call_graph: HashMap<String, Vec<String>>,
285    /// Global invariants across functions
286    pub global_invariants: Vec<Invariant>,
287}
288
289/// Property verification result
290#[derive(Debug, Clone)]
291pub struct PropertyResult {
292    /// The property that was checked
293    pub property: Property,
294    /// Result of the check
295    pub result: SafetyCheckResult,
296    /// Confidence in the result
297    pub confidence: f64,
298    /// Additional details about the check
299    pub details: String,
300}
301
302/// Precision analysis result
303#[derive(Debug, Clone)]
304pub struct PrecisionAnalysis {
305    /// Overall precision score
306    pub overall_precision: f64,
307    /// Per-node precision scores
308    pub node_precision: HashMap<NodeId, f64>,
309    /// Areas where precision could be improved
310    pub improvement_suggestions: Vec<String>,
311}
312
313/// Performance analysis result
314#[derive(Debug, Clone)]
315pub struct PerformanceAnalysis {
316    /// Overall complexity score
317    pub complexity_score: f64,
318    /// Detected performance bottlenecks
319    pub bottlenecks: Vec<PerformanceBottleneck>,
320    /// Optimization opportunities
321    pub optimization_opportunities: Vec<OptimizationOpportunity>,
322}
323
324/// Performance bottleneck detection
325#[derive(Debug, Clone)]
326pub struct PerformanceBottleneck {
327    /// Type of bottleneck
328    pub bottleneck_type: BottleneckType,
329    /// Location of the bottleneck
330    pub location: NodeId,
331    /// Severity score (0.0 to 1.0)
332    pub severity: f64,
333    /// Description of the issue
334    pub description: String,
335}
336
337/// Types of performance bottlenecks
338#[derive(Debug, Clone)]
339pub enum BottleneckType {
340    /// Expensive computation
341    ComputationIntensive,
342    /// Memory bandwidth limited
343    MemoryBound,
344    /// Loop with high iteration count
345    LoopBottleneck,
346    /// Frequent function calls
347    CallOverhead,
348    /// Cache misses
349    CacheMisses,
350}
351
352/// Optimization opportunity
353#[derive(Debug, Clone)]
354pub struct OptimizationOpportunity {
355    /// Type of optimization
356    pub optimization_type: OptimizationType,
357    /// Location where optimization applies
358    pub location: NodeId,
359    /// Expected benefit (0.0 to 1.0)
360    pub benefit: f64,
361    /// Description of the optimization
362    pub description: String,
363}
364
365/// Types of optimizations
366#[derive(Debug, Clone)]
367pub enum OptimizationType {
368    /// Loop unrolling
369    LoopUnrolling,
370    /// Constant folding
371    ConstantFolding,
372    /// Common subexpression elimination
373    CommonSubexpressionElimination,
374    /// Dead code elimination
375    DeadCodeElimination,
376    /// Vectorization
377    Vectorization,
378}
379
380/// Complexity metrics
381#[derive(Debug, Clone)]
382pub struct ComplexityMetrics {
383    /// Cyclomatic complexity
384    pub cyclomatic_complexity: usize,
385    /// Number of variables
386    pub variable_count: usize,
387    /// Nesting depth
388    pub nesting_depth: usize,
389}
390
391/// Complete abstract analysis result
392#[derive(Debug, Clone)]
393pub struct AbstractAnalysisResult {
394    /// Forward analysis result
395    pub forward_result: ForwardAnalysisResult,
396    /// Backward analysis result (if performed)
397    pub backward_result: Option<BackwardAnalysisResult>,
398    /// Detected invariants
399    pub invariants: Vec<Invariant>,
400    /// Property verification results
401    pub property_results: Vec<PropertyResult>,
402    /// Precision analysis
403    pub precision_analysis: PrecisionAnalysis,
404    /// Performance analysis
405    pub performance_analysis: PerformanceAnalysis,
406    /// Analysis statistics
407    pub statistics: AnalysisStatistics,
408    /// Abstract values for each node
409    pub node_values: HashMap<NodeId, AbstractValue>,
410}
411
412/// IR module analysis result
413#[derive(Debug, Clone)]
414pub struct AbstractIrResult {
415    /// Results for individual functions
416    pub function_results: HashMap<String, AbstractFunctionResult>,
417    /// Interprocedural analysis result
418    pub interprocedural_result: InterproceduralAnalysisResult,
419    /// Module-level invariants
420    pub module_invariants: Vec<ModuleInvariant>,
421}