mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 19:58:32 +00:00
Use DefPathHash instead of HirId to break cycles.
This commit is contained in:
parent
0677edc86e
commit
e1b36f5ae2
@ -1,7 +1,6 @@
|
|||||||
//! Inlining pass for MIR functions
|
//! Inlining pass for MIR functions
|
||||||
|
|
||||||
use rustc_attr::InlineAttr;
|
use rustc_attr::InlineAttr;
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
||||||
@ -88,7 +87,6 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
|
|||||||
tcx,
|
tcx,
|
||||||
param_env,
|
param_env,
|
||||||
codegen_fn_attrs: tcx.codegen_fn_attrs(def_id),
|
codegen_fn_attrs: tcx.codegen_fn_attrs(def_id),
|
||||||
hir_id,
|
|
||||||
history: Vec::new(),
|
history: Vec::new(),
|
||||||
changed: false,
|
changed: false,
|
||||||
};
|
};
|
||||||
@ -102,8 +100,6 @@ struct Inliner<'tcx> {
|
|||||||
param_env: ParamEnv<'tcx>,
|
param_env: ParamEnv<'tcx>,
|
||||||
/// Caller codegen attributes.
|
/// Caller codegen attributes.
|
||||||
codegen_fn_attrs: &'tcx CodegenFnAttrs,
|
codegen_fn_attrs: &'tcx CodegenFnAttrs,
|
||||||
/// Caller HirID.
|
|
||||||
hir_id: hir::HirId,
|
|
||||||
/// Stack of inlined Instances.
|
/// Stack of inlined Instances.
|
||||||
history: Vec<ty::Instance<'tcx>>,
|
history: Vec<ty::Instance<'tcx>>,
|
||||||
/// Indicates that the caller body has been modified.
|
/// Indicates that the caller body has been modified.
|
||||||
@ -179,7 +175,8 @@ impl<'tcx> Inliner<'tcx> {
|
|||||||
caller_body: &Body<'tcx>,
|
caller_body: &Body<'tcx>,
|
||||||
callee: &Instance<'tcx>,
|
callee: &Instance<'tcx>,
|
||||||
) -> Result<(), &'static str> {
|
) -> Result<(), &'static str> {
|
||||||
if callee.def_id() == caller_body.source.def_id() {
|
let caller_def_id = caller_body.source.def_id();
|
||||||
|
if callee.def_id() == caller_def_id {
|
||||||
return Err("self-recursion");
|
return Err("self-recursion");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,22 +212,19 @@ impl<'tcx> Inliner<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(callee_def_id) = callee.def_id().as_local() {
|
if let Some(callee_def_id) = callee.def_id().as_local() {
|
||||||
let callee_hir_id = self.tcx.hir().local_def_id_to_hir_id(callee_def_id);
|
|
||||||
// Avoid a cycle here by only using `instance_mir` only if we have
|
// Avoid a cycle here by only using `instance_mir` only if we have
|
||||||
// a lower `HirId` than the callee. This ensures that the callee will
|
// a lower `DefPathHash` than the callee. This ensures that the callee will
|
||||||
// not inline us. This trick only works without incremental compilation.
|
// not inline us. This trick even works with incremental compilation,
|
||||||
// So don't do it if that is enabled.
|
// since `DefPathHash` is stable.
|
||||||
if !self.tcx.dep_graph.is_fully_enabled() && self.hir_id.index() < callee_hir_id.index()
|
if self.tcx.def_path_hash(caller_def_id)
|
||||||
|
< self.tcx.def_path_hash(callee_def_id.to_def_id())
|
||||||
{
|
{
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we know for sure that the function we're calling will itself try to
|
// If we know for sure that the function we're calling will itself try to
|
||||||
// call us, then we avoid inlining that function.
|
// call us, then we avoid inlining that function.
|
||||||
if self
|
if self.tcx.mir_callgraph_reachable((*callee, caller_def_id.expect_local())) {
|
||||||
.tcx
|
|
||||||
.mir_callgraph_reachable((*callee, caller_body.source.def_id().expect_local()))
|
|
||||||
{
|
|
||||||
return Err("caller might be reachable from callee (query cycle avoidance)");
|
return Err("caller might be reachable from callee (query cycle avoidance)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user