delete dead code

This commit is contained in:
Niko Matsakis 2017-05-01 18:44:25 -04:00
parent 2fa1ba3e7e
commit 74b2783877
5 changed files with 3 additions and 427 deletions

View File

@ -26,15 +26,12 @@
use rustc_data_structures::indexed_vec::IndexVec;
use std::cell::{RefCell, RefMut};
use std::option;
use std::fmt::Debug;
use std::hash::Hash;
use std::iter::{self, Once};
use std::mem;
use std::collections::BTreeMap;
use std::ops::Deref;
use std::rc::Rc;
use std::vec;
use syntax_pos::{Span, DUMMY_SP};
use syntax::symbol::Symbol;
@ -161,67 +158,6 @@ fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
}
}
trait IntoKeyValues<K: Key, V> {
type KeyValues: IntoIterator<Item=(K, V)>;
fn into_key_values(key: &K, value: Self) -> Self::KeyValues;
}
impl<K: Key, V> IntoKeyValues<K, V> for V {
type KeyValues = Once<(K, V)>;
fn into_key_values(key: &K, value: Self) -> Self::KeyValues {
iter::once((key.clone(), value))
}
}
/// Return type for a multi-query, which is a query which may (if it
/// chooses) return more than one (key, value) pair. Construct a
/// `Multi` using `Multi::from(...)`.
pub struct Multi<K: Key, V> {
single: Option<V>,
map: Vec<(K, V)>,
}
impl<K: Key, V> Multi<K, V> {
pub fn iter<'a>(&'a self, key: &'a K) -> impl Iterator<Item = (&'a K, &'a V)> + 'a {
self.single.iter()
.map(move |v| (key, v))
.chain(self.map.iter().map(move |&(ref k, ref v)| (k, v)))
}
}
/// Construct a `Multi` from a single value.
impl<K: Key, V> From<V> for Multi<K, V> {
fn from(value: V) -> Self {
Multi {
single: Some(value),
map: vec![],
}
}
}
/// Construct a `Multi` from a hashmap of (K, V) pairs.
impl<K: Key, V> From<Vec<(K, V)>> for Multi<K, V> {
fn from(value: Vec<(K, V)>) -> Self {
Multi {
single: None,
map: value
}
}
}
impl<K: Key, V> IntoKeyValues<K, V> for Multi<K, V> {
type KeyValues = iter::Chain<option::IntoIter<(K, V)>, vec::IntoIter<(K, V)>>;
fn into_key_values(key: &K, value: Self) -> Self::KeyValues {
value.single
.map(|v| (key.clone(), v))
.into_iter()
.chain(value.map)
}
}
pub struct CycleError<'a, 'tcx: 'a> {
span: Span,
cycle: RefMut<'a, [(Span, Query<'tcx>)]>,
@ -490,14 +426,7 @@ fn try_get_with<F, R>(tcx: TyCtxt<'a, $tcx, 'lcx>,
provider(tcx.global_tcx(), key)
})?;
{
let map = &mut *tcx.maps.$name.borrow_mut();
for (k, v) in IntoKeyValues::<$K, $V>::into_key_values(&key, result) {
map.insert(k, v);
}
}
Ok(f(tcx.maps.$name.borrow().get(&key).expect("value just generated")))
Ok(f(tcx.maps.$name.borrow_mut().entry(key).or_insert(result)))
}
pub fn try_get(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K)
@ -683,20 +612,6 @@ fn default() -> Self {
}
};
// The `multi` modifier indicates a **multiquery**, in which case
// the function returns a `Multi<K,V>` instead of just a value
// `V`.
(tcx: $tcx:tt,
input: (([multi $($other_modifiers:tt)*] $name:tt [$K:ty] [$V:ty]) $($input:tt)*),
output: $output:tt) => {
define_provider_struct! {
tcx: $tcx,
ready: ($name [$K] [Multi<$K,$V>]),
input: ($($input)*),
output: $output
}
};
// Regular queries produce a `V` only.
(tcx: $tcx:tt,
input: (([] $name:tt $K:tt $V:tt) $($input:tt)*),
@ -709,7 +624,7 @@ fn default() -> Self {
}
};
// Skip modifiers other than `multi`.
// Skip modifiers.
(tcx: $tcx:tt,
input: (([$other_modifier:tt $($modifiers:tt)*] $($fields:tt)*) $($input:tt)*),
output: $output:tt) => {

View File

@ -1,249 +0,0 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! MIR-based callgraph.
//!
//! This only considers direct calls
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc_data_structures::graph;
use rustc::mir::*;
use rustc::mir::visit::*;
use rustc::ty;
use rustc::util::nodemap::DefIdMap;
use transform::interprocedural::InterproceduralCx;
pub struct CallGraph {
node_map: DefIdMap<graph::NodeIndex>,
graph: graph::Graph<DefId, ()>
}
impl CallGraph {
pub fn build<'a, 'tcx>(cx: &mut InterproceduralCx<'a, 'tcx>) -> CallGraph {
let mut callgraph = CallGraph {
node_map: DefIdMap(),
graph: graph::Graph::new()
};
for &def_id in cx.tcx.mir_keys(LOCAL_CRATE).iter() {
let idx = callgraph.add_node(def_id);
let mut call_visitor = CallVisitor {
caller: idx,
graph: &mut callgraph
};
if let Some(mir) = cx.ensure_mir_and_read(def_id) {
call_visitor.visit_mir(mir);
}
}
callgraph
}
// Iterate over the strongly-connected components of the graph
pub fn scc_iter(&self) -> SCCIterator {
SCCIterator::new(&self.graph)
}
// Get the def_id for the given graph node
pub fn def_id(&self, node: graph::NodeIndex) -> DefId {
*self.graph.node_data(node)
}
fn add_node(&mut self, id: DefId) -> graph::NodeIndex {
let graph = &mut self.graph;
*self.node_map.entry(id).or_insert_with(|| {
graph.add_node(id)
})
}
}
struct CallVisitor<'a> {
caller: graph::NodeIndex,
graph: &'a mut CallGraph
}
impl<'a, 'tcx> Visitor<'tcx> for CallVisitor<'a> {
fn visit_terminator_kind(&mut self, _block: BasicBlock,
kind: &TerminatorKind<'tcx>, _loc: Location) {
if let TerminatorKind::Call {
func: Operand::Constant(ref f)
, .. } = *kind {
if let ty::TyFnDef(def_id, _, _) = f.ty.sty {
let callee = self.graph.add_node(def_id);
self.graph.graph.add_edge(self.caller, callee, ());
}
}
}
}
struct StackElement<'g> {
node: graph::NodeIndex,
lowlink: usize,
children: graph::AdjacentTargets<'g, DefId, ()>
}
/**
* Iterator over strongly-connected-components using Tarjan's algorithm[1]
*
* [1]: https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
*/
pub struct SCCIterator<'g> {
graph: &'g graph::Graph<DefId, ()>,
index: usize,
node_indices: Vec<Option<usize>>,
scc_stack: Vec<graph::NodeIndex>,
current_scc: Vec<graph::NodeIndex>,
visit_stack: Vec<StackElement<'g>>,
}
impl<'g> SCCIterator<'g> {
pub fn new(graph: &'g graph::Graph<DefId, ()>) -> SCCIterator<'g> {
if graph.len_nodes() == 0 {
return SCCIterator {
graph: graph,
index: 0,
node_indices: Vec::new(),
scc_stack: Vec::new(),
current_scc: Vec::new(),
visit_stack: Vec::new()
};
}
let first = graph::NodeIndex(0);
SCCIterator::with_entry(graph, first)
}
pub fn with_entry(graph: &'g graph::Graph<DefId, ()>,
entry: graph::NodeIndex) -> SCCIterator<'g> {
let mut iter = SCCIterator {
graph: graph,
index: 0,
node_indices: Vec::with_capacity(graph.len_nodes()),
scc_stack: Vec::new(),
current_scc: Vec::new(),
visit_stack: Vec::new()
};
iter.visit_one(entry);
iter
}
fn get_next(&mut self) {
self.current_scc.clear();
while !self.visit_stack.is_empty() {
self.visit_children();
let node = self.visit_stack.pop().unwrap();
if let Some(last) = self.visit_stack.last_mut() {
if last.lowlink > node.lowlink {
last.lowlink = node.lowlink;
}
}
debug!("TarjanSCC: Popped node {:?} : lowlink = {:?}; index = {:?}",
node.node, node.lowlink, self.node_index(node.node).unwrap());
if node.lowlink != self.node_index(node.node).unwrap() {
continue;
}
loop {
let n = self.scc_stack.pop().unwrap();
self.current_scc.push(n);
self.set_node_index(n, !0);
if n == node.node { return; }
}
}
}
fn visit_one(&mut self, node: graph::NodeIndex) {
self.index += 1;
let idx = self.index;
self.set_node_index(node, idx);
self.scc_stack.push(node);
self.visit_stack.push(StackElement {
node: node,
lowlink: self.index,
children: self.graph.successor_nodes(node)
});
debug!("TarjanSCC: Node {:?} : index = {:?}", node, idx);
}
fn visit_children(&mut self) {
while let Some(child) = self.visit_stack.last_mut().unwrap().children.next() {
if let Some(child_num) = self.node_index(child) {
let cur = self.visit_stack.last_mut().unwrap();
if cur.lowlink > child_num {
cur.lowlink = child_num;
}
} else {
self.visit_one(child);
}
}
}
fn node_index(&self, node: graph::NodeIndex) -> Option<usize> {
self.node_indices.get(node.node_id()).and_then(|&idx| idx)
}
fn set_node_index(&mut self, node: graph::NodeIndex, idx: usize) {
let i = node.node_id();
if i >= self.node_indices.len() {
self.node_indices.resize(i + 1, None);
}
self.node_indices[i] = Some(idx);
}
}
impl<'g> Iterator for SCCIterator<'g> {
type Item = Vec<graph::NodeIndex>;
fn next(&mut self) -> Option<Vec<graph::NodeIndex>> {
self.get_next();
if self.current_scc.is_empty() {
// Try a new root for the next SCC, if the node_indices
// map is doesn't contain all nodes, use the smallest one
// with no entry, otherwise find the first empty node.
//
// FIXME: This should probably use a set of precomputed
// roots instead
if self.node_indices.len() < self.graph.len_nodes() {
let idx = graph::NodeIndex(self.node_indices.len());
self.visit_one(idx);
} else {
for idx in 0..self.node_indices.len() {
if self.node_indices[idx].is_none() {
let idx = graph::NodeIndex(idx);
self.visit_one(idx);
break;
}
}
}
self.get_next();
}
if self.current_scc.is_empty() {
None
} else {
Some(self.current_scc.clone())
}
}
}

