Skip to content

Refactor call & function handling in trans, enable MIR bootstrap. #32080

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 77 commits into from
Mar 18, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
b47fcb8
trans: Use fmt::Debug for debugging instead of ad-hoc methods.
eddyb Feb 18, 2016
9723a3b
Move simd_ffi gating from trans to typeck.
eddyb Feb 23, 2016
b918e37
metedata: Remove the unnecessary indirection to astencode.
eddyb Feb 23, 2016
062a05d
metadata: Constrain FoundAst::FoundParent to an Item.
eddyb Feb 23, 2016
16201d4
trans: Get functions and do calls only through Callee.
eddyb Feb 23, 2016
e097049
trans: Move trans_foreign_mod and trans_impl to trans_item.
eddyb Feb 23, 2016
c3f856e
trans: Remove dead code for variants and structs from get_item_val.
eddyb Feb 23, 2016
5af3c12
trans: Move static item handling to consts.
eddyb Feb 23, 2016
55b5a36
trans: Remove unused return type argument from declare_cfn.
eddyb Feb 23, 2016
7011e30
trans: Remove the old ExprOrMethodCall.
eddyb Feb 23, 2016
9221b91
trans: Pass the Rust type for the closure env in type_of_rust_fn.
eddyb Feb 23, 2016
c6d214b
trans: Revamp and empower cabi::FnType.
eddyb Feb 23, 2016
b122d16
trans: simplify the declare interface.
eddyb Feb 23, 2016
89766a8
trans: use Cell instead of RefCell where it suffices.
eddyb Feb 23, 2016
d6e72c4
trans: Don't store extra copies of intrinsics ID/substs.
eddyb Feb 23, 2016
b05556e
trans: Rename MonoId to Instance and start using it in more places.
eddyb Feb 23, 2016
cdfad40
trans: Condense the fn instantiation logic into callee.
eddyb Feb 23, 2016
da66431
trans: Combine cabi and back::abi into abi.
eddyb Feb 23, 2016
3342da4
trans: Don't treat closure types like function types in declare.
eddyb Feb 23, 2016
200d001
trans: Pass fat pointers as two arguments even for FFI.
eddyb Feb 24, 2016
cf0ea78
tests: Force instantiation of extern fns.
eddyb Feb 24, 2016
f6bbbe1
trans: Remove dropflag-unaware type_is_newtype_immediate shortcut.
eddyb Feb 24, 2016
0394205
trans: Handle type_of for Rust fn's via abi::FnType.
eddyb Feb 24, 2016
ac60318
trans: Only mutate ArgTy's in C ABI handling, don't create them.
eddyb Feb 25, 2016
d492d09
trans: Apply ZExt and StructRet attributes uniformly.
eddyb Feb 25, 2016
1d7c9bd
trans: use sizing_type_of for interacting with potentially incomplete…
eddyb Feb 25, 2016
763b6cb
rustc_llvm: Update the Attribute bitflags and remove OtherAttribute.
eddyb Feb 25, 2016
c7172a9
rustc_llvm: An AttrBuilder that's not completely wasteful.
eddyb Feb 25, 2016
de5f824
trans: Use llvm::Attributes directly in ArgTy.
eddyb Feb 25, 2016
77f3484
trans: Apply all attributes through FnType.
eddyb Feb 25, 2016
7454b5c
trans: Set the calling convention in apply_attrs_callsite.
eddyb Mar 6, 2016
80d939f
trans: Handle ignored arguments/returns uniformly.
eddyb Mar 6, 2016
9e036c0
trans: Provide the FnType for a direct call via Callee::direct_fn_type.
eddyb Mar 6, 2016
0399388
trans: Handle calls for all ABIs through FnType.
eddyb Mar 6, 2016
bd0a849
trans: datum::lvalue_scratch_datum doesn't need a move-into-closure t…
eddyb Mar 6, 2016
aec6382
trans: Handle all function setup for all ABIs via FnType.
eddyb Mar 6, 2016
6c0674e
trans: Remove the foreign module.
eddyb Mar 6, 2016
bffb0de
tests: Use arguments in codegen/stores.rs to turn aggregates into imm…
eddyb Mar 6, 2016
f9c06ab
trans: Simplify "try" intrinsic.
eddyb Mar 6, 2016
56417b3
mir: Monomorphize LvalueTy's of projections.
eddyb Mar 8, 2016
b38627d
mir: Use the right form of GEPi for indexing slices vs arrays.
eddyb Mar 8, 2016
1de6a96
mir: Don't use ConstVal kinds that contain local NodeId's.
eddyb Mar 8, 2016
ccc5e07
mir: Ignore noop casts (e.g. when `as` used for coercion).
eddyb Mar 8, 2016
9cc5ee3
mir: Unsize ConstVal::ByteStr before comparing &[u8] against it.
eddyb Mar 8, 2016
d3a6d67
mir: Don't use ConstVal when adjustments are involved, as they would …
eddyb Mar 8, 2016
eb43d95
mir: Don't load the discriminant, it's already in immediate form.
eddyb Mar 8, 2016
92e4858
mir: Load FatPtr constants instead of keeping them indirect.
eddyb Mar 8, 2016
b63a5ee
mir: Support RustCall ABI functions.
eddyb Mar 8, 2016
38638d3
trans: Take a &Builder in call_memcpy, like call_memset.
eddyb Mar 8, 2016
9c6bfe4
mir: Truncate bool to i1 for SwitchInt.
eddyb Mar 8, 2016
47cd05c
mir: Don't shadow the "args" variable in Call translation.
eddyb Mar 8, 2016
6c551b3
trans: Load and cache cross-crate Mir instances in the shared context.
eddyb Mar 8, 2016
41fc5f7
mir: Trigger closure instantiations when the closure value is created.
eddyb Mar 8, 2016
ee7687a
mir: Reintroduce the temporary block after invokes, to handle critica…
eddyb Mar 8, 2016
3e98220
mir: Translate intrinsics, via old trans where possible.
eddyb Mar 8, 2016
82fad1d
mir: Call set_operand_dropped in more places, specifically Unsize casts.
eddyb Mar 8, 2016
d9277b1
trans: Make everything used from within at_start Builder-friendly.
eddyb Mar 9, 2016
41499f4
mir: Match against slices by calling PartialEq::eq.
eddyb Mar 9, 2016
cf4daf7
mir: Don't lose sub-patterns inside slice patterns.
eddyb Mar 9, 2016
aca4f93
mir: Get the right non-reference type for binding patterns.
eddyb Mar 9, 2016
415d95f
mir: Translate Rvalue::Slice without relying on tvec.
eddyb Mar 9, 2016
856185d
hir, mir: Separate HIR expressions / MIR operands from InlineAsm.
eddyb Mar 9, 2016
835e2bd
Add -Z orbit for forcing MIR for everything, unless #[rustc_no_mir] i…
eddyb Mar 9, 2016
5eeda54
mir: Use usize instead of u32 for indexing slices.
eddyb Mar 10, 2016
7912f94
const_eval: Take just one set of substitutions in lookup_const_by_id.
eddyb Mar 10, 2016
5739ed1
trans: Do not depend on having Expr's around for generic_simd_intrinsic.
eddyb Mar 10, 2016
cfd768e
hir_map: Provide expression and statement attributes.
eddyb Mar 10, 2016
5f990fb
mir: Don't forget to drop arguments.
eddyb Mar 10, 2016
080bd97
compiletest: Add rustc-env for run-pass/super-fast-paren-parsing.
eddyb Mar 10, 2016
473f804
Add #[rustc_no_mir] to make tests pass with -Z orbit.
eddyb Mar 10, 2016
460e664
mir: Store immediates used for indirect arguments in an alloca.
eddyb Mar 10, 2016
02a141a
mir: Don't memset allocas of types that do not require drop.
eddyb Mar 10, 2016
9a8b807
trans: Pass newtypes of immediates as their inner-most type again.
eddyb Mar 17, 2016
d6689e5
Update the not-at-all-pretty pain-o-tron-4000+264 test.
eddyb Mar 18, 2016
181097d
trans: Decide whether to load volatile_store's argument based on its …
eddyb Mar 18, 2016
e177207
trans: Don't ignore zero-sized struct arguments on x86_64-pc-windows-…
eddyb Mar 18, 2016
b12dcde
tests: Update run-make/issue-25581 to reflect how fat pointers are pa…
eddyb Mar 18, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
trans: Pass fat pointers as two arguments even for FFI.
  • Loading branch information
