Move param_substs onto MirContext
This commit is contained in:
parent
a42a3429fe
commit
e10695f161
@ -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.
|
||||
//
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user