Skip to content

Trans Refactor: Episode 2 #7182

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

Closed
wants to merge 13 commits into from
61 changes: 28 additions & 33 deletions src/librustc/back/upcall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

use driver::session;
use middle::trans::base;
use middle::trans::common::{T_fn, T_i8, T_i32, T_int, T_ptr, T_void};
use lib::llvm::{ModuleRef, ValueRef, TypeRef};
use middle::trans::type_::Type;
use lib::llvm::{ModuleRef, ValueRef};

pub struct Upcalls {
trace: ValueRef,
Expand All @@ -22,40 +22,35 @@ pub struct Upcalls {
reset_stack_limit: ValueRef
}

pub fn declare_upcalls(targ_cfg: @session::config,
llmod: ModuleRef) -> @Upcalls {
fn decl(llmod: ModuleRef, prefix: ~str, name: ~str,
tys: ~[TypeRef], rv: TypeRef) ->
ValueRef {
let arg_tys = tys.map(|t| *t);
let fn_ty = T_fn(arg_tys, rv);
return base::decl_cdecl_fn(llmod, prefix + name, fn_ty);
}
fn nothrow(f: ValueRef) -> ValueRef {
base::set_no_unwind(f); f
}
let d: &fn(a: ~str, b: ~[TypeRef], c: TypeRef) -> ValueRef =
|a,b,c| decl(llmod, ~"upcall_", a, b, c);
let dv: &fn(a: ~str, b: ~[TypeRef]) -> ValueRef =
|a,b| decl(llmod, ~"upcall_", a, b, T_void());
macro_rules! upcall (
(fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
let fn_ty = Type::func([ $($arg),* ], &$ret);
base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty)
});
(nothrow fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
let fn_ty = Type::func([ $($arg),* ], &$ret);
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
base::set_no_unwind(decl);
decl
});
(nothrow fn $name:ident -> $ret:expr) => ({
let fn_ty = Type::func([], &$ret);
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
base::set_no_unwind(decl);
decl
})
)

let int_t = T_int(targ_cfg);
pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls {
let opaque_ptr = Type::i8().ptr_to();
let int_ty = Type::int(targ_cfg.arch);

@Upcalls {
trace: dv(~"trace", ~[T_ptr(T_i8()),
T_ptr(T_i8()),
int_t]),
call_shim_on_c_stack:
d(~"call_shim_on_c_stack",
// arguments: void *args, void *fn_ptr
~[T_ptr(T_i8()), T_ptr(T_i8())],
int_t),
trace: upcall!(fn trace(opaque_ptr, opaque_ptr, int_ty) -> Type::void()),
call_shim_on_c_stack: upcall!(fn call_shim_on_c_stack(opaque_ptr, opaque_ptr) -> int_ty),
call_shim_on_rust_stack:
d(~"call_shim_on_rust_stack",
~[T_ptr(T_i8()), T_ptr(T_i8())], int_t),
rust_personality:
nothrow(d(~"rust_personality", ~[], T_i32())),
reset_stack_limit:
nothrow(dv(~"reset_stack_limit", ~[]))
upcall!(fn call_shim_on_rust_stack(opaque_ptr, opaque_ptr) -> int_ty),
rust_personality: upcall!(nothrow fn rust_personality -> Type::i32()),
reset_stack_limit: upcall!(nothrow fn reset_stack_limit -> Type::void())
}
}
205 changes: 70 additions & 135 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use core::prelude::*;
use core::hashmap::HashMap;
use core::libc::{c_uint, c_ushort};
use core::option;
use core::ptr;
use core::str;
use core::vec;

use middle::trans::type_::Type;

