Move param_substs onto MirContext

This commit is contained in:
Mark Simulacrum 2016-12-18 16:05:40 -07:00
parent a42a3429fe
commit e10695f161
8 changed files with 48 additions and 56 deletions

View File

@ -20,10 +20,8 @@ use monomorphize::Instance;
use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
use rustc::hir::map::DefPathData;
use rustc::infer::TransNormalize;
use rustc::util::common::MemoizationMap;
use middle::lang_items::LangItem;
use rustc::ty::subst::Substs;
use abi::{Abi, FnType};
use base;
use builder::Builder;
@ -37,7 +35,6 @@ use value::Value;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::layout::Layout;
use rustc::traits::{self, SelectionContext, Reveal};
use rustc::ty::fold::TypeFoldable;
use rustc::hir;
use libc::{c_uint, c_char};
@ -249,10 +246,6 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
// Describes the return/argument LLVM types and their ABI handling.
pub fn_ty: FnType,
// If this function is being monomorphized, this contains the type
// substitutions used.
pub param_substs: &'tcx Substs<'tcx>,
// This function's enclosing crate context.
pub ccx: &'a CrateContext<'a, 'tcx>,
@ -266,23 +259,13 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
ccx: &'a CrateContext<'a, 'tcx>,
llfndecl: ValueRef,
fn_ty: FnType,
definition: Option<(Instance<'tcx>, &ty::FnSig<'tcx>, Abi)>,
skip_retptr: bool,
) -> FunctionContext<'a, 'tcx> {
let param_substs = match definition {
Some((instance, ..)) => {
assert!(!instance.substs.needs_infer());
instance.substs
}
None => ccx.tcx().intern_substs(&[])
};
let mut fcx = FunctionContext {
llfn: llfndecl,
llretslotptr: None,
alloca_insert_pt: None,
fn_ty: fn_ty,
param_substs: param_substs,
ccx: ccx,
alloca_builder: Builder::with_ccx(ccx),
};
@ -340,14 +323,6 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
BlockAndBuilder::new(self.new_block(name), self)
}
pub fn monomorphize<T>(&self, value: &T) -> T
where T: TransNormalize<'tcx>
{
monomorphize::apply_param_substs(self.ccx.shared(),
self.param_substs,
value)
}
pub fn eh_personality(&self) -> ValueRef {
// The exception handling personality function.
//

View File

@ -17,15 +17,18 @@ use rustc::mir::{self, Location, TerminatorKind};
use rustc::mir::visit::{Visitor, LvalueContext};
use rustc::mir::traversal;
use common::{self, BlockAndBuilder};
use super::MirContext;
use super::rvalue;
pub fn lvalue_locals<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>, mir: &mir::Mir<'tcx>) -> BitVector {
let mut analyzer = LocalAnalyzer::new(mir, &bcx);
pub fn lvalue_locals<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>, mircx: &MirContext<'a, 'tcx>)
-> BitVector {
let mir = mircx.mir;
let mut analyzer = LocalAnalyzer::new(mircx, &bcx);
analyzer.visit_mir(mir);
for (index, ty) in mir.local_decls.iter().map(|l| l.ty).enumerate() {
let ty = bcx.fcx().monomorphize(&ty);
let ty = mircx.monomorphize(&ty);
debug!("local {} has type {:?}", index, ty);
if ty.is_scalar() ||
ty.is_unique() ||
@ -54,20 +57,20 @@ pub fn lvalue_locals<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>, mir: &mir::Mir<'
}
struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> {
mir: &'mir mir::Mir<'tcx>,
mir: &'mir MirContext<'a, 'tcx>,
bcx: &'mir BlockAndBuilder<'a, 'tcx>,
lvalue_locals: BitVector,
seen_assigned: BitVector
}
impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> {
fn new(mir: &'mir mir::Mir<'tcx>, bcx: &'mir BlockAndBuilder<'a, 'tcx>)
fn new(mircx: &'mir MirContext<'a, 'tcx>, bcx: &'mir BlockAndBuilder<'a, 'tcx>)
-> LocalAnalyzer<'mir, 'a, 'tcx> {
LocalAnalyzer {
mir: mir,
mir: mircx,
bcx: bcx,
lvalue_locals: BitVector::new(mir.local_decls.len()),
seen_assigned: BitVector::new(mir.local_decls.len())
lvalue_locals: BitVector::new(mircx.mir.local_decls.len()),
seen_assigned: BitVector::new(mircx.mir.local_decls.len())
}
}
@ -93,7 +96,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
if let mir::Lvalue::Local(index) = *lvalue {
self.mark_assigned(index);
if !rvalue::rvalue_creates_operand(self.mir, self.bcx, rvalue) {
if !rvalue::rvalue_creates_operand(self.mir.mir, self.bcx, rvalue) {
self.mark_as_lvalue(index);
}
} else {
@ -136,9 +139,9 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
// Allow uses of projections of immediate pair fields.
if let mir::Lvalue::Projection(ref proj) = *lvalue {
if let mir::Lvalue::Local(_) = proj.base {
let ty = proj.base.ty(self.mir, self.bcx.tcx());
let ty = proj.base.ty(self.mir.mir, self.bcx.tcx());
let ty = self.bcx.fcx().monomorphize(&ty.to_ty(self.bcx.tcx()));
let ty = self.mir.monomorphize(&ty.to_ty(self.bcx.tcx()));
if common::type_is_imm_pair(self.bcx.ccx(), ty) {
if let mir::ProjectionElem::Field(..) = proj.elem {
if let LvalueContext::Consume = context {
@ -167,8 +170,8 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
}
LvalueContext::Drop => {
let ty = lvalue.ty(self.mir, self.bcx.tcx());
let ty = self.bcx.fcx().monomorphize(&ty.to_ty(self.bcx.tcx()));
let ty = lvalue.ty(self.mir.mir, self.bcx.tcx());
let ty = self.mir.monomorphize(&ty.to_ty(self.bcx.tcx()));
// Only need the lvalue if we're actually dropping it.
if self.bcx.ccx().shared().type_needs_drop(ty) {

View File

@ -242,7 +242,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
mir::TerminatorKind::Drop { ref location, target, unwind } => {
let ty = location.ty(&self.mir, bcx.tcx()).to_ty(bcx.tcx());
let ty = bcx.fcx().monomorphize(&ty);
let ty = self.monomorphize(&ty);
// Double check for necessity to drop
if !bcx.ccx().shared().type_needs_drop(ty) {
@ -522,7 +522,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
let extra_args = &args[sig.inputs().len()..];
let extra_args = extra_args.iter().map(|op_arg| {
let op_ty = op_arg.ty(&self.mir, bcx.tcx());
bcx.fcx().monomorphize(&op_ty)
self.monomorphize(&op_ty)
}).collect::<Vec<_>>();
let fn_ty = callee.direct_fn_type(bcx.ccx(), &extra_args);

View File

@ -952,7 +952,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
-> Const<'tcx>
{
debug!("trans_constant({:?})", constant);
let ty = bcx.fcx().monomorphize(&constant.ty);
let ty = self.monomorphize(&constant.ty);
let result = match constant.literal.clone() {
mir::Literal::Item { def_id, substs } => {
// Shortcut for zero-sized types, including function item
@ -962,14 +962,13 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
return Const::new(C_null(llty), ty);
}
let substs = bcx.fcx().monomorphize(&substs);
let substs = self.monomorphize(&substs);
let instance = Instance::new(def_id, substs);
MirConstContext::trans_def(bcx.ccx(), instance, IndexVec::new())
}
mir::Literal::Promoted { index } => {
let mir = &self.mir.promoted[index];
MirConstContext::new(bcx.ccx(), mir, bcx.fcx().param_substs,
IndexVec::new()).trans()
MirConstContext::new(bcx.ccx(), mir, self.param_substs, IndexVec::new()).trans()
}
mir::Literal::Value { value } => {
Ok(Const::from_constval(bcx.ccx(), value, ty))

View File

@ -103,7 +103,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
let ptr = self.trans_consume(bcx, base);
let projected_ty = LvalueTy::from_ty(ptr.ty)
.projection_ty(tcx, &mir::ProjectionElem::Deref);
let projected_ty = bcx.fcx().monomorphize(&projected_ty);
let projected_ty = self.monomorphize(&projected_ty);
let (llptr, llextra) = match ptr.val {
OperandValue::Immediate(llptr) => (llptr, ptr::null_mut()),
OperandValue::Pair(llptr, llextra) => (llptr, llextra),
@ -118,7 +118,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
mir::Lvalue::Projection(ref projection) => {
let tr_base = self.trans_lvalue(bcx, &projection.base);
let projected_ty = tr_base.ty.projection_ty(tcx, &projection.elem);
let projected_ty = bcx.fcx().monomorphize(&projected_ty);
let projected_ty = self.monomorphize(&projected_ty);
let project_index = |llindex| {
let element = if let ty::TySlice(_) = tr_base.ty.to_ty(tcx).sty {
@ -274,6 +274,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
pub fn monomorphized_lvalue_ty(&self, lvalue: &mir::Lvalue<'tcx>) -> Ty<'tcx> {
let tcx = self.fcx.ccx.tcx();
let lvalue_ty = lvalue.ty(&self.mir, tcx);
self.fcx.monomorphize(&lvalue_ty.to_ty(tcx))
self.monomorphize(&lvalue_ty.to_ty(tcx))
}
}

View File

@ -14,11 +14,14 @@ use llvm::debuginfo::DIScope;
use rustc::ty;
use rustc::mir::{self, Mir};
use rustc::mir::tcx::LvalueTy;
use rustc::ty::subst::Substs;
use rustc::infer::TransNormalize;
use rustc::ty::TypeFoldable;
use session::config::FullDebugInfo;
use base;
use common::{self, BlockAndBuilder, CrateContext, FunctionContext, C_null, Funclet};
use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext};
use monomorphize::Instance;
use monomorphize::{self, Instance};
use machine;
use type_of;
@ -88,9 +91,17 @@ pub struct MirContext<'a, 'tcx:'a> {
/// Debug information for MIR scopes.
scopes: IndexVec<mir::VisibilityScope, debuginfo::MirDebugScope>,
/// If this function is being monomorphized, this contains the type substitutions used.
param_substs: &'tcx Substs<'tcx>,
}
impl<'a, 'tcx> MirContext<'a, 'tcx> {
pub fn monomorphize<T>(&self, value: &T) -> T
where T: TransNormalize<'tcx> {
monomorphize::apply_param_substs(self.fcx.ccx.shared(), self.param_substs, value)
}
pub fn debug_loc(&mut self, source_info: mir::SourceInfo) -> (DIScope, Span) {
// Bail out if debug info emission is not enabled.
match self.debug_context {
@ -207,8 +218,6 @@ pub fn trans_mir<'a, 'tcx: 'a>(
let bcx = fcx.get_entry_block();
// Analyze the temps to determine which must be lvalues
// FIXME
let lvalue_locals = analyze::lvalue_locals(&bcx, &mir);
let cleanup_kinds = analyze::cleanup_kinds(&mir);
// Allocate a `Block` for every basic block
@ -235,15 +244,21 @@ pub fn trans_mir<'a, 'tcx: 'a>(
scopes: scopes,
locals: IndexVec::new(),
debug_context: debug_context,
param_substs: {
assert!(!instance.substs.needs_infer());
instance.substs
},
};
let lvalue_locals = analyze::lvalue_locals(&bcx, &mircx);
// Allocate variable and temp allocas
mircx.locals = {
let args = arg_local_refs(&bcx, &mircx, &mircx.scopes, &lvalue_locals);
let mut allocate_local = |local| {
let decl = &mir.local_decls[local];
let ty = bcx.fcx().monomorphize(&decl.ty);
let ty = mircx.monomorphize(&decl.ty);
if let Some(name) = decl.name {
// User variable
@ -356,7 +371,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
mir.args_iter().enumerate().map(|(arg_index, local)| {
let arg_decl = &mir.local_decls[local];
let arg_ty = bcx.fcx().monomorphize(&arg_decl.ty);
let arg_ty = mircx.monomorphize(&arg_decl.ty);
if Some(local) == mir.spread_arg {
// This argument (e.g. the last argument in the "rust-call" ABI)

View File

@ -197,7 +197,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
let llval = [a, b][f.index()];
let op = OperandRef {
val: OperandValue::Immediate(llval),
ty: bcx.fcx().monomorphize(&ty)
ty: self.monomorphize(&ty)
};
// Handle nested pairs.

View File

@ -53,7 +53,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
}
mir::Rvalue::Cast(mir::CastKind::Unsize, ref source, cast_ty) => {
let cast_ty = bcx.fcx().monomorphize(&cast_ty);
let cast_ty = self.monomorphize(&cast_ty);
if common::type_is_fat_ptr(bcx.ccx(), cast_ty) {
// into-coerce of a thin pointer to a fat pointer - just
@ -186,7 +186,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
mir::Rvalue::Cast(ref kind, ref source, cast_ty) => {
let operand = self.trans_operand(&bcx, source);
debug!("cast operand is {:?}", operand);
let cast_ty = bcx.fcx().monomorphize(&cast_ty);
let cast_ty = self.monomorphize(&cast_ty);
let val = match *kind {
mir::CastKind::ReifyFnPointer => {
@ -443,7 +443,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
}
mir::Rvalue::Box(content_ty) => {
let content_ty: Ty<'tcx> = bcx.fcx().monomorphize(&content_ty);
let content_ty: Ty<'tcx> = self.monomorphize(&content_ty);
let llty = type_of::type_of(bcx.ccx(), content_ty);
let llsize = machine::llsize_of(bcx.ccx(), llty);
let align = type_of::align_of(bcx.ccx(), content_ty);