Reduced the Lvalue constructors to a kernel of three constructors.

Updated all call sites that used the other contructors to uniformly
call `Lvalue::new_with_hint`, passing along the appropriate kind
of hint for each context.

Placated tidy in a few other places in datum.rs.
This commit is contained in:
Felix S. Klock II 2015-06-10 11:42:48 +02:00
parent ff14eaf054
commit 494ce37ffe
3 changed files with 67 additions and 97 deletions

View file

@ -950,8 +950,15 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
let lvalue = match binding_info.trmode {
TrByCopy(..) =>
Lvalue::new("_match::insert_lllocals"),
TrByMoveIntoCopy(..) =>
Lvalue::match_input("_match::insert_lllocals", bcx, binding_info.id),
TrByMoveIntoCopy(..) => {
// match_input moves from the input into a
// separate stack slot; it must zero (at least
// until we track drop flags for a fragmented
// parent match input expression).
let hint_kind = HintKind::ZeroAndMaintain;
Lvalue::new_with_hint("_match::insert_lllocals (match_input)",
bcx, binding_info.id, hint_kind)
}
_ => unreachable!(),
};
let datum = Datum::new(llval, binding_info.ty, lvalue);
@ -971,10 +978,22 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
TrByRef => (binding_info.llmatch, true),
};
let lvalue = Lvalue::local("_match::insert_lllocals",
bcx,
binding_info.id,
aliases_other_state);
// A local that aliases some other state must be zeroed, since
// the other state (e.g. some parent data that we matched
// into) will still have its subcomponents (such as this
// local) destructed at the end of the parent's scope. Longer
// term, we will properly map such parents to the set of
// unique drop flags for its fragments.
let hint_kind = if aliases_other_state {
HintKind::ZeroAndMaintain
} else {
HintKind::DontZeroJustUse
};
let lvalue = Lvalue::new_with_hint("_match::insert_lllocals (local)",
bcx,
binding_info.id,
hint_kind);
let datum = Datum::new(llval, binding_info.ty, lvalue);
if let Some(cs) = cs {
let opt_datum = lvalue.dropflag_hint(bcx);
@ -1709,7 +1728,7 @@ fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
// Allocate memory on stack for the binding.
let llval = alloc_ty(bcx, var_ty, &bcx.name(name));
let lvalue = Lvalue::binding(caller_name, bcx, p_id, name);
let lvalue = Lvalue::new_with_hint(caller_name, bcx, p_id, HintKind::DontZeroJustUse);
let datum = Datum::new(llval, var_ty, lvalue);
// Subtle: be sure that we *populate* the memory *before*

View file

@ -189,96 +189,42 @@ pub struct Rvalue {
pub mode: RvalueMode
}
// XXX: reduce this to a smaller kernel of constructors.
impl Lvalue { // These are all constructors for various Lvalues.
pub fn new(source: &'static str) -> Lvalue {
#[derive(Copy, Clone, Debug)]
pub enum HintKind {
ZeroAndMaintain,
DontZeroJustUse,
}
impl Lvalue { // Constructors for various Lvalues.
pub fn new<'blk, 'tcx>(source: &'static str) -> Lvalue {
debug!("Lvalue at {} no drop flag info", source);
Lvalue { source: source, drop_flag_info: DropFlagInfo::None }
}
pub fn upvar<'blk, 'tcx>(source: &'static str,
bcx: Block<'blk, 'tcx>,
id: ast::NodeId) -> Lvalue {
let info = if Lvalue::has_dropflag_hint(bcx, id) {
DropFlagInfo::ZeroAndMaintain(id)
} else {
DropFlagInfo::None
};
let info = if bcx.tcx().sess.nonzeroing_move_hints() { info } else { DropFlagInfo::None };
debug!("upvar Lvalue at {}, id: {} info: {:?}", source, id, info);
Lvalue { source: source, drop_flag_info: info }
}
pub fn match_input<'blk, 'tcx>(source: &'static str,
bcx: Block<'blk, 'tcx>,
id: ast::NodeId) -> Lvalue
{
let info = if Lvalue::has_dropflag_hint(bcx, id) {
// match_input is used to move from the input into a
// separate stack slot; it must zero (at least until we
// improve things to track drop flags for the fragmented
// parent match input expression).
DropFlagInfo::ZeroAndMaintain(id)
} else {
DropFlagInfo::None
};
let info = if bcx.tcx().sess.nonzeroing_move_hints() { info } else { DropFlagInfo::None };
debug!("match_input Lvalue at {}, id: {} info: {:?}", source, id, info);
Lvalue { source: source, drop_flag_info: info }
}
pub fn local<'blk, 'tcx>(source: &'static str,
bcx: Block<'blk, 'tcx>,
id: ast::NodeId,
aliases_other_state: bool)
-> Lvalue
{
let info = if Lvalue::has_dropflag_hint(bcx, id) {
if aliases_other_state {
DropFlagInfo::ZeroAndMaintain(id)
} else {
DropFlagInfo::DontZeroJustUse(id)
}
} else {
DropFlagInfo::None
};
let info = if bcx.tcx().sess.nonzeroing_move_hints() { info } else { DropFlagInfo::None };
debug!("local Lvalue at {}, id: {} info: {:?}", source, id, info);
Lvalue { source: source, drop_flag_info: info }
}
pub fn store_arg<'blk, 'tcx>(source: &'static str,
bcx: Block<'blk, 'tcx>,
id: ast::NodeId) -> Lvalue
{
let info = if Lvalue::has_dropflag_hint(bcx, id) {
DropFlagInfo::ZeroAndMaintain(id)
} else {
DropFlagInfo::None
};
let info = if bcx.tcx().sess.nonzeroing_move_hints() { info } else { DropFlagInfo::None };
debug!("store_arg Lvalue at {}, id: {} info: {:?}", source, id, info);
Lvalue { source: source, drop_flag_info: info }
}
pub fn binding<'blk, 'tcx>(source: &'static str,
bcx: Block<'blk, 'tcx>,
id: ast::NodeId,
name: ast::Name) -> Lvalue {
let info = if Lvalue::has_dropflag_hint(bcx, id) {
DropFlagInfo::DontZeroJustUse(id)
} else {
DropFlagInfo::None
};
let info = if bcx.tcx().sess.nonzeroing_move_hints() { info } else { DropFlagInfo::None };
debug!("binding Lvalue at {}, id: {} name: {} info: {:?}",
source, id, name, info);
Lvalue { source: source, drop_flag_info: info }
}
pub fn new_dropflag_hint(source: &'static str) -> Lvalue {
debug!("dropflag hint Lvalue at {}", source);
debug!("Lvalue at {} is drop flag hint", source);
Lvalue { source: source, drop_flag_info: DropFlagInfo::None }
}
pub fn new_with_hint<'blk, 'tcx>(source: &'static str,
bcx: Block<'blk, 'tcx>,
id: ast::NodeId,
k: HintKind) -> Lvalue {
let (opt_id, info) = {
let hint_available = Lvalue::has_dropflag_hint(bcx, id) &&
bcx.tcx().sess.nonzeroing_move_hints();
let info = match k {
HintKind::ZeroAndMaintain if hint_available =>
DropFlagInfo::ZeroAndMaintain(id),
HintKind::DontZeroJustUse if hint_available =>
DropFlagInfo::DontZeroJustUse(id),
_ => DropFlagInfo::None,
};
(Some(id), info)
};
debug!("Lvalue at {}, id: {:?} info: {:?}", source, opt_id, info);
Lvalue { source: source, drop_flag_info: info }
}
} // end Lvalue constructor methods.
impl Lvalue {
@ -454,11 +400,15 @@ impl KindOps for Lvalue {
}
bcx
} else {
// XXX would be nice to assert this, but we currently are
// adding e.g. DontZeroJustUse flags. (The dropflag hint
// construction should be taking !type_needs_drop into
// account; earlier analysis phases may not have all the
// info they need to do it properly, I think...)
// FIXME (#5016) would be nice to assert this, but we have
// to allow for e.g. DontZeroJustUse flags, for now.
//
// (The dropflag hint construction should be taking
// !type_needs_drop into account; earlier analysis phases
// may not have all the info they need to include such
// information properly, I think; in particular the
// fragments analysis works on a non-monomorphized view of
// the code.)
//
// assert_eq!(self.drop_flag_info, DropFlagInfo::None);
bcx

View file

@ -1321,7 +1321,8 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
def::DefUpvar(nid, _) => {
// Can't move upvars, so this is never a ZeroMemLastUse.
let local_ty = node_id_type(bcx, nid);
let lval = Lvalue::upvar("expr::trans_local_var", bcx, nid);
let lval = Lvalue::new_with_hint("expr::trans_local_var (upvar)",
bcx, nid, HintKind::ZeroAndMaintain);
match bcx.fcx.llupvars.borrow().get(&nid) {
Some(&val) => Datum::new(val, local_ty, lval),
None => {