Skip to content

Commit 8b8ccf0

Browse files
committed
[MIR] Constant propagation
Based on the shiny new dataflow framework, comes the constant propagation on MIR! Propagates constants, evaluates a number of binary, unary and cast operations and simplifies CFG based on the evaluations done. Code comments coming in subsequent PRs. Fixes rust-lang#35316
1 parent ccdc81a commit 8b8ccf0

File tree

8 files changed

+585
-143
lines changed

8 files changed

+585
-143
lines changed

src/librustc/mir/repr.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ use ty::{self, AdtDef, ClosureSubsts, Region, Ty};
2121
use util::ppaux;
2222
use rustc_back::slice;
2323
use hir::InlineAsm;
24+
use hir::BinOp_ as HirBinOp;
25+
use hir::UnOp as HirUnOp;
2426
use std::ascii;
2527
use std::borrow::{Cow};
2628
use std::cell::Ref;
@@ -1020,6 +1022,27 @@ impl BinOp {
10201022
_ => false
10211023
}
10221024
}
1025+
1026+
pub fn to_hir_binop(self) -> HirBinOp {
1027+
match self {
1028+
BinOp::Add => HirBinOp::BiAdd,
1029+
BinOp::Sub => HirBinOp::BiSub,
1030+
BinOp::Mul => HirBinOp::BiMul,
1031+
BinOp::Div => HirBinOp::BiDiv,
1032+
BinOp::Rem => HirBinOp::BiRem,
1033+
BinOp::BitXor => HirBinOp::BiBitXor,
1034+
BinOp::BitAnd => HirBinOp::BiBitAnd,
1035+
BinOp::BitOr => HirBinOp::BiBitOr,
1036+
BinOp::Shl => HirBinOp::BiShl,
1037+
BinOp::Shr => HirBinOp::BiShr,
1038+
BinOp::Eq => HirBinOp::BiEq,
1039+
BinOp::Ne => HirBinOp::BiNe,
1040+
BinOp::Lt => HirBinOp::BiLt,
1041+
BinOp::Gt => HirBinOp::BiGt,
1042+
BinOp::Le => HirBinOp::BiLe,
1043+
BinOp::Ge => HirBinOp::BiGe
1044+
}
1045+
}
10231046
}
10241047

10251048
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
@@ -1030,6 +1053,15 @@ pub enum UnOp {
10301053
Neg,
10311054
}
10321055

1056+
impl UnOp {
1057+
pub fn to_hir_unop(self) -> HirUnOp {
1058+
match self {
1059+
UnOp::Not => HirUnOp::UnNot,
1060+
UnOp::Neg => HirUnOp::UnNeg,
1061+
}
1062+
}
1063+
}
1064+
10331065
impl<'tcx> Debug for Rvalue<'tcx> {
10341066
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
10351067
use self::Rvalue::*;

src/librustc/mir/tcx.rs

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,26 @@ impl<'tcx> TypeFoldable<'tcx> for LvalueTy<'tcx> {
113113
}
114114
}
115115

