1use super::{MopAliasPair, MopFnAliasMap, graph::*, types::*, value::*};
2use crate::compat::{FxHashMap, FxHashSet};
3use crate::def_id::*;
4use rustc_hir::def_id::DefId;
5use rustc_middle::{
6 mir::{Local, Operand, Place, ProjectionElem, TerminatorKind},
7 ty,
8};
9use std::collections::HashSet;
10
11const MAX_VALUES_PER_PATH: usize = 1000;
14
15const MAX_FIELD_DEPTH: usize = 10;
17
18impl<'tcx> AliasGraph<'tcx> {
19 pub fn alias_bb(&mut self, bb_index: usize) {
21 for constant in self.block_facts[bb_index].const_value.clone() {
22 self.constants.insert(constant.local, constant.value);
23 }
24 let block_facts = self.block_facts[bb_index].clone();
25 for assign in block_facts.assignments {
26 rap_debug!("assign: {:?}", assign);
27 let lv_idx = self.projection(assign.lv);
28 let rv_idx = self.projection(assign.rv);
29
30 self.assign_alias(lv_idx, rv_idx);
31 rap_debug!("Alias sets: {:?}", self.alias_sets)
32 }
33 }
34
35 pub fn alias_bbcall(
37 &mut self,
38 bb_index: usize,
39 fn_map: &mut MopFnAliasMap,
40 recursion_set: &mut HashSet<DefId>,
41 ) {
42 if let Some(terminator) = self.terminator(bb_index).cloned() {
43 if let TerminatorKind::Call {
44 func: Operand::Constant(ref constant),
45 ref args,
46 ref destination,
47 target: _,
48 unwind: _,
49 call_source: _,
50 fn_span: _,
51 } = terminator.kind
52 {
53 let lv = self.projection(*destination);
54 let mut may_drop = false;
55 if self.values[lv].may_drop {
56 may_drop = true;
57 }
58
59 let mut merge_vec = Vec::new();
60 merge_vec.push(lv);
61
62 for arg in args {
63 match arg.node {
64 Operand::Copy(ref p) | Operand::Move(ref p) => {
65 let rv = self.projection(*p);
66 merge_vec.push(rv);
67 if self.values[rv].may_drop {
68 may_drop = true;
69 }
70 }
71 Operand::Constant(_) => {
73 merge_vec.push(0);
74 }
75 #[cfg(rapx_rustc_ge_196)]
76 Operand::RuntimeChecks(_) => {}
77 }
78 }
79 if let &ty::FnDef(target_id, _) = constant.const_.ty().kind() {
80 if may_drop == false {
81 return;
82 }
83 if is_no_alias_intrinsic(target_id) {
85 return;
86 }
87 if !self.tcx().is_mir_available(target_id) {
88 return;
89 }
90 rap_debug!("Sync aliases for function call: {:?}", target_id);
91 let fn_aliases = if fn_map.contains_key(&target_id) {
92 rap_debug!("Aliases existed");
93 fn_map.get(&target_id).unwrap()
94 } else {
95 if recursion_set.contains(&target_id) {
97 return;
98 }
99 recursion_set.insert(target_id);
100 let mut alias_graph = AliasGraph::new(self.tcx(), target_id);
101 alias_graph.find_scc();
102 alias_graph.process_function_paths(fn_map, recursion_set);
103 let ret_alias = alias_graph.ret_alias.clone();
104 rap_debug!("Find aliases of {:?}: {:?}", target_id, ret_alias);
105 fn_map.insert(target_id, ret_alias);
106 recursion_set.remove(&target_id);
107 fn_map.get(&target_id).unwrap()
108 };
109 if fn_aliases.aliases().is_empty() {
110 if let Some(l_set_idx) = self.find_alias_set(lv) {
111 self.alias_sets[l_set_idx].remove(&lv);
112 }
113 }
114 for alias in fn_aliases.aliases().iter() {
115 if !alias.valuable() {
116 continue;
117 }
118 self.handle_fn_alias(alias, &merge_vec);
119 rap_debug!("{:?}", self.alias_sets);
120 }
121 } else if self.values[lv].may_drop {
122 for rv in &merge_vec {
123 if self.values[*rv].may_drop && lv != *rv && self.values[lv].is_ptr() {
124 self.merge_alias(lv, *rv);
128 }
129 }
130 }
131 }
132 }
133 }
134
135 pub fn projection(&mut self, place: Place<'tcx>) -> usize {
141 let local = place.local.as_usize();
142 rap_debug!("projection: place = {:?}, local = {:?}", place, local);
143 let mut value_idx = local;
144 for proj in place.projection {
149 rap_debug!("proj: {:?}", proj);
150 let new_value_idx = self.values.len();
151 match proj {
152 ProjectionElem::Deref => {}
153 ProjectionElem::Field(field, ty) => {
154 let field_idx = field.as_usize();
155 if !self.values[value_idx].fields.contains_key(&field_idx) {
156 if self.values.len() < MAX_VALUES_PER_PATH {
157 let ty_env = ty::TypingEnv::post_analysis(self.tcx(), self.def_id());
158 let need_drop = ty.needs_drop(self.tcx(), ty_env);
159 let may_drop = !is_not_drop(self.tcx(), ty);
160 let mut node =
161 Value::new(new_value_idx, local, need_drop, need_drop || may_drop);
162 node.kind = kind(ty);
163 node.father = Some(FatherInfo::new(value_idx, field_idx));
164 self.values[value_idx].fields.insert(field_idx, node.index);
165 self.values.push(node);
166 } else {
167 break;
168 }
169 }
170 value_idx = *self.values[value_idx].fields.get(&field_idx).unwrap();
171 }
172 _ => {}
173 }
174 }
175 value_idx
176 }
177
178 pub fn assign_alias(&mut self, lv_idx: usize, rv_idx: usize) {
182 rap_debug!("assign_alias: lv = {:?}. rv = {:?}", lv_idx, rv_idx);
183
184 let r_set_idx = if let Some(idx) = self.find_alias_set(rv_idx) {
185 idx
186 } else {
187 self.alias_sets
188 .push([rv_idx].into_iter().collect::<FxHashSet<usize>>());
189 self.alias_sets.len() - 1
190 };
191
192 if let Some(l_set_idx) = self.find_alias_set(lv_idx) {
193 if l_set_idx == r_set_idx {
194 return;
195 }
196 self.alias_sets[l_set_idx].remove(&lv_idx);
197 }
198 let new_l_set_idx = r_set_idx;
199 self.alias_sets[new_l_set_idx].insert(lv_idx);
200
201 if self.values[lv_idx].fields.len() > 0 || self.values[rv_idx].fields.len() > 0 {
202 self.sync_field_alias(lv_idx, rv_idx, 0, true);
203 }
204 if self.values[rv_idx].father != None {
205 self.sync_father_alias(lv_idx, rv_idx, new_l_set_idx);
206 }
207 }
208
209 pub fn sync_field_alias(&mut self, lv: usize, rv: usize, depth: usize, clear_left: bool) {
215 if depth > MAX_FIELD_DEPTH || self.values.len() >= MAX_VALUES_PER_PATH {
216 return;
217 }
218 rap_debug!("sync field aliases for lv:{} rv:{}", lv, rv);
219
220 if clear_left {
222 for lv_field in self.values[lv].fields.clone().into_iter() {
223 if let Some(alias_set_idx) = self.find_alias_set(lv_field.1) {
224 self.alias_sets[alias_set_idx].remove(&lv_field.1);
225 }
226 }
227 }
228 for rv_field in self.values[rv].fields.clone().into_iter() {
229 rap_debug!("rv_field: {:?}", rv_field);
230 if !self.values[lv].fields.contains_key(&rv_field.0) {
231 if self.values.len() < MAX_VALUES_PER_PATH {
232 let mut node = Value::new(
233 self.values.len(),
234 self.values[lv].local,
235 self.values[rv_field.1].need_drop,
236 self.values[rv_field.1].may_drop,
237 );
238 node.kind = self.values[rv_field.1].kind;
239 node.father = Some(FatherInfo::new(lv, rv_field.0));
240 self.values[lv].fields.insert(rv_field.0, node.index);
241 self.values.push(node);
242 } else {
243 continue;
244 }
245 }
246 let lv_field_value_idx = *(self.values[lv].fields.get(&rv_field.0).unwrap());
247
248 rap_debug!(
249 "alias_set_id of rv_field {:?}",
250 self.find_alias_set(rv_field.1)
251 );
252 if let Some(alias_set_idx) = self.find_alias_set(rv_field.1) {
253 self.alias_sets[alias_set_idx].insert(lv_field_value_idx);
254 }
255 rap_debug!("alias sets: {:?}", self.alias_sets);
256 self.sync_field_alias(lv_field_value_idx, rv_field.1, depth + 1, true);
257 }
258 }
259
260 pub fn sync_father_alias(&mut self, lv: usize, rv: usize, lv_alias_set_idx: usize) {
266 rap_debug!("sync father aliases for lv:{} rv:{}", lv, rv);
267 let mut father_id = rv;
268 let mut father = self.values[father_id].father.clone();
269 let mut iteration = 0usize;
270 while let Some(father_info) = father {
271 iteration += 1;
272 if iteration > 1000 {
273 rap_warn!(
274 "sync_father_alias exceeded 1000 iterations: lv={} rv={} father_id={}",
275 lv,
276 rv,
277 father_id
278 );
279 break;
280 }
281 father_id = father_info.father_value_id;
282 let field_id = father_info.field_id;
283 let father_value = self.values[father_id].clone();
284 if let Some(alias_set_idx) = self.find_alias_set(father_id) {
285 for value_idx in self.alias_sets[alias_set_idx].clone() {
286 let field_value_idx = if self.values[value_idx].fields.contains_key(&field_id) {
288 *self.values[value_idx].fields.get(&field_id).unwrap()
289 } else if self.values.len() < MAX_VALUES_PER_PATH {
290 let mut node = Value::new(
291 self.values.len(),
292 self.values[value_idx].local,
293 self.values[value_idx].need_drop,
294 self.values[value_idx].may_drop,
295 );
296 node.kind = self.values[value_idx].kind;
297 node.father = Some(FatherInfo::new(value_idx, field_id));
298 self.values.push(node.clone());
299 self.values[value_idx].fields.insert(field_id, node.index);
300 node.index
301 } else {
302 continue;
303 };
304 self.alias_sets[lv_alias_set_idx].insert(field_value_idx);
306 }
307 }
308 father = father_value.father;
309 }
310 }
311
312 pub fn handle_fn_alias(&mut self, fn_alias: &MopAliasPair, arg_vec: &[usize]) {
314 rap_debug!(
315 "merge aliases returned by function calls, args: {:?}",
316 arg_vec
317 );
318 rap_debug!("fn alias: {:?}", fn_alias);
319 if fn_alias.left_local() >= arg_vec.len() || fn_alias.right_local() >= arg_vec.len() {
320 return;
321 }
322
323 let mut lv = arg_vec[fn_alias.left_local()];
324 let mut rv = arg_vec[fn_alias.right_local()];
325 let left_local = self.values[lv].local;
326 let right_local = self.values[rv].local;
327
328 for index in fn_alias.lhs_fields().iter() {
329 if !self.values[lv].fields.contains_key(index) {
330 if self.values.len() < MAX_VALUES_PER_PATH {
331 let need_drop = fn_alias.lhs_need_drop;
332 let may_drop = fn_alias.lhs_may_drop;
333 let mut node = Value::new(self.values.len(), left_local, need_drop, may_drop);
334 node.kind = ValueKind::RawPtr;
335 node.father = Some(FatherInfo::new(lv, *index));
336 self.values[lv].fields.insert(*index, node.index);
337 self.values.push(node);
338 } else {
339 break;
340 }
341 }
342 lv = *self.values[lv].fields.get(index).unwrap();
343 }
344 for index in fn_alias.rhs_fields().iter() {
345 if !self.values[rv].fields.contains_key(index) {
346 if self.values.len() < MAX_VALUES_PER_PATH {
347 let need_drop = fn_alias.rhs_need_drop;
348 let may_drop = fn_alias.rhs_may_drop;
349 let mut node = Value::new(self.values.len(), right_local, need_drop, may_drop);
350 node.kind = ValueKind::RawPtr;
351 node.father = Some(FatherInfo::new(rv, *index));
352 self.values[rv].fields.insert(*index, node.index);
353 self.values.push(node);
354 } else {
355 break;
356 }
357 }
358 rv = *self.values[rv].fields.get(index).unwrap();
359 }
360 self.merge_alias(lv, rv);
363 }
364
365 pub fn get_field_seq(&self, value: &Value) -> Vec<usize> {
366 let mut field_id_seq = vec![];
367 let mut node_ref = value;
368 let mut iteration = 0usize;
369 while let Some(father) = &node_ref.father {
370 iteration += 1;
371 if iteration > 1000 {
372 rap_warn!("get_field_seq exceeded 1000 iterations: value={:?}", value);
373 break;
374 }
375 field_id_seq.push(father.field_id);
376 node_ref = &self.values[father.father_value_id];
377 }
378 field_id_seq
379 }
380
381 fn is_valid_field(&self, local: usize, field_seq: &[usize]) -> bool {
384 let body = self.tcx().optimized_mir(self.def_id());
385 let mut ty = body.local_decls[Local::from_usize(local)].ty;
386 for &fidx in field_seq {
387 while let ty::TyKind::Ref(_, inner, _) | ty::TyKind::RawPtr(inner, _) = ty.kind() {
388 ty = *inner;
389 }
390 if let ty::Adt(def, _) = ty.kind() {
391 let field_count = def.all_fields().count();
392 if fidx >= field_count {
393 return false;
394 }
395 } else {
396 return false;
398 }
399 }
400 true
401 }
402
403 pub fn merge_results(&mut self) {
405 rap_debug!("merge results");
406 let f_node: Vec<Option<FatherInfo>> =
407 self.values.iter().map(|v| v.father.clone()).collect();
408 let set_index = self.build_set_index();
409 let mut set_arg_values: Vec<Vec<usize>> = vec![Vec::new(); self.alias_sets.len()];
411 for (set_idx, set) in self.alias_sets.iter().enumerate() {
412 for &v in set {
413 if self.values[v].local <= self.arg_size() {
414 set_arg_values[set_idx].push(v);
415 }
416 }
417 }
418 for node in self.values.iter() {
419 if node.local > self.arg_size() {
420 continue;
421 }
422 let scan_limit = MAX_VALUES_PER_PATH.min(self.values.len());
424 for idx in 1..scan_limit {
425 if !self.is_aliasing_indexed(idx, node.index, &set_index) {
426 continue;
427 }
428
429 let mut replace = None;
430 if self.values[idx].local > self.arg_size() {
431 for (i, fidx) in f_node.iter().enumerate() {
432 if replace.is_some() {
433 break;
434 }
435 if let Some(father_info) = fidx {
436 if i != idx && i != node.index {
437 if let Some(set_idx) = set_index.get(&father_info.father_value_id) {
438 for &j in &set_arg_values[*set_idx] {
439 if j != idx && j != node.index {
440 replace = Some(&self.values[j]);
441 break;
442 }
443 }
444 }
445 }
446 }
447 }
448 }
449
450 if (self.values[idx].local <= self.arg_size() || replace.is_some())
451 && idx != node.index
452 && node.local != self.values[idx].local
453 {
454 let left_node;
455 let right_node;
456 match self.values[idx].local {
457 0 => {
458 left_node = match replace {
459 Some(replace_node) => replace_node,
460 None => &self.values[idx],
461 };
462 right_node = node;
463 }
464 _ => {
465 left_node = node;
466 right_node = match replace {
467 Some(replace_node) => replace_node,
468 None => &self.values[idx],
469 };
470 }
471 }
472 let mut new_alias = MopAliasPair::new(
473 left_node.local,
474 left_node.may_drop,
475 left_node.need_drop,
476 right_node.local,
477 right_node.may_drop,
478 right_node.need_drop,
479 );
480 new_alias.fact.lhs_fields = self.get_field_seq(left_node);
481 new_alias.fact.rhs_fields = self.get_field_seq(right_node);
482 if new_alias.left_local() == new_alias.right_local() {
483 continue;
484 }
485 if !self.is_valid_field(left_node.local, &new_alias.fact.lhs_fields)
486 || !self.is_valid_field(right_node.local, &new_alias.fact.rhs_fields)
487 {
488 rap_debug!("new_alias with invalid field: {:?}", new_alias);
489 continue;
490 }
491 rap_debug!("new_alias: {:?}", new_alias);
492 self.ret_alias.add_alias(new_alias);
493 }
494 }
495 }
496 self.compress_aliases();
497 }
498
499 pub fn compress_aliases(&mut self) {
515 let mut truncated_facts = Vec::new();
517 for fact in self.ret_alias.alias_set.iter() {
518 let mut new_fact = fact.clone();
519 if !new_fact.fact.lhs_fields.is_empty() {
520 new_fact.fact.lhs_fields = vec![new_fact.fact.lhs_fields[0]];
521 }
522 if !new_fact.fact.rhs_fields.is_empty() {
523 new_fact.fact.rhs_fields = vec![new_fact.fact.rhs_fields[0]];
524 }
525 truncated_facts.push(new_fact);
526 }
527 self.ret_alias.alias_set.clear();
529 for fact in truncated_facts {
530 self.ret_alias.alias_set.insert(fact);
531 }
532
533 let aliases: Vec<MopAliasPair> = self.ret_alias.alias_set.iter().cloned().collect();
536 let n = aliases.len();
537 let mut to_remove: HashSet<MopAliasPair> = HashSet::new();
538
539 for i in 0..n {
540 for j in 0..n {
541 if i == j || to_remove.contains(&aliases[j]) {
542 continue;
543 }
544 let a = &aliases[i].fact;
545 let b = &aliases[j].fact;
546 if a.left_local() == b.left_local() && a.right_local() == b.right_local() {
548 if a.lhs_fields.len() <= b.lhs_fields.len()
549 && a.lhs_fields == b.lhs_fields[..a.lhs_fields.len()]
550 && a.rhs_fields.len() <= b.rhs_fields.len()
551 && a.rhs_fields == b.rhs_fields[..a.rhs_fields.len()]
552 && (a.lhs_fields.len() < b.lhs_fields.len() || a.rhs_fields.len() < b.rhs_fields.len())
554 {
555 to_remove.insert(aliases[j].clone());
556 }
557 }
558 }
559 }
560 for alias in to_remove {
561 self.ret_alias.alias_set.remove(&alias);
562 }
563 }
564
565 #[inline(always)]
566 pub fn find_alias_set(&self, e: usize) -> Option<usize> {
567 self.alias_sets.iter().position(|set| set.contains(&e))
568 }
569
570 #[inline(always)]
571 pub fn is_aliasing(&self, e1: usize, e2: usize) -> bool {
572 let s1 = self.find_alias_set(e1);
573 let s2 = self.find_alias_set(e2);
574 s1.is_some() && s1 == s2
575 }
576
577 fn build_set_index(&self) -> FxHashMap<usize, usize> {
578 let mut map = FxHashMap::default();
579 for (set_idx, set) in self.alias_sets.iter().enumerate() {
580 for &v in set {
581 map.insert(v, set_idx);
582 }
583 }
584 map
585 }
586
587 #[inline(always)]
588 fn is_aliasing_indexed(&self, e1: usize, e2: usize, index: &FxHashMap<usize, usize>) -> bool {
589 match (index.get(&e1), index.get(&e2)) {
590 (Some(s1), Some(s2)) => s1 == s2,
591 _ => false,
592 }
593 }
594
595 pub fn merge_alias(&mut self, e1: usize, e2: usize) {
596 let mut s1 = self.find_alias_set(e1);
597 let mut s2 = self.find_alias_set(e2);
598
599 if s1.is_none() {
601 self.alias_sets
602 .push([e1].into_iter().collect::<FxHashSet<usize>>());
603 s1 = Some(self.alias_sets.len() - 1);
604 }
605
606 if s2.is_none() {
608 self.alias_sets
609 .push([e2].into_iter().collect::<FxHashSet<usize>>());
610 s2 = Some(self.alias_sets.len() - 1);
611 }
612
613 let idx1 = s1.unwrap();
615 let idx2 = s2.unwrap();
616
617 if idx1 == idx2 {
618 return;
619 }
620
621 let set2 = self.alias_sets.remove(idx2);
622 let idx1 = if idx2 < idx1 { idx1 - 1 } else { idx1 };
624 self.alias_sets[idx1].extend(set2);
625
626 if self.values[e1].fields.len() > 0 {
627 self.sync_field_alias(e2, e1, 0, false);
628 }
629 if self.values[e2].fields.len() > 0 {
630 self.sync_field_alias(e1, e2, 0, false);
631 }
632 if self.values[e1].father != None {
633 self.sync_father_alias(e2, e1, idx1);
634 }
635 if self.values[e2].father != None {
636 self.sync_father_alias(e1, e2, idx1);
637 }
638 }
639
640 #[inline(always)]
641 pub fn get_alias_set(&mut self, e: usize) -> Option<FxHashSet<usize>> {
642 if let Some(idx) = self.find_alias_set(e) {
643 Some(self.alias_sets[idx].clone())
644 } else {
645 None
646 }
647 }
648}
649
650pub fn is_no_alias_intrinsic(def_id: DefId) -> bool {
651 let v = [call_mut_opt(), clone_opt(), take_opt()];
652 contains(&v, def_id)
653}