3333//! aggressive inlining to fully flatten the filter logic. The aggressive phase:
3434//! 1. Iterates up to `aggressive_inline_cutoff` times per filter.
3535//! 2. On each iteration, inlines all eligible callsites found in the filter.
36- //! 3. Tracks which SCCs have been inlined to prevent cycles.
36+ //! 3. Calls to loop breakers and self-calls are skipped to prevent cycles.
3737//! 4. Emits a diagnostic if the cutoff is reached.
3838//!
3939//! # Budget System
@@ -53,18 +53,12 @@ use alloc::collections::BinaryHeap;
5353use core:: { alloc:: Allocator , cmp, mem} ;
5454
5555use hashql_core:: {
56- graph:: {
57- DirectedGraph as _,
58- algorithms:: {
59- Tarjan , TriColorDepthFirstSearch ,
60- tarjan:: { Members , SccId , StronglyConnectedComponents } ,
61- } ,
56+ graph:: algorithms:: {
57+ Tarjan , TriColorDepthFirstSearch ,
58+ tarjan:: { Members , SccId , StronglyConnectedComponents } ,
6259 } ,
6360 heap:: { BumpAllocator , Heap } ,
64- id:: {
65- Id as _, IdSlice ,
66- bit_vec:: { DenseBitSet , SparseBitMatrix } ,
67- } ,
61+ id:: { Id as _, IdSlice , bit_vec:: DenseBitSet } ,
6862 span:: SpanId ,
6963} ;
7064
@@ -214,11 +208,6 @@ struct InlineState<'ctx, 'state, 'env, 'heap, A: Allocator> {
214208 /// Calls to a breaker within its SCC are skipped during inlining.
215209 /// Calls from a breaker to non-breakers are still inlined.
216210 loop_breakers : DenseBitSet < DefId > ,
217- /// Tracks which SCCs have been inlined into each function.
218- ///
219- /// Used to prevent cycles during aggressive inlining: once an SCC
220- /// has been inlined into a filter, it won't be inlined again.
221- inlined : SparseBitMatrix < DefId , SccId , A > ,
222211
223212 // cost estimation properties
224213 costs : CostEstimationResidual < ' heap , A > ,
@@ -231,23 +220,15 @@ struct InlineState<'ctx, 'state, 'env, 'heap, A: Allocator> {
231220}
232221
233222impl < ' heap , A : Allocator > InlineState < ' _ , ' _ , ' _ , ' heap , A > {
234- /// Collect all non-recursive callsites for aggressive inlining.
223+ /// Collect all callsites for aggressive inlining.
235224 ///
236225 /// Used for filter functions which bypass normal heuristics.
237- /// Records inlined SCCs to prevent cycles in subsequent iterations.
238- fn collect_all_callsites ( & mut self , body : DefId , mem : & mut InlineStateMemory < A > ) {
239- let component = self . components . scc ( body) ;
240-
226+ /// Self-calls are excluded to prevent panics in `get_disjoint_mut`.
227+ fn collect_all_callsites ( & self , body : DefId , mem : & mut InlineStateMemory < A > ) {
241228 self . graph
242229 . apply_callsites ( body)
243- . filter ( |callsite| self . components . scc ( callsite. target ) != component )
230+ . filter ( |callsite| callsite. target != body )
244231 . collect_into ( & mut mem. callsites ) ;
245-
246- self . inlined . insert ( body, component) ;
247- for callsite in & mem. callsites {
248- self . inlined
249- . insert ( body, self . components . scc ( callsite. target ) ) ;
250- }
251232 }
252233
253234 /// Collect callsites using heuristic scoring and budget.
@@ -570,7 +551,6 @@ impl<A: BumpAllocator> Inline<A> {
570551 config : self . config ,
571552 filters,
572553 loop_breakers,
573- inlined : SparseBitMatrix :: new_in ( components. node_count ( ) , & self . alloc ) ,
574554 interner,
575555 graph,
576556 costs,
@@ -640,9 +620,6 @@ impl<A: BumpAllocator> Inline<A> {
640620 mem. callsites
641621 . sort_unstable_by ( |lhs, rhs| lhs. kind . cmp ( & rhs. kind ) . reverse ( ) ) ;
642622 for callsite in mem. callsites . drain ( ..) {
643- let target_component = state. components . scc ( callsite. target ) ;
644- state. inlined . insert ( filter, target_component) ;
645-
646623 state. inline ( bodies, callsite) ;
647624 }
648625
0 commit comments