116-
impl<'tcx> Lvalue<'tcx> {
117-
pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> LvalueTy<'tcx> {
118-
match self {
119-
&Lvalue::Var(index) =>
120-
LvalueTy::Ty { ty: mir.var_decls[index].ty },
121-
&Lvalue::Temp(index) =>
122-
LvalueTy::Ty { ty: mir.temp_decls[index].ty },
123-
&Lvalue::Arg(index) =>
124-
LvalueTy::Ty { ty: mir.arg_decls[index].ty },
125-
&Lvalue::Static(def_id) =>
116+
impl<'a, 'gcx, 'tcx> Mir<'tcx> {
117+
pub fn operand_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
118+
operand: &Operand<'tcx>)
119+
-> Ty<'tcx>
120+
{
121+
match *operand {
122+
Operand::Consume(ref l) => self.lvalue_ty(tcx, l).to_ty(tcx),
123+
Operand::Constant(ref c) => c.ty,
124+
}
125+
}
126+
127+
pub fn ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, lvalue: &Lvalue<'tcx>) -> LvalueTy<'tcx> {
128+
match *lvalue {
129+
Lvalue::Var(index) =>
130+
LvalueTy::Ty { ty: self.var_decls[index].ty },
131+
Lvalue::Temp(index) =>
132+
LvalueTy::Ty { ty: self.temp_decls[index].ty },
133+
Lvalue::Arg(index) =>
134+
LvalueTy::Ty { ty: self.arg_decls[index].ty },
135+
Lvalue::Static(def_id) =>
126136
LvalueTy::Ty { ty: tcx.lookup_item_type(def_id).ty },
127137
&Lvalue::ReturnPointer =>
128138
LvalueTy::Ty { ty: mir.return_ty },
@@ -153,17 +163,17 @@ impl<'tcx> Rvalue<'tcx> {
153163
}
154164
))
155165
}
156-
&Rvalue::Len(..) => Some(tcx.types.usize),
157-
&Rvalue::Cast(_, _, ty) => Some(ty),
158-
&Rvalue::BinaryOp(op, ref lhs, ref rhs) => {
159-
let lhs_ty = lhs.ty(mir, tcx);
160-
let rhs_ty = rhs.ty(mir, tcx);
161-
Some(op.ty(tcx, lhs_ty, rhs_ty))
166+
Rvalue::Len(..) => Some(tcx.types.usize),
167+
Rvalue::Cast(_, _, ty) => Some(ty),
168+
Rvalue::BinaryOp(op, ref lhs, ref rhs) => {
169+
let lhs_ty = self.operand_ty(tcx, lhs);
170+
let rhs_ty = self.operand_ty(tcx, rhs);
171+
Some(binop_ty(tcx, op, lhs_ty, rhs_ty))
162172
}
163-
&Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) => {
164-
let lhs_ty = lhs.ty(mir, tcx);
165-
let rhs_ty = rhs.ty(mir, tcx);
166-
let ty = op.ty(tcx, lhs_ty, rhs_ty);
173+
Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) => {
174+
let lhs_ty = self.operand_ty(tcx, lhs);
175+
let rhs_ty = self.operand_ty(tcx, rhs);
176+
let ty = binop_ty(tcx, op, lhs_ty, rhs_ty);
167177
let ty = tcx.mk_tup(vec![ty, tcx.types.bool]);
168178
Some(ty)
169179
}
@@ -247,26 +257,3 @@ impl BorrowKind {
247257
}
248258
}
249259
}
250-
251-
impl BinOp {
252-
pub fn to_hir_binop(self) -> hir::BinOp_ {
253-
match self {
254-
BinOp::Add => hir::BinOp_::BiAdd,
255-
BinOp::Sub => hir::BinOp_::BiSub,
256-
BinOp::Mul => hir::BinOp_::BiMul,
257-
BinOp::Div => hir::BinOp_::BiDiv,
258-
BinOp::Rem => hir::BinOp_::BiRem,
259-
BinOp::BitXor => hir::BinOp_::BiBitXor,
260-
BinOp::BitAnd => hir::BinOp_::BiBitAnd,
261-
BinOp::BitOr => hir::BinOp_::BiBitOr,
262-
BinOp::Shl => hir::BinOp_::BiShl,
263-
BinOp::Shr => hir::BinOp_::BiShr,
264-
BinOp::Eq => hir::BinOp_::BiEq,
265-
BinOp::Ne => hir::BinOp_::BiNe,
266-
BinOp::Lt => hir::BinOp_::BiLt,
267-
BinOp::Gt => hir::BinOp_::BiGt,
268-
BinOp::Le => hir::BinOp_::BiLe,
269-
BinOp::Ge => hir::BinOp_::BiGe
270-
}
271-
}
272-
}

0 commit comments

Comments
 (0)