|
1 | | -use rustc_index::bit_set::DenseBitSet; |
2 | | -use rustc_index::interval::SparseIntervalMatrix; |
3 | | -use rustc_index::{Idx, IndexSlice, IndexVec}; |
4 | | -use rustc_middle::mir::{self, BasicBlock, Body, Location}; |
5 | | - |
6 | | -use crate::framework::{Analysis, Direction, Results, ResultsVisitor, visit_results}; |
| 1 | +use rustc_index::{Idx, IndexVec}; |
| 2 | +use rustc_middle::mir::{BasicBlock, Body, Location}; |
7 | 3 |
|
8 | 4 | /// Maps between a `Location` and a `PointIndex` (and vice versa). |
9 | 5 | pub struct DenseLocationMap { |
@@ -93,85 +89,3 @@ rustc_index::newtype_index! { |
93 | 89 | #[debug_format = "PointIndex({})"] |
94 | 90 | pub struct PointIndex {} |
95 | 91 | } |
96 | | - |
97 | | -/// Add points depending on the result of the given dataflow analysis. |
98 | | -pub fn save_as_intervals<'tcx, N, M, A>( |
99 | | - elements: &DenseLocationMap, |
100 | | - body: &mir::Body<'tcx>, |
101 | | - relevant: &IndexSlice<N, M>, |
102 | | - mut analysis: A, |
103 | | - results: Results<A::Domain>, |
104 | | -) -> SparseIntervalMatrix<N, PointIndex> |
105 | | -where |
106 | | - N: Idx, |
107 | | - M: Idx, |
108 | | - A: Analysis<'tcx, Domain = DenseBitSet<M>>, |
109 | | -{ |
110 | | - let mut values = SparseIntervalMatrix::new(elements.num_points()); |
111 | | - let reachable_blocks = mir::traversal::reachable_as_bitset(body); |
112 | | - if A::Direction::IS_BACKWARD { |
113 | | - // Iterate blocks in decreasing order, to visit locations in decreasing order. This |
114 | | - // allows to use the more efficient `prepend` method to interval sets. |
115 | | - let callback = |state: &DenseBitSet<M>, location| { |
116 | | - let point = elements.point_from_location(location); |
117 | | - for (relevant, &original) in relevant.iter_enumerated() { |
118 | | - if state.contains(original) { |
119 | | - values.prepend(relevant, point); |
120 | | - } |
121 | | - } |
122 | | - }; |
123 | | - let mut visitor = Visitor { callback }; |
124 | | - visit_results( |
125 | | - body, |
126 | | - // Note the `.rev()`. |
127 | | - body.basic_blocks.indices().filter(|&bb| reachable_blocks.contains(bb)).rev(), |
128 | | - &mut analysis, |
129 | | - &results, |
130 | | - &mut visitor, |
131 | | - ); |
132 | | - } else { |
133 | | - // Iterate blocks in increasing order, to visit locations in increasing order. This |
134 | | - // allows to use the more efficient `append` method to interval sets. |
135 | | - let callback = |state: &DenseBitSet<M>, location| { |
136 | | - let point = elements.point_from_location(location); |
137 | | - for (relevant, &original) in relevant.iter_enumerated() { |
138 | | - if state.contains(original) { |
139 | | - values.append(relevant, point); |
140 | | - } |
141 | | - } |
142 | | - }; |
143 | | - let mut visitor = Visitor { callback }; |
144 | | - visit_results(body, reachable_blocks.iter(), &mut analysis, &results, &mut visitor); |
145 | | - } |
146 | | - values |
147 | | -} |
148 | | - |
149 | | -struct Visitor<F> { |
150 | | - callback: F, |
151 | | -} |
152 | | - |
153 | | -impl<'tcx, A, F> ResultsVisitor<'tcx, A> for Visitor<F> |
154 | | -where |
155 | | - A: Analysis<'tcx>, |
156 | | - F: FnMut(&A::Domain, Location), |
157 | | -{ |
158 | | - fn visit_after_primary_statement_effect<'mir>( |
159 | | - &mut self, |
160 | | - _analysis: &mut A, |
161 | | - state: &A::Domain, |
162 | | - _statement: &'mir mir::Statement<'tcx>, |
163 | | - location: Location, |
164 | | - ) { |
165 | | - (self.callback)(state, location); |
166 | | - } |
167 | | - |
168 | | - fn visit_after_primary_terminator_effect<'mir>( |
169 | | - &mut self, |
170 | | - _analysis: &mut A, |
171 | | - state: &A::Domain, |
172 | | - _terminator: &'mir mir::Terminator<'tcx>, |
173 | | - location: Location, |
174 | | - ) { |
175 | | - (self.callback)(state, location); |
176 | | - } |
177 | | -} |
0 commit comments