Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIR] Dataflow framework, constant propagation and dead code elimination #35608

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
64afc5e
Make BitVec::contains panic-less
nagisa Aug 2, 2016
5fdc839
Expand BitVec functionality slightly
nagisa Aug 2, 2016
34d0545
[MIR] Utility to retrieve base variable of Lvalue
nagisa Aug 2, 2016
ccdc81a
Add a MIR dataflow framework (again)
nagisa Aug 5, 2016
8b8ccf0
[MIR] Constant propagation
nagisa Aug 6, 2016
ba6a8fb
Count time taken by MIR passes
nagisa Aug 6, 2016
2cc114c
Count and report time taken by MIR passes
nagisa Aug 7, 2016
d203b9c
Comments, todos and small improvements
nagisa Aug 7, 2016
18f65dd
Add Rvalue::is_pure
nagisa Aug 7, 2016
97bfde3
Fix compilation
nagisa Aug 9, 2016
61a58f1
Fix join function for CsLattice
nagisa Aug 11, 2016
efbea54
Rename dead code removal pass to a proper-er name
nagisa Aug 11, 2016
b15bb6d
Add some constant propagation tests
nagisa Aug 11, 2016
f78274c
Clean-up the ConstLattice; Propagate global state
nagisa Aug 15, 2016
61871d4
Re-add a way to specify initial state
nagisa Aug 15, 2016
1b3e945
Rebase fallout
nagisa Aug 15, 2016
935dc8d
Make SwitchInt switch on Operand
nagisa Aug 15, 2016
3e2e8b9
Disallow to optimise out constants in OOB tests
nagisa Aug 15, 2016
e00862b
A way to remove otherwise unused locals from MIR
nagisa Aug 16, 2016
c352ae2
Do not run the DA+ConstProp before DropElab
nagisa Aug 16, 2016
708487b
Rebase fallout
nagisa Aug 16, 2016
0791d56
Do not be overly aggressive optimising MIR with -g
nagisa Aug 18, 2016
9b227dd
More bitvec tests
nagisa Aug 18, 2016
ec8e500
Fix aliasing in const-propagate
nagisa Aug 19, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
67 changes: 63 additions & 4 deletions src/librustc/mir/repr.rs
Expand Up @@ -21,6 +21,8 @@ use ty::{self, AdtDef, ClosureSubsts, Region, Ty};
use util::ppaux;
use rustc_back::slice;
use hir::InlineAsm;
use hir::BinOp_ as HirBinOp;
use hir::UnOp as HirUnOp;
use std::ascii;
use std::borrow::{Cow};
use std::cell::Ref;
Expand All @@ -36,7 +38,7 @@ use super::cache::Cache;
macro_rules! newtype_index {
($name:ident, $debug_name:expr) => (
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord,
RustcEncodable, RustcDecodable)]
RustcEncodable, RustcDecodable)]
pub struct $name(u32);

