Print value aliases at referrent definition (#492)

* Print value aliases at referrent definition

Closes #488.
This commit is contained in:
Kaz Wesley
2018-09-04 15:02:46 -07:00
committed by Dan Gohman
parent 4045d50b7b
commit 7e571f4a49
4 changed files with 131 additions and 24 deletions

View File

@@ -1,6 +1,6 @@
//! Data flow graph tracking Instructions, Values, and EBBs.
use entity::{EntityMap, PrimaryMap};
use entity::{self, EntityMap, PrimaryMap};
use ir;
use ir::builder::ReplaceBuilder;
use ir::extfunc::ExtFuncData;
@@ -149,6 +149,38 @@ fn resolve_aliases(values: &PrimaryMap<Value, ValueData>, value: Value) -> Value
}
}
/// Iterator over all Values in a DFG
pub struct Values<'a> {
inner: entity::Iter<'a, Value, ValueData>,
}
/// Check for non-values
fn valid_valuedata(data: &ValueData) -> bool {
if let &ValueData::Alias {
ty: types::VOID,
original,
} = data
{
if original == Value::reserved_value() {
return false;
}
}
return true;
}
impl<'a> Iterator for Values<'a> {
type Item = Value;
fn next(&mut self) -> Option<Self::Item> {
return self
.inner
.by_ref()
.filter(|kv| valid_valuedata(kv.1))
.next()
.map(|kv| kv.0);
}
}
/// Handling values.
///
/// Values are either EBB parameters or instruction results.
@@ -158,6 +190,13 @@ impl DataFlowGraph {
self.values.push(data)
}
/// Get an iterator over all values.
pub fn values<'a>(&'a self) -> Values {
Values {
inner: self.values.iter(),
}
}
/// Check if a value reference is valid.
pub fn value_is_valid(&self, v: Value) -> bool {
self.values.is_valid(v)
@@ -932,9 +971,9 @@ impl DataFlowGraph {
}
/// Create a new value alias. This is only for use by the parser to create
/// aliases with specific values.
/// aliases with specific values, and the printer for testing.
#[cold]
pub fn make_value_alias_for_parser(&mut self, src: Value, dest: Value) {
pub fn make_value_alias_for_serialization(&mut self, src: Value, dest: Value) {
assert_ne!(src, Value::reserved_value());
assert_ne!(dest, Value::reserved_value());
@@ -951,9 +990,9 @@ impl DataFlowGraph {
/// If `v` is already defined as an alias, return its destination value.
/// Otherwise return None. This allows the parser to coalesce identical
/// alias definitions.
/// alias definitions, and the printer to identify an alias's immediate target.
#[cold]
pub fn value_alias_dest_for_parser(&self, v: Value) -> Option<Value> {
pub fn value_alias_dest_for_serialization(&self, v: Value) -> Option<Value> {
if let ValueData::Alias { original, .. } = self.values[v] {
Some(original)
} else {