eddyb committed Mar 17, 2016
commit 200d001784e62c85d0e938637ce4043162aa94fd
18 changes: 14 additions & 4 deletions src/librustc_trans/trans/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub use self::ArgKind::*;

use llvm::{self, AttrHelper, ValueRef};
use trans::attributes;
use trans::common::return_type_is_void;
use trans::common::{return_type_is_void, type_is_fat_ptr};
use trans::context::CrateContext;
use trans::cabi_x86;
use trans::cabi_x86_64;
Expand Down Expand Up @@ -184,10 +184,20 @@ impl FnType {
_ => Type::void(ccx)
};

let mut args = Vec::with_capacity(sig.inputs.len() + extra_args.len());
for ty in sig.inputs.iter().chain(extra_args.iter()) {
let llty = c_type_of(ccx, ty);
if type_is_fat_ptr(ccx.tcx(), ty) {
args.extend(llty.field_types().into_iter().map(|llty| {
ArgType::direct(llty, None, None, None)
}));
} else {
args.push(ArgType::direct(llty, None, None, None));
}
}

let mut fty = FnType {
args: sig.inputs.iter().chain(extra_args.iter()).map(|&ty| {
ArgType::direct(c_type_of(ccx, ty), None, None, None)
}).collect(),
args: args,
ret: ArgType::direct(rty, None, None, None),
variadic: sig.variadic,
cconv: cconv
Expand Down
92 changes: 54 additions & 38 deletions src/librustc_trans/trans/foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,17 @@ use back::link;
use llvm::{ValueRef, get_param};
use llvm;
use middle::weak_lang_items;
use trans::abi::{self, Abi, FnType};
use trans::abi::{Abi, FnType};
use trans::attributes;
use trans::base::{llvm_linkage_by_name, push_ctxt};
use trans::base;
use trans::build::*;
use trans::common::*;
use trans::debuginfo::DebugLoc;
use trans::declare;
use trans::expr;
use trans::machine;
use trans::monomorphize;
use trans::type_::Type;
use trans::type_of::*;
use trans::type_of;
use trans::value::Value;
use middle::infer;
Expand Down Expand Up @@ -167,17 +165,40 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
}