pub type Opcode = u32;
pub type Bool = c_uint;
Expand Down Expand Up @@ -2121,155 +2121,90 @@ pub fn ConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef {
/* Memory-managed object interface to type handles. */

pub struct TypeNames {
type_names: @mut HashMap<TypeRef, @str>,
named_types: @mut HashMap<@str, TypeRef>
}

pub fn associate_type(tn: @TypeNames, s: @str, t: TypeRef) {
assert!(tn.type_names.insert(t, s));
assert!(tn.named_types.insert(s, t));
}

pub fn type_has_name(tn: @TypeNames, t: TypeRef) -> Option<@str> {
return tn.type_names.find(&t).map_consume(|x| *x);
type_names: HashMap<TypeRef, ~str>,
named_types: HashMap<~str, TypeRef>
}

pub fn name_has_type(tn: @TypeNames, s: @str) -> Option<TypeRef> {
return tn.named_types.find(&s).map_consume(|x| *x);
}

pub fn mk_type_names() -> @TypeNames {
@TypeNames {
type_names: @mut HashMap::new(),
named_types: @mut HashMap::new()
impl TypeNames {
pub fn new() -> TypeNames {
TypeNames {
type_names: HashMap::new(),
named_types: HashMap::new()
}
}
}

pub fn type_to_str(names: @TypeNames, ty: TypeRef) -> @str {
return type_to_str_inner(names, [], ty);
}
pub fn associate_type(&mut self, s: &str, t: &Type) {
assert!(self.type_names.insert(t.to_ref(), s.to_owned()));
assert!(self.named_types.insert(s.to_owned(), t.to_ref()));
}

pub fn type_to_str_inner(names: @TypeNames, outer0: &[TypeRef], ty: TypeRef)
-> @str {
unsafe {
match type_has_name(names, ty) {
option::Some(n) => return n,
_ => {}
pub fn find_name<'r>(&'r self, ty: &Type) -> Option<&'r str> {
match self.type_names.find(&ty.to_ref()) {
Some(a) => Some(a.slice(0, a.len())),
None => None
}
}

let outer = vec::append_one(outer0.to_owned(), ty);

let kind = llvm::LLVMGetTypeKind(ty);
pub fn find_type(&self, s: &str) -> Option<Type> {
self.named_types.find_equiv(&s).map_consume(|x| Type::from_ref(*x))
}

fn tys_str(names: @TypeNames, outer: &[TypeRef],
tys: ~[TypeRef]) -> @str {
let mut s = ~"";
let mut first: bool = true;
for tys.each |t| {
if first { first = false; } else { s += ", "; }
s += type_to_str_inner(names, outer, *t);
}
// [Note at-str] FIXME #2543: Could rewrite this without the copy,
// but need better @str support.
return s.to_managed();
pub fn type_to_str(&self, ty: Type) -> ~str {
match self.find_name(&ty) {
option::Some(name) => return name.to_owned(),
None => ()
}

match kind {
Void => return @"Void",
Half => return @"Half",
Float => return @"Float",
Double => return @"Double",
X86_FP80 => return @"X86_FP80",
FP128 => return @"FP128",
PPC_FP128 => return @"PPC_FP128",
Label => return @"Label",
Integer => {
// See [Note at-str]
return fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty)
as int).to_managed();
}
Function => {
let out_ty: TypeRef = llvm::LLVMGetReturnType(ty);
let n_args = llvm::LLVMCountParamTypes(ty) as uint;
let args = vec::from_elem(n_args, 0 as TypeRef);
llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args));
// See [Note at-str]
return fmt!("fn(%s) -> %s",
tys_str(names, outer, args),
type_to_str_inner(names, outer, out_ty)).to_managed();
}
Struct => {
let elts = struct_tys(ty);
// See [Note at-str]
return fmt!("{%s}", tys_str(names, outer, elts)).to_managed();
}
Array => {
let el_ty = llvm::LLVMGetElementType(ty);
// See [Note at-str]
return fmt!("[%s@ x %u", type_to_str_inner(names, outer, el_ty),
llvm::LLVMGetArrayLength(ty) as uint).to_managed();
}
Pointer => {
let mut i = 0;
for outer0.each |tout| {
i += 1;
if *tout as int == ty as int {
let n = outer0.len() - i;
// See [Note at-str]
return fmt!("*\\%d", n as int).to_managed();
unsafe {
let kind = ty.kind();

match kind {
Void => ~"Void",
Half => ~"Half",
Double => ~"Double",
X86_FP80 => ~"X86_FP80",
FP128 => ~"FP128",
PPC_FP128 => ~"PPC_FP128",
Label => ~"Label",
Vector => ~"Vector",
Metadata => ~"Metadata",
X86_MMX => ~"X86_MMAX",
Integer => {
fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty.to_ref()) as int)
}
}
let addrstr = {
let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint;
if addrspace == 0 {
~""
} else {
fmt!("addrspace(%u)", addrspace)
Function => {
let out_ty = ty.return_type();
let args = ty.func_params();
let args = args.map(|&ty| self.type_to_str(ty)).connect(", ");
let out_ty = self.type_to_str(out_ty);
fmt!("fn(%s) -> %s", args, out_ty)
}
Struct => {
let tys = ty.field_types();
let tys = tys.map(|&ty| self.type_to_str(ty)).connect(", ");
fmt!("{%s}", tys)
}
Array => {
let el_ty = ty.element_type();
let el_ty = self.type_to_str(el_ty);
let len = ty.array_length();
fmt!("[%s x %u]", el_ty, len)
}
Pointer => {
let el_ty = ty.element_type();
let el_ty = self.type_to_str(el_ty);
fmt!("*%s", el_ty)
}
};
// See [Note at-str]
return fmt!("%s*%s", addrstr, type_to_str_inner(names,
outer,
llvm::LLVMGetElementType(ty))).to_managed();
}
Vector => return @"Vector",
Metadata => return @"Metadata",
X86_MMX => return @"X86_MMAX",
_ => fail!()
_ => fail!("Unknown Type Kind (%u)", kind as uint)
}
}
}
}

pub fn float_width(llt: TypeRef) -> uint {
unsafe {
return match llvm::LLVMGetTypeKind(llt) as int {
1 => 32u,
2 => 64u,
3 => 80u,
4 | 5 => 128u,
_ => fail!("llvm_float_width called on a non-float type")
};
}
}

pub fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] {
unsafe {
let args = vec::from_elem(llvm::LLVMCountParamTypes(fn_ty) as uint,
0 as TypeRef);
llvm::LLVMGetParamTypes(fn_ty, vec::raw::to_ptr(args));
return args;
}
}

pub fn struct_tys(struct_ty: TypeRef) -> ~[TypeRef] {
unsafe {
let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint;
if n_elts == 0 {
return ~[];
pub fn val_to_str(&self, val: ValueRef) -> ~str {
unsafe {
let ty = Type::from_ref(llvm::LLVMTypeOf(val));
self.type_to_str(ty)
}
let mut elts = vec::from_elem(n_elts, ptr::null());
llvm::LLVMGetStructElementTypes(struct_ty, &mut elts[0]);
return elts;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ use core::prelude::*;

use middle::ty;
use middle::typeck;
use util::ppaux::{ty_to_str, region_to_str, Repr};
use util::ppaux::{ty_to_str, region_ptr_to_str, Repr};
use util::common::indenter;

use core::uint;
Expand Down Expand Up @@ -1026,7 +1026,7 @@ impl mem_categorization_ctxt {
}

pub fn region_to_str(&self, r: ty::Region) -> ~str {
region_to_str(self.tcx, r)
region_ptr_to_str(self.tcx, r)
}
}

Expand Down
Loading