Skip to content

Commit dc4560d

Browse files
committed
auto merge of #7182 : Aatch/rust/trans-refactor-pt2, r=graydon
This is another big refactoring of `trans` though this is unlikely to have much of an impact on code size or speed. The major change here is the implementation of a `Type` struct which is the new home for all your LLVM `TypeRef` needs. It's a simple wrapper struct, with static methods for constructing types, then regular methods for manipulating/interrogating them. The purpose of this is mostly to make the code surrounding them somewhat more ideomatic. A line like: `T_ptr(T_ptr(T_i8()))` is now `Type::i8().ptr_to().ptr_to()`,which is much more like regular Rust code. There are a variety of smaller changes here and there: * Remove address spaces. At least it doesn't generate them, I haven't spent much time looking for related code. * Use a macro for declaring the LLVM intrinsics, makes it look much nicer. * Make the type for a string slice actually create a named `str_slice` type in LLVM, this makes reading the appropriate code much easier. * Change the way struct and enum type names are generated. This just means that a struct like `struct Foo { a: int }` now produces the IR `%struct.Foo = type { i64 }`, which is much easier to read. Similarly, other structs are a bit tighter to make it easier to read. --- --- --- This PR did get away from me a little, as I occasionally got distracted or as I fixed up problems with unrelated code that were stopping me from continuing. One major thing is that this PR contains the work from #7168, since that would have conflicted with this and it was broken anyway. Sorry for bundling it like this. Fixes #3670 and #7063 --- --- --- EDIT: This no longer removes the llvm insn stats.
2 parents f886520 + e3ef750 commit dc4560d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2496
-2797
lines changed

src/librustc/back/upcall.rs

+28-33
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
use driver::session;
1313
use middle::trans::base;
14-
use middle::trans::common::{T_fn, T_i8, T_i32, T_int, T_ptr, T_void};
15-
use lib::llvm::{ModuleRef, ValueRef, TypeRef};
14+
use middle::trans::type_::Type;
15+
use lib::llvm::{ModuleRef, ValueRef};
1616

1717
pub struct Upcalls {
1818
trace: ValueRef,
@@ -22,40 +22,35 @@ pub struct Upcalls {
2222
reset_stack_limit: ValueRef
2323
}
2424

25-
pub fn declare_upcalls(targ_cfg: @session::config,
26-
llmod: ModuleRef) -> @Upcalls {
27-
fn decl(llmod: ModuleRef, prefix: ~str, name: ~str,
28-
tys: ~[TypeRef], rv: TypeRef) ->
29-
ValueRef {
30-
let arg_tys = tys.map(|t| *t);
31-
let fn_ty = T_fn(arg_tys, rv);
32-
return base::decl_cdecl_fn(llmod, prefix + name, fn_ty);
33-
}
34-
fn nothrow(f: ValueRef) -> ValueRef {
35-
base::set_no_unwind(f); f
36-
}
37-
let d: &fn(a: ~str, b: ~[TypeRef], c: TypeRef) -> ValueRef =
38-
|a,b,c| decl(llmod, ~"upcall_", a, b, c);
39-
let dv: &fn(a: ~str, b: ~[TypeRef]) -> ValueRef =
40-
|a,b| decl(llmod, ~"upcall_", a, b, T_void());
25+
macro_rules! upcall (
26+
(fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
27+
let fn_ty = Type::func([ $($arg),* ], &$ret);
28+
base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty)
29+
});
30+
(nothrow fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
31+
let fn_ty = Type::func([ $($arg),* ], &$ret);
32+
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
33+
base::set_no_unwind(decl);
34+
decl
35+
});
36+
(nothrow fn $name:ident -> $ret:expr) => ({
37+
let fn_ty = Type::func([], &$ret);
38+
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
39+
base::set_no_unwind(decl);
40+
decl
41+
})
42+
)
4143

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

4448
@Upcalls {
45-
trace: dv(~"trace", ~[T_ptr(T_i8()),
46-
T_ptr(T_i8()),
47-
int_t]),
48-
call_shim_on_c_stack:
49-
d(~"call_shim_on_c_stack",
50-
// arguments: void *args, void *fn_ptr
51-
~[T_ptr(T_i8()), T_ptr(T_i8())],
52-
int_t),
49+
trace: upcall!(fn trace(opaque_ptr, opaque_ptr, int_ty) -> Type::void()),
50+
call_shim_on_c_stack: upcall!(fn call_shim_on_c_stack(opaque_ptr, opaque_ptr) -> int_ty),
5351
call_shim_on_rust_stack:
54-
d(~"call_shim_on_rust_stack",
55-
~[T_ptr(T_i8()), T_ptr(T_i8())], int_t),
56-
rust_personality:
57-
nothrow(d(~"rust_personality", ~[], T_i32())),
58-
reset_stack_limit:
59-
nothrow(dv(~"reset_stack_limit", ~[]))
52+
upcall!(fn call_shim_on_rust_stack(opaque_ptr, opaque_ptr) -> int_ty),
53+
rust_personality: upcall!(nothrow fn rust_personality -> Type::i32()),
54+
reset_stack_limit: upcall!(nothrow fn reset_stack_limit -> Type::void())
6055
}
6156
}