View File

@ -46,8 +46,7 @@
pub mod diagnostics;
pub mod build;
pub mod callgraph;
mod build;
mod hair;
mod shim;
mod queries;

View File

@ -1,88 +0,0 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::hir::def_id::DefId;
use rustc::mir::Mir;
use rustc::mir::transform::{PassId};
use rustc::ty::steal::Steal;
use rustc::ty::TyCtxt;
use rustc_data_structures::fx::FxHashMap;
/// When writing inter-procedural analyses etc, we need to read (and
/// steal) the MIR for a number of def-ids at once, not all of which
/// are local. This little cache code attempts to remember what you've
/// stolen and so forth. It is more of a placeholder meant to get
/// inlining up and going again, and is probably going to need heavy
/// revision as we scale up to more interesting optimizations.
pub struct InterproceduralCx<'a, 'tcx: 'a> {
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
local_cache: FxHashMap<DefId, Mir<'tcx>>,
}
impl<'a, 'tcx> InterproceduralCx<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
InterproceduralCx {
tcx: tcx,
local_cache: FxHashMap::default(),
}
}
pub fn into_local_mirs(self) -> Vec<(PassId, &'tcx Steal<Mir<'tcx>>)> {
unimplemented!()
}
/// Ensures that the mir for `def_id` is available, if it can be
/// made available.
pub fn ensure_mir(&mut self, def_id: DefId) {
if def_id.is_local() {
self.ensure_mir_and_read(def_id);
}
}
/// Ensures that the mir for `def_id` is available and returns it if possible;
/// returns `None` if this is a cross-crate MIR that is not
/// available from metadata.
pub fn ensure_mir_and_read(&mut self, def_id: DefId) -> Option<&Mir<'tcx>> {
if def_id.is_local() {
Some(self.mir_mut(def_id))
} else {
self.tcx.maybe_item_mir(def_id)
}
}
/// True if the local cache contains MIR for `def-id`.
pub fn contains_mir(&self, def_id: DefId) -> bool {
if def_id.is_local() {
self.local_cache.contains_key(&def_id)
} else {
self.tcx.is_item_mir_available(def_id)
}
}
/// Reads the MIR for `def-id`. If the MIR is local, this will
/// panic if you have not previously invoked `ensure_mir`.
pub fn mir(&self, def_id: DefId) -> Option<&Mir<'tcx>> {
if def_id.is_local() {
match self.local_cache.get(&def_id) {
Some(p) => Some(p),
None => {
panic!("MIR for local def-id `{:?}` not previously ensured", def_id)
}
}
} else {
self.tcx.maybe_item_mir(def_id)
}
}
pub fn mir_mut(&mut self, def_id: DefId) -> &mut Mir<'tcx> {
assert!(def_id.is_local(), "cannot get mutable mir of remote entry");
unimplemented!()
}
}

View File

@ -26,7 +26,6 @@
pub mod instcombine;
pub mod copy_prop;
pub mod inline;
pub mod interprocedural;
pub(crate) fn provide(providers: &mut Providers) {
self::qualify_consts::provide(providers);