Skip to content

Commit

Permalink
Merge pull request #49 from sbillig/no-alias
Browse files Browse the repository at this point in the history
Remove ValueData::Alias
  • Loading branch information
Y-Nak authored Aug 21, 2024
2 parents e695df7 + 78c997e commit fbb42c4
Show file tree
Hide file tree
Showing 20 changed files with 273 additions and 186 deletions.
27 changes: 23 additions & 4 deletions crates/codegen/src/optim/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ impl GvnSolver {
value: Value,
edge: Edge,
) -> Value {
let mut rep_value = self.leader(func.dfg.resolve_alias(value));
let mut rep_value = self.leader(value);

if let Some(inferred_value) = self.infer_value_impl(edge, rep_value) {
rep_value = inferred_value;
Expand Down Expand Up @@ -1334,6 +1334,8 @@ struct RedundantCodeRemover<'a> {

/// Record resolved value phis.
resolved_value_phis: FxHashMap<ValuePhi, Value>,

renames: FxHashMap<Value, Value>,
}

impl<'a> RedundantCodeRemover<'a> {
Expand All @@ -1342,9 +1344,25 @@ impl<'a> RedundantCodeRemover<'a> {
solver,
avail_set: SecondaryMap::default(),
resolved_value_phis: FxHashMap::default(),
renames: FxHashMap::default(),
}
}

fn change_to_alias(&mut self, func: &mut Function, value: Value, target: Value) {
func.dfg.change_to_alias(value, target);
self.renames.insert(value, target);
}

fn resolve_alias(&self, mut value: Value) -> Value {
for _ in 0..1 + self.renames.len() {
match self.renames.get(&value) {
Some(v) => value = *v,
None => return value,
}
}
panic!("alias loop detected");
}

/// The entry function of redundant code removal.
///
/// This function
Expand Down Expand Up @@ -1421,7 +1439,7 @@ impl<'a> RedundantCodeRemover<'a> {

// Use representative value if the class is in avail set.
if let Some(value) = avails.get(&class) {
func.dfg.change_to_alias(insn_result, *value);
self.change_to_alias(func, insn_result, *value);
inserter.remove_insn(func);
continue;
}
Expand Down Expand Up @@ -1469,7 +1487,8 @@ impl<'a> RedundantCodeRemover<'a> {
ty,
block,
);
func.dfg.change_to_alias(insn_result, value);

self.change_to_alias(func, insn_result, value);
inserter.remove_insn(func);
continue;
}
Expand Down Expand Up @@ -1537,7 +1556,7 @@ impl<'a> RedundantCodeRemover<'a> {
for (value_phi, phi_block) in &phi_insn.args {
let resolved =
self.resolve_value_phi(func, inserter, value_phi, ty, *phi_block);
phi.append_phi_arg(resolved, *phi_block);
phi.append_phi_arg(self.resolve_alias(resolved), *phi_block);
}

// Insert new phi insn to top of the phi_insn block.
Expand Down
2 changes: 1 addition & 1 deletion crates/codegen/src/optim/licm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl LicmSolver {

/// Returns preheader of the loop.
/// 1. If there is natural preheader for the loop, then returns it without any modification of
/// function.
/// function.
/// 2. If no natural preheader for the loop, then create the preheader and modify function
/// layout, `cfg`, and `lpt`.
fn create_preheader(
Expand Down
2 changes: 0 additions & 2 deletions crates/codegen/src/optim/sccp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ impl SccpSolver {
for (i, from) in func.dfg.phi_blocks(insn).iter().enumerate() {
if self.is_reachable(func, *from, block) {
let phi_arg = func.dfg.insn_arg(insn, i);
let phi_arg = func.dfg.resolve_alias(phi_arg);

let v_cell = self.lattice[phi_arg];
eval_result = eval_result.join(v_cell);
}
Expand Down
10 changes: 5 additions & 5 deletions crates/codegen/src/optim/simplify_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use generated_code::{Context, SimplifyRawResult};

pub fn simplify_insn(dfg: &mut DataFlowGraph, insn: Insn) -> Option<SimplifyResult> {
if dfg.is_phi(insn) {
return simplify_phi(dfg, dfg.insn_data(insn));
return simplify_phi(dfg.insn_data(insn));
}

let mut ctx = SimplifyContext::new(dfg);
Expand All @@ -27,7 +27,7 @@ pub fn simplify_insn(dfg: &mut DataFlowGraph, insn: Insn) -> Option<SimplifyResu

pub fn simplify_insn_data(dfg: &mut DataFlowGraph, data: InsnData) -> Option<SimplifyResult> {
if matches!(data, InsnData::Phi { .. }) {
return simplify_phi(dfg, &data);
return simplify_phi(&data);
}

let mut ctx = SimplifyContext::new(dfg);
Expand All @@ -40,12 +40,12 @@ pub enum SimplifyResult {
Insn(InsnData),
}

fn simplify_phi(dfg: &DataFlowGraph, insn_data: &InsnData) -> Option<SimplifyResult> {
fn simplify_phi(insn_data: &InsnData) -> Option<SimplifyResult> {
match insn_data {
InsnData::Phi { values, .. } => {
let mut values = values.iter().copied();
let first_value = values.next().unwrap();
if values.all(|value| dfg.is_same_value(first_value, value)) {
if values.all(|value| value == first_value) {
Some(SimplifyResult::Value(first_value))
} else {
None
Expand Down Expand Up @@ -499,7 +499,7 @@ impl<'a> generated_code::Context for SimplifyContext<'a> {

fn is_eq(&mut self, arg0: ExprValue, arg1: ExprValue) -> Option<()> {
match (arg0.as_value(), arg1.as_value()) {
(Some(val1), Some(val2)) => self.dfg.is_same_value(val1, val2),
(Some(val1), Some(val2)) => val1 == val2,
_ => arg0 == arg1,
}
.then_some(())
Expand Down
8 changes: 4 additions & 4 deletions crates/filecheck/fixtures/adce/all_dests_remove.sntn
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ func public %all_dests_removed() -> i8 {
}

# check: block0:
# nextln: v1.i32 = add v0 v0;
# nextln: v1.i8 = add v0 v0;
# nextln: jump block3;
# nextln:
# nextln: block3:
# nextln: return v1;
func public %all_dests_removed2(v0.i32) -> i8 {
func public %all_dests_removed2(v0.i8) -> i8 {
block0:
v1.i32 = add v0 v0;
br_table v0 (v1 block1) (2.i32 block2);
v1.i8 = add v0 v0;
br_table v0 (v1 block1) (2.i8 block2);

block1:
v3.i8 = add v0 -10.i8;
Expand Down
2 changes: 1 addition & 1 deletion crates/filecheck/fixtures/adce/whole_loop_removed.sntn
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ target = "evm-ethereum-london"
# nextln: return 1.i8;
func public %whole_loop_removed() -> i8 {
block0:
v0.i1 = or 1.i8 0.i8;
v0.i8 = or 1.i8 0.i8;
v1.i8 = sext v0;
jump block2;

Expand Down
6 changes: 3 additions & 3 deletions crates/filecheck/fixtures/gvn/fold_predicted_value.sntn
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ target = "evm-ethereum-london"
# nextln: return 1.i1;
# check: block2:
# nextln: return 0.i1;
func public %fold_with_predicted_value(v0.i1) -> i8 {
func public %fold_with_predicted_value(v0.i1) -> i1 {
block0:
br v0 block1 block2;

block1:
v1.i8 = or v0 v0;
v1.i1 = or v0 v0;
return v1;

block2:
v2.i8 = or v0 v0;
v2.i1 = or v0 v0;
return v2;
}
4 changes: 2 additions & 2 deletions crates/filecheck/fixtures/insn_simplify/neg.sntn
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func public %neg0(v0.i8) -> i8 {
# check: v2.i16 = add v0 1.i16;
func public %neg1(v0.i16) -> i16 {
block0:
v1.i8 = not v0;
v2.i8 = neg v1;
v1.i16 = not v0;
v2.i16 = neg v1;
return v2;
}
12 changes: 6 additions & 6 deletions crates/interpreter/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ mod test {
v0.i16 = add 3.i16 4.i16;
v1.i16 = sub v0 1.i16;
v2.i16 = udiv v1 2.i16;
v3.i8 = sdiv v2 65535.i16;
v3.i16 = sdiv v2 65535.i16;
return v3;
}
";
Expand Down Expand Up @@ -380,7 +380,7 @@ mod test {
block0:
v0.*i32 = alloca i32;
store @memory v0 1.i32;
v1.*i32 = load @memory v0;
v1.i32 = load @memory v0;
return v1;
}
";
Expand Down Expand Up @@ -559,10 +559,10 @@ mod test {
let input = "
target = \"evm-ethereum-london\"
func private %test() -> *i1 {
func private %test() -> **i32 {
block0:
v0.*[*i32; 3] = alloca [*i32; 3];
v1.*i32 = gep v0 2.i8;
v1.**i32 = gep v0 2.i8;
return v1;
}
";
Expand All @@ -581,10 +581,10 @@ mod test {
type %s1 = {i32, [i16; 3], [i8; 2]};
func private %test() -> *i1 {
func private %test() -> *i8 {
block0:
v0.*%s1 = alloca %s1;
v1.*i1 = gep v0 2.i8 1.i8;
v1.*i8 = gep v0 2.i8 1.i8;
return v1;
}
";
Expand Down
85 changes: 59 additions & 26 deletions crates/ir/src/dfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::collections::BTreeSet;

use cranelift_entity::{entity_impl, packed_option::PackedOption, PrimaryMap, SecondaryMap};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;

use crate::{global_variable::ConstantValue, module::ModuleCtx, GlobalVariable};

Expand Down Expand Up @@ -82,23 +83,15 @@ impl DataFlowGraph {
}

pub fn change_to_alias(&mut self, value: Value, alias: Value) {
self.values[value] = ValueData::Alias {
alias: self.resolve_alias(alias),
}
}

pub fn resolve_alias(&self, mut value: Value) -> Value {
for _ in 0..self.values.len() {
match self.values[value] {
ValueData::Insn { .. }
| ValueData::Arg { .. }
| ValueData::Immediate { .. }
| ValueData::Global { .. } => return value,
ValueData::Alias { alias } => value = alias,
let mut users = std::mem::take(&mut self.users[value]);
for insn in &users {
for arg in self.insns[*insn].args_mut() {
if *arg == value {
*arg = alias;
}
}
}

panic!("alias loop detected");
self.users[alias].append(&mut users);
}

pub fn make_result(&mut self, insn: Insn) -> Option<ValueData> {
Expand Down Expand Up @@ -159,21 +152,18 @@ impl DataFlowGraph {
}

pub fn value_insn(&self, value: Value) -> Option<Insn> {
let value = self.resolve_alias(value);
match self.value_data(value) {
ValueData::Insn { insn, .. } => Some(*insn),
_ => None,
}
}

pub fn value_ty(&self, value: Value) -> Type {
let value = self.resolve_alias(value);
match &self.values[value] {
ValueData::Insn { ty, .. }
| ValueData::Arg { ty, .. }
| ValueData::Immediate { ty, .. }
| ValueData::Global { ty, .. } => *ty,
ValueData::Alias { .. } => unreachable!(),
}
}

Expand All @@ -182,7 +172,6 @@ impl DataFlowGraph {
}

pub fn value_imm(&self, value: Value) -> Option<Immediate> {
let value = self.resolve_alias(value);
match self.value_data(value) {
ValueData::Immediate { imm, .. } => Some(*imm),
ValueData::Global { gv, .. } => self.ctx.with_gv_store(|s| {
Expand All @@ -199,7 +188,6 @@ impl DataFlowGraph {
}

pub fn value_gv(&self, value: Value) -> Option<GlobalVariable> {
let value = self.resolve_alias(value);
match self.value_data(value) {
ValueData::Global { gv, .. } => Some(*gv),
_ => None,
Expand Down Expand Up @@ -262,7 +250,57 @@ impl DataFlowGraph {
}

pub fn remove_branch_dest(&mut self, insn: Insn, dest: Block) {
self.insns[insn].remove_branch_dest(dest)
let this = &mut self.insns[insn];
match this {
InsnData::Jump { .. } => panic!("can't remove destination from `Jump` insn"),

InsnData::Branch { dests, args } => {
let remain = if dests[0] == dest {
dests[1]
} else if dests[1] == dest {
dests[0]
} else {
panic!("no dests found in the branch destination")
};
self.users[args[0]].remove(&insn);
*this = InsnData::jump(remain);
}

InsnData::BrTable {
default,
table,
args,
} => {
if Some(dest) == *default {
*default = None;
} else if let Some((lhs, rest)) = args.split_first() {
type V<T> = SmallVec<[T; 8]>;
let (keep, drop): (V<_>, V<_>) = table
.iter()
.copied()
.zip(rest.iter().copied())
.partition(|(b, _)| *b != dest);
let (b, mut a): (V<_>, V<_>) = keep.into_iter().unzip();
a.insert(0, *lhs);
*args = a;
*table = b;

for (_, val) in drop {
self.users[val].remove(&insn);
}
}

let branch_info = this.analyze_branch();
if branch_info.dests_num() == 1 {
for val in this.args() {
self.users[*val].remove(&insn);
}
*this = InsnData::jump(branch_info.iter_dests().next().unwrap());
}
}

_ => panic!("not a branch"),
}
}

pub fn rewrite_branch_dest(&mut self, insn: Insn, from: Block, to: Block) {
Expand All @@ -281,18 +319,13 @@ impl DataFlowGraph {
self.insns[insn].is_branch()
}

pub fn is_same_value(&self, v0: Value, v1: Value) -> bool {
self.resolve_alias(v0) == self.resolve_alias(v1)
}

/// Returns `true` if `value` is an immediate.
pub fn is_imm(&self, value: Value) -> bool {
self.value_imm(value).is_some()
}

/// Returns `true` if `value` is a function argument.
pub fn is_arg(&self, value: Value) -> bool {
let value = self.resolve_alias(value);
matches!(self.value_data(value), ValueData::Arg { .. })
}
}
Expand Down
Loading

0 comments on commit fbb42c4

Please sign in to comment.