src/librustc/lib/llvm.rs

+70-135
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ use core::prelude::*;
1313
use core::hashmap::HashMap;
1414
use core::libc::{c_uint, c_ushort};
1515
use core::option;
16-
use core::ptr;
1716
use core::str;
18-
use core::vec;
17+
18+
use middle::trans::type_::Type;
1919

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

21232123
pub struct TypeNames {
2124-
type_names: @mut HashMap<TypeRef, @str>,
2125-
named_types: @mut HashMap<@str, TypeRef>
2126-
}
2127-
2128-
pub fn associate_type(tn: @TypeNames, s: @str, t: TypeRef) {
2129-
assert!(tn.type_names.insert(t, s));
2130-
assert!(tn.named_types.insert(s, t));
2131-
}
2132-
2133-
pub fn type_has_name(tn: @TypeNames, t: TypeRef) -> Option<@str> {
2134-
return tn.type_names.find(&t).map_consume(|x| *x);
2124+
type_names: HashMap<TypeRef, ~str>,
2125+
named_types: HashMap<~str, TypeRef>
21352126
}
21362127

2137-
pub fn name_has_type(tn: @TypeNames, s: @str) -> Option<TypeRef> {
2138-
return tn.named_types.find(&s).map_consume(|x| *x);
2139-
}
2140-
2141-
pub fn mk_type_names() -> @TypeNames {
2142-
@TypeNames {
2143-
type_names: @mut HashMap::new(),
2144-
named_types: @mut HashMap::new()
2128+
impl TypeNames {
2129+
pub fn new() -> TypeNames {
2130+
TypeNames {
2131+
type_names: HashMap::new(),
2132+
named_types: HashMap::new()
2133+
}
21452134
}
2146-
}
21472135

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

2152-
pub fn type_to_str_inner(names: @TypeNames, outer0: &[TypeRef], ty: TypeRef)
2153-
-> @str {
2154-
unsafe {
2155-
match type_has_name(names, ty) {
2156-
option::Some(n) => return n,
2157-
_ => {}
2141+
pub fn find_name<'r>(&'r self, ty: &Type) -> Option<&'r str> {
2142+
match self.type_names.find(&ty.to_ref()) {
2143+
Some(a) => Some(a.slice(0, a.len())),
2144+
None => None
21582145
}
2146+
}
21592147

2160-
let outer = vec::append_one(outer0.to_owned(), ty);
2161-
2162-
let kind = llvm::LLVMGetTypeKind(ty);
2148+
pub fn find_type(&self, s: &str) -> Option<Type> {
2149+
self.named_types.find_equiv(&s).map_consume(|x| Type::from_ref(*x))
2150+
}
21632151

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

2177-
match kind {
2178-
Void => return @"Void",
2179-
Half => return @"Half",
2180-
Float => return @"Float",
2181-
Double => return @"Double",
2182-
X86_FP80 => return @"X86_FP80",
2183-
FP128 => return @"FP128",
2184-
PPC_FP128 => return @"PPC_FP128",
2185-
Label => return @"Label",
2186-
Integer => {
2187-
// See [Note at-str]
2188-
return fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty)
2189-
as int).to_managed();
2190-
}
2191-
Function => {
2192-
let out_ty: TypeRef = llvm::LLVMGetReturnType(ty);
2193-
let n_args = llvm::LLVMCountParamTypes(ty) as uint;
2194-
let args = vec::from_elem(n_args, 0 as TypeRef);
2195-
llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args));
2196-
// See [Note at-str]
2197-
return fmt!("fn(%s) -> %s",
2198-
tys_str(names, outer, args),
2199-
type_to_str_inner(names, outer, out_ty)).to_managed();
2200-
}
2201-
Struct => {
2202-
let elts = struct_tys(ty);
2203-
// See [Note at-str]
2204-
return fmt!("{%s}", tys_str(names, outer, elts)).to_managed();
2205-
}
2206-
Array => {
2207-
let el_ty = llvm::LLVMGetElementType(ty);
2208-
// See [Note at-str]
2209-
return fmt!("[%s@ x %u", type_to_str_inner(names, outer, el_ty),
2210-
llvm::LLVMGetArrayLength(ty) as uint).to_managed();
2211-
}
2212-
Pointer => {
2213-
let mut i = 0;
2214-
for outer0.each |tout| {
2215-
i += 1;
2216-
if *tout as int == ty as int {
2217-
let n = outer0.len() - i;
2218-
// See [Note at-str]
2219-
return fmt!("*\\%d", n as int).to_managed();
2158+
unsafe {
2159+
let kind = ty.kind();
2160+
2161+
match kind {
2162+
Void => ~"Void",
2163+
Half => ~"Half",
2164+
Double => ~"Double",
2165+
X86_FP80 => ~"X86_FP80",
2166+
FP128 => ~"FP128",
2167+
PPC_FP128 => ~"PPC_FP128",
2168+
Label => ~"Label",
2169+
Vector => ~"Vector",
2170+
Metadata => ~"Metadata",
2171+
X86_MMX => ~"X86_MMAX",
2172+
Integer => {
2173+
fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty.to_ref()) as int)
22202174
}
2221-
}
2222-
let addrstr = {
2223-
let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint;
2224-
if addrspace == 0 {
2225-
~""
2226-
} else {
2227-
fmt!("addrspace(%u)", addrspace)
2175+
Function => {
2176+
let out_ty = ty.return_type();
2177+
let args = ty.func_params();
2178+
let args = args.map(|&ty| self.type_to_str(ty)).connect(", ");
2179+
let out_ty = self.type_to_str(out_ty);
2180+
fmt!("fn(%s) -> %s", args, out_ty)
2181+
}
2182+
Struct => {
2183+
let tys = ty.field_types();
2184+
let tys = tys.map(|&ty| self.type_to_str(ty)).connect(", ");
2185+
fmt!("{%s}", tys)
2186+
}
2187+
Array => {
2188+
let el_ty = ty.element_type();
2189+
let el_ty = self.type_to_str(el_ty);
2190+
let len = ty.array_length();
2191+
fmt!("[%s x %u]", el_ty, len)
2192+
}
2193+
Pointer => {
2194+
let el_ty = ty.element_type();
2195+
let el_ty = self.type_to_str(el_ty);
2196+
fmt!("*%s", el_ty)
22282197
}
2229-
};
2230-
// See [Note at-str]
2231-
return fmt!("%s*%s", addrstr, type_to_str_inner(names,
2232-
outer,
2233-
llvm::LLVMGetElementType(ty))).to_managed();
2234-
}
2235-
Vector => return @"Vector",
2236-
Metadata => return @"Metadata",
2237-
X86_MMX => return @"X86_MMAX",
2238-
_ => fail!()
2198+
_ => fail!("Unknown Type Kind (%u)", kind as uint)
2199+
}
22392200
}
22402201
}
2241-
}
2242-
2243-
pub fn float_width(llt: TypeRef) -> uint {
2244-
unsafe {
2245-
return match llvm::LLVMGetTypeKind(llt) as int {
2246-
1 => 32u,
2247-
2 => 64u,
2248-
3 => 80u,
2249-
4 | 5 => 128u,
2250-
_ => fail!("llvm_float_width called on a non-float type")
2251-
};
2252-
}
2253-
}
2254-
2255-
pub fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] {
2256-
unsafe {
2257-
let args = vec::from_elem(llvm::LLVMCountParamTypes(fn_ty) as uint,
2258-
0 as TypeRef);
2259-
llvm::LLVMGetParamTypes(fn_ty, vec::raw::to_ptr(args));
2260-
return args;
2261-
}
2262-
}
22632202