let mut offset = 0;
for (i, arg_ty) in fn_type.args.iter().enumerate() {
let mut llarg_rust = llargs_rust[i + offset];
let mut i = 0;
for &passed_arg_ty in &passed_arg_tys {
let arg_ty = fn_type.args[i];

if arg_ty.is_ignore() {
i += 1;
continue;
}

if type_is_fat_ptr(ccx.tcx(), passed_arg_ty) {
// Fat pointers are one pointer and one integer or pointer.
let (a, b) = (fn_type.args[i], fn_type.args[i + 1]);
assert_eq!((a.cast, b.cast), (None, None));
assert!(!a.is_indirect() && !b.is_indirect());

if let Some(ty) = a.pad {
llargs_foreign.push(C_undef(ty));
}
llargs_foreign.push(llargs_rust[i]);
i += 1;

if let Some(ty) = b.pad {
llargs_foreign.push(C_undef(ty));
}
llargs_foreign.push(llargs_rust[i]);
i += 1;
continue;
}

// Does Rust pass this argument by pointer?
let rust_indirect = type_of::arg_is_indirect(ccx, passed_arg_tys[i]);
let rust_indirect = type_of::arg_is_indirect(ccx, passed_arg_ty);

let mut llarg_rust = llargs_rust[i];
i += 1;
debug!("argument {}, llarg_rust={:?}, rust_indirect={}, arg_ty={:?}",
i,
Value(llarg_rust),
Expand All @@ -187,24 +208,17 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Ensure that we always have the Rust value indirectly,
// because it makes bitcasting easier.
if !rust_indirect {
let scratch = base::alloc_ty(bcx, passed_arg_tys[i], "__arg");
if type_is_fat_ptr(ccx.tcx(), passed_arg_tys[i]) {
Store(bcx, llargs_rust[i + offset], expr::get_dataptr(bcx, scratch));
Store(bcx, llargs_rust[i + offset + 1], expr::get_meta(bcx, scratch));
offset += 1;
} else {
base::store_ty(bcx, llarg_rust, scratch, passed_arg_tys[i]);
}
let scratch = base::alloc_ty(bcx, passed_arg_ty, "__arg");
base::store_ty(bcx, llarg_rust, scratch, passed_arg_ty);
llarg_rust = scratch;
}

debug!("llarg_rust={:?} (after indirection)",
Value(llarg_rust));

// Check whether we need to do any casting
match arg_ty.cast {
Some(ty) => llarg_rust = BitCast(bcx, llarg_rust, ty.ptr_to()),
None => ()
if let Some(ty) = arg_ty.cast {
llarg_rust = BitCast(bcx, llarg_rust, ty.ptr_to());
}

debug!("llarg_rust={:?} (after casting)",
Expand All @@ -214,22 +228,19 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let foreign_indirect = arg_ty.is_indirect();
let llarg_foreign = if foreign_indirect {
llarg_rust
} else if passed_arg_ty.is_bool() {
let val = LoadRangeAssert(bcx, llarg_rust, 0, 2, llvm::False);
Trunc(bcx, val, Type::i1(bcx.ccx()))
} else {
if passed_arg_tys[i].is_bool() {
let val = LoadRangeAssert(bcx, llarg_rust, 0, 2, llvm::False);
Trunc(bcx, val, Type::i1(bcx.ccx()))
} else {
Load(bcx, llarg_rust)
}
Load(bcx, llarg_rust)
};

debug!("argument {}, llarg_foreign={:?}",
i, Value(llarg_foreign));

// fill padding with undef value
match arg_ty.pad {
Some(ty) => llargs_foreign.push(C_undef(ty)),
None => ()
if let Some(ty) = arg_ty.pad {
llargs_foreign.push(C_undef(ty));
}
llargs_foreign.push(llarg_foreign);
}
Expand Down Expand Up @@ -552,16 +563,16 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
// Build up the arguments to the call to the rust function.
// Careful to adapt for cases where the native convention uses
// a pointer and Rust does not or vice versa.
let mut tys = fn_ty.args.iter().zip(rust_param_tys);
for i in 0..fn_sig.inputs.len() {
let rust_ty = fn_sig.inputs[i];
let rust_indirect = type_of::arg_is_indirect(ccx, rust_ty);
let llty = rust_param_tys.next().expect("Not enough parameter types!");
let (llforeign_arg_ty, llty) = tys.next().expect("Not enough parameter types!");
let llrust_ty = if rust_indirect {
llty.element_type()
} else {
llty
};
let llforeign_arg_ty = fn_ty.args[i];
let foreign_indirect = llforeign_arg_ty.is_indirect();

if llforeign_arg_ty.is_ignore() {
Expand All @@ -574,6 +585,19 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let foreign_index = next_foreign_arg(llforeign_arg_ty.pad.is_some());
let mut llforeign_arg = get_param(llwrapfn, foreign_index);

if type_is_fat_ptr(ccx.tcx(), rust_ty) {
// Fat pointers are one pointer and one integer or pointer.
let a = llforeign_arg_ty;
let (b, _) = tys.next().expect("Not enough parameter types!");
assert_eq!((a.cast, b.cast), (None, None));
assert!(!a.is_indirect() && !b.is_indirect());

llrust_args.push(llforeign_arg);
let foreign_index = next_foreign_arg(llforeign_arg_ty.pad.is_some());
llrust_args.push(get_param(llwrapfn, foreign_index));
continue;
}

debug!("llforeign_arg {}{}: {:?}", "#",
i, Value(llforeign_arg));
debug!("rust_indirect = {}, foreign_indirect = {}",
Expand Down Expand Up @@ -624,15 +648,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,

debug!("llrust_arg {}{}: {:?}", "#",
i, Value(llrust_arg));
if type_is_fat_ptr(ccx.tcx(), rust_ty) {
let next_llrust_ty = rust_param_tys.next().expect("Not enough parameter types!");
llrust_args.push(builder.load(builder.bitcast(builder.struct_gep(
llrust_arg, abi::FAT_PTR_ADDR), llrust_ty.ptr_to())));
llrust_args.push(builder.load(builder.bitcast(builder.struct_gep(
llrust_arg, abi::FAT_PTR_EXTRA), next_llrust_ty.ptr_to())));
} else {
llrust_args.push(llrust_arg);
}
llrust_args.push(llrust_arg);
}

// Perform the call itself
Expand Down