Skip to content

Commit 317daf7

Browse files
committed
Do some simple constant propagation in the ConstProp pass
1 parent f64ed09 commit 317daf7

File tree

1 file changed

+62
-9
lines changed

1 file changed

+62
-9
lines changed

src/librustc_mir/transform/const_prop.rs

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,25 @@
33
44
use rustc::hir::def::DefKind;
55
use rustc::mir::{
6-
Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local,
6+
AggregateKind, Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local,
77
NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind,
88
TerminatorKind, Terminator, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem,
99
SourceScope, SourceScopeLocalData, LocalDecl, Promoted,
1010
};
11-
use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext};
11+
use rustc::mir::visit::{
12+
Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext,
13+
};
1214
use rustc::mir::interpret::{InterpError, Scalar, GlobalId, EvalResult};
1315
use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
14-
use syntax::source_map::DUMMY_SP;
16+
use syntax_pos::{Span, DUMMY_SP};
1517
use rustc::ty::subst::InternalSubsts;
1618
use rustc_data_structures::indexed_vec::IndexVec;
1719
use rustc::ty::layout::{
1820
LayoutOf, TyLayout, LayoutError,
1921
HasTyCtxt, TargetDataLayout, HasDataLayout,
2022
};
2123

22-
use crate::interpret::{InterpretCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind};
24+
use crate::interpret::{self, InterpretCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind};
2325
use crate::const_eval::{
2426
CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx,
2527
};
@@ -497,6 +499,53 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
497499
},
498500
}
499501
}
502+
503+
fn operand_from_scalar(&self, scalar: Scalar, ty: Ty<'tcx>, span: Span) -> Operand<'tcx> {
504+
Operand::Constant(Box::new(
505+
Constant {
506+
span,
507+
ty,
508+
user_ty: None,
509+
literal: self.tcx.mk_const(ty::Const::from_scalar(
510+
scalar,
511+
ty,
512+
))
513+
}
514+
))
515+
}
516+
517+
fn replace_with_const(&self, rval: &mut Rvalue<'tcx>, value: Const<'tcx>, span: Span) {
518+
self.ecx.validate_operand(
519+
value,
520+
vec![],
521+
None,
522+
true,
523+
).expect("value should already be a valid const");
524+
525+
if let interpret::Operand::Immediate(im) = *value {
526+
match im {
527+
interpret::Immediate::Scalar(ScalarMaybeUndef::Scalar(scalar)) => {
528+
*rval = Rvalue::Use(self.operand_from_scalar(scalar, value.layout.ty, span));
529+
},
530+
Immediate::ScalarPair(
531+
ScalarMaybeUndef::Scalar(one),
532+
ScalarMaybeUndef::Scalar(two)
533+
) => {
534+
let ty = &value.layout.ty.sty;
535+
if let ty::Tuple(substs) = ty {
536+
*rval = Rvalue::Aggregate(
537+
Box::new(AggregateKind::Tuple),
538+
vec![
539+
self.operand_from_scalar(one, substs[0].expect_ty(), span),
540+
self.operand_from_scalar(two, substs[1].expect_ty(), span),
541+
],
542+
);
543+
}
544+
},
545+
_ => { }
546+
}
547+
}
548+
}
500549
}
501550

502551
fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -560,10 +609,10 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
560609
}
561610
}
562611

563-
impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
612+
impl<'b, 'a, 'tcx> MutVisitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
564613
fn visit_constant(
565614
&mut self,
566-
constant: &Constant<'tcx>,
615+
constant: &mut Constant<'tcx>,
567616
location: Location,
568617
) {
569618
trace!("visit_constant: {:?}", constant);
@@ -573,11 +622,11 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
573622

574623
fn visit_statement(
575624
&mut self,
576-
statement: &Statement<'tcx>,
625+
statement: &mut Statement<'tcx>,
577626
location: Location,
578627
) {
579628
trace!("visit_statement: {:?}", statement);
580-
if let StatementKind::Assign(ref place, ref rval) = statement.kind {
629+
if let StatementKind::Assign(ref place, ref mut rval) = statement.kind {
581630
let place_ty: Ty<'tcx> = place
582631
.ty(&self.local_decls, self.tcx)
583632
.ty;
@@ -589,6 +638,10 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
589638
trace!("storing {:?} to {:?}", value, local);
590639
assert!(self.places[local].is_none());
591640
self.places[local] = Some(value);
641+
642+
if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 {
643+
self.replace_with_const(rval, value, statement.source_info.span);
644+
}
592645
}
593646
}
594647
}
@@ -599,7 +652,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
599652

600653
fn visit_terminator(
601654
&mut self,
602-
terminator: &Terminator<'tcx>,
655+
terminator: &mut Terminator<'tcx>,
603656
location: Location,
604657
) {
605658
self.super_terminator(terminator, location);

0 commit comments

Comments
 (0)