2264-
pub fn struct_tys(struct_ty: TypeRef) -> ~[TypeRef] {
2265-
unsafe {
2266-
let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint;
2267-
if n_elts == 0 {
2268-
return ~[];
2203+
pub fn val_to_str(&self, val: ValueRef) -> ~str {
2204+
unsafe {
2205+
let ty = Type::from_ref(llvm::LLVMTypeOf(val));
2206+
self.type_to_str(ty)
22692207
}
2270-
let mut elts = vec::from_elem(n_elts, ptr::null());
2271-
llvm::LLVMGetStructElementTypes(struct_ty, &mut elts[0]);
2272-
return elts;
22732208
}
22742209
}
22752210

src/librustc/middle/mem_categorization.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ use core::prelude::*;
5050

5151
use middle::ty;
5252
use middle::typeck;
53-
use util::ppaux::{ty_to_str, region_to_str, Repr};
53+
use util::ppaux::{ty_to_str, region_ptr_to_str, Repr};
5454
use util::common::indenter;
5555

5656
use core::uint;
@@ -1026,7 +1026,7 @@ impl mem_categorization_ctxt {
10261026
}
10271027

10281028
pub fn region_to_str(&self, r: ty::Region) -> ~str {
1029-
region_to_str(self.tcx, r)
1029+
region_ptr_to_str(self.tcx, r)
10301030
}
10311031
}
10321032

0 commit comments

Comments
 (0)