impl Idx for $name {
Expand Down Expand Up @@ -393,7 +395,7 @@ pub enum TerminatorKind<'tcx> {
/// to one of the targets, and otherwise fallback to `otherwise`
SwitchInt {
/// discriminant value being tested
discr: Lvalue<'tcx>,
discr: Operand<'tcx>,

/// type of value being tested
switch_ty: Ty<'tcx>,
Expand Down Expand Up @@ -725,7 +727,7 @@ newtype_index!(Local, "local");

/// A path to a value; something that can be evaluated without
/// changing or disturbing program state.
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Lvalue<'tcx> {
/// local variable declared by the user
Var(Var),
Expand All @@ -747,6 +749,16 @@ pub enum Lvalue<'tcx> {
Projection(Box<LvalueProjection<'tcx>>),
}

impl<'tcx> Lvalue<'tcx> {
pub fn base(&self) -> &Lvalue<'tcx> {
let mut lval = self;
while let Lvalue::Projection(ref proj) = *lval {
lval = &proj.base;
}
lval
}
}

/// The `Projection` data structure defines things of the form `B.x`
/// or `*B` or `B[index]`. Note that it is parameterized because it is
/// shared between `Constant` and `Lvalue`. See the aliases
Expand Down Expand Up @@ -883,7 +895,7 @@ pub struct VisibilityScopeData {
/// These are values that can appear inside an rvalue (or an index
/// lvalue). They are intentionally limited to prevent rvalues from
/// being nested in one another.
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Operand<'tcx> {
Consume(Lvalue<'tcx>),
Constant(Constant<'tcx>),
Expand Down Expand Up @@ -1010,6 +1022,27 @@ impl BinOp {
_ => false
}
}

pub fn to_hir_binop(self) -> HirBinOp {
match self {
BinOp::Add => HirBinOp::BiAdd,
BinOp::Sub => HirBinOp::BiSub,
BinOp::Mul => HirBinOp::BiMul,
BinOp::Div => HirBinOp::BiDiv,
BinOp::Rem => HirBinOp::BiRem,
BinOp::BitXor => HirBinOp::BiBitXor,
BinOp::BitAnd => HirBinOp::BiBitAnd,
BinOp::BitOr => HirBinOp::BiBitOr,
BinOp::Shl => HirBinOp::BiShl,
BinOp::Shr => HirBinOp::BiShr,
BinOp::Eq => HirBinOp::BiEq,
BinOp::Ne => HirBinOp::BiNe,
BinOp::Lt => HirBinOp::BiLt,
BinOp::Gt => HirBinOp::BiGt,
BinOp::Le => HirBinOp::BiLe,
BinOp::Ge => HirBinOp::BiGe
}
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
Expand All @@ -1020,6 +1053,32 @@ pub enum UnOp {
Neg,
}

impl UnOp {
pub fn to_hir_unop(self) -> HirUnOp {
match self {
UnOp::Not => HirUnOp::UnNot,
UnOp::Neg => HirUnOp::UnNeg,
}
}
}

impl<'tcx> Rvalue<'tcx> {
pub fn is_pure(&self) -> bool {
use self::Rvalue::*;
match *self {
// Arbitrary side effects
InlineAsm { .. } |
// Side effect: allocation
Box(_) |
// Side effect: assertion
CheckedBinaryOp(..) => false,
// No side effects
Use(_) | Repeat(..) | Len(_) | Cast(..) | BinaryOp(..) | UnaryOp(..) |
Ref(..) | Aggregate(..) => true
}
}
}

impl<'tcx> Debug for Rvalue<'tcx> {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
use self::Rvalue::*;
Expand Down
23 changes: 0 additions & 23 deletions src/librustc/mir/tcx.rs
Expand Up @@ -247,26 +247,3 @@ impl BorrowKind {
}
}
}

impl BinOp {
pub fn to_hir_binop(self) -> hir::BinOp_ {
match self {
BinOp::Add => hir::BinOp_::BiAdd,
BinOp::Sub => hir::BinOp_::BiSub,
BinOp::Mul => hir::BinOp_::BiMul,
BinOp::Div => hir::BinOp_::BiDiv,
BinOp::Rem => hir::BinOp_::BiRem,
BinOp::BitXor => hir::BinOp_::BiBitXor,
BinOp::BitAnd => hir::BinOp_::BiBitAnd,
BinOp::BitOr => hir::BinOp_::BiBitOr,
BinOp::Shl => hir::BinOp_::BiShl,
BinOp::Shr => hir::BinOp_::BiShr,
BinOp::Eq => hir::BinOp_::BiEq,
BinOp::Ne => hir::BinOp_::BiNe,
BinOp::Lt => hir::BinOp_::BiLt,
BinOp::Gt => hir::BinOp_::BiGt,
BinOp::Le => hir::BinOp_::BiLe,
BinOp::Ge => hir::BinOp_::BiGe
}
}
}
25 changes: 17 additions & 8 deletions src/librustc/mir/transform.rs
Expand Up @@ -15,7 +15,10 @@ use mir::mir_map::MirMap;
use mir::repr::{Mir, Promoted};
use ty::TyCtxt;
use syntax::ast::NodeId;
use util::common::time;
use session::Session;

use std::borrow::Cow;
use std::fmt;

/// Where a specific Mir comes from.
Expand Down Expand Up @@ -72,14 +75,19 @@ impl<'a, 'tcx> MirSource {
/// Various information about pass.
pub trait Pass {
// fn should_run(Session) to check if pass should run?
fn name(&self) -> &str {
fn name<'a>(&self) -> Cow<'static, str> {
let name = unsafe { ::std::intrinsics::type_name::<Self>() };
if let Some(tail) = name.rfind(":") {
&name[tail+1..]
Cow::from(&name[tail+1..])
} else {
name
Cow::from(name)
}
}
fn should_run(&self, session: &Session) -> bool {
// Always run passes by default unless MIR passes have been explicitly turned off with -Z
// mir-opt-level=0
session.opts.mir_opt_level >= 1
}
fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> { None }
}

Expand Down Expand Up @@ -162,11 +170,12 @@ impl<'a, 'tcx> Passes {
}

pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, map: &mut MirMap<'tcx>) {
for pass in &mut self.plugin_passes {
pass.run_pass(tcx, map, &mut self.pass_hooks);
}
for pass in &mut self.passes {
pass.run_pass(tcx, map, &mut self.pass_hooks);
let Passes { ref mut passes, ref mut plugin_passes, ref mut pass_hooks } = *self;
for pass in plugin_passes.iter_mut().chain(passes.iter_mut()) {
let name = pass.name();
if pass.should_run(&tcx.sess) {
time(tcx.sess.time_passes(), &*name, || pass.run_pass(tcx, map, pass_hooks));
}
}
}

Expand Down