rustc: Actually emit shapes

This commit is contained in:
Patrick Walton 2011-08-04 11:25:09 -07:00
parent b55b80ed11
commit 2a3235b58c
3 changed files with 59 additions and 51 deletions

View File

@ -47,30 +47,21 @@ const vec_elt_pad: int = 3;
const vec_elt_data: int = 4;
const tydesc_field_first_param: int = 0;
const tydesc_field_size: int = 1;
const tydesc_field_align: int = 2;
const tydesc_field_copy_glue: int = 3;
const tydesc_field_drop_glue: int = 4;
const tydesc_field_free_glue: int = 5;
const tydesc_field_sever_glue: int = 6;
const tydesc_field_mark_glue: int = 7;
// FIXME no longer used in rustc, drop when rustboot is gone
const tydesc_field_obj_drop_glue: int = 8;
const tydesc_field_is_stateful: int = 9;
const tydesc_field_cmp_glue: int = 10;
const n_tydesc_fields: int = 11;
const tydesc_field_shape: int = 11;
const tydesc_field_shape_tables: int = 12;
const tydesc_field_n_params: int = 13;
const n_tydesc_fields: int = 14;
const cmp_glue_op_eq: uint = 0u;

View File

@ -895,7 +895,8 @@ fn linearize_ty_params(cx: &@block_ctxt, t: &ty::t) ->
fn trans_stack_local_derived_tydesc(cx: &@block_ctxt, llsz: ValueRef,
llalign: ValueRef, llroottydesc: ValueRef,
llparamtydescs: ValueRef) -> ValueRef {
llparamtydescs: ValueRef,
n_params: uint) -> ValueRef {
let llmyroottydesc = alloca(cx, bcx_ccx(cx).tydesc_type);
// By convention, desc 0 is the root descriptor.
@ -904,11 +905,14 @@ fn trans_stack_local_derived_tydesc(cx: &@block_ctxt, llsz: ValueRef,
// Store a pointer to the rest of the descriptors.
let llfirstparam = cx.build.GEP(llparamtydescs, ~[C_int(0), C_int(0)]);
cx.build.Store(llfirstparam,
cx.build.GEP(llmyroottydesc, ~[C_int(0), C_int(0)]));
cx.build.Store(llsz, cx.build.GEP(llmyroottydesc, ~[C_int(0), C_int(1)]));
cx.build.Store(llalign,
cx.build.GEP(llmyroottydesc, ~[C_int(0), C_int(2)]));
store_inbounds(cx, llfirstparam, llmyroottydesc,
~[C_int(0), C_int(abi::tydesc_field_first_param)]);
store_inbounds(cx, C_uint(n_params), llmyroottydesc,
~[C_int(0), C_int(abi::tydesc_field_n_params)]);
store_inbounds(cx, llsz, llmyroottydesc,
~[C_int(0), C_int(abi::tydesc_field_size)]);
store_inbounds(cx, llalign, llmyroottydesc,
~[C_int(0), C_int(abi::tydesc_field_align)]);
ret llmyroottydesc;
}
@ -964,7 +968,8 @@ fn get_derived_tydesc(cx: &@block_ctxt, t: &ty::t, escapes: bool,
v = td_val;
} else {
let llparamtydescs =
alloca(bcx, T_array(T_ptr(bcx_ccx(bcx).tydesc_type), n_params));
alloca(bcx, T_array(T_ptr(bcx_ccx(bcx).tydesc_type),
n_params + 1u));
let i = 0;
for td: ValueRef in tys.descs {
let tdp = bcx.build.GEP(llparamtydescs, ~[C_int(0), C_int(i)]);
@ -973,7 +978,7 @@ fn get_derived_tydesc(cx: &@block_ctxt, t: &ty::t, escapes: bool,
}
v =
trans_stack_local_derived_tydesc(bcx, sz.val, align.val, root,
llparamtydescs);
llparamtydescs, n_params);
}
bcx.fcx.derived_tydescs.insert(t, {lltydesc: v, escapes: escapes});
ret rslt(cx, v);
@ -1191,20 +1196,28 @@ fn emit_tydescs(ccx: &@crate_ctxt) {
none. { ccx.stats.n_null_glues += 1u; C_null(cmp_fn_ty) }
some(v) { ccx.stats.n_real_glues += 1u; v }
};
let // copy_glue
// drop_glue
// free_glue
// sever_glue
// mark_glue
// obj_drop_glue
// is_stateful
tydesc =
let shape = shape::shape_of(ccx, pair.key);
let shape_tables =
llvm::LLVMConstPointerCast(ccx.shape_cx.llshapetables,
T_ptr(T_i8()));
let tydesc =
C_named_struct(ccx.tydesc_type,
~[C_null(T_ptr(T_ptr(ccx.tydesc_type))), ti.size,
ti.align, copy_glue, drop_glue, free_glue,
C_null(glue_fn_ty), C_null(glue_fn_ty),
C_null(glue_fn_ty), C_null(glue_fn_ty),
cmp_glue]); // cmp_glue
~[C_null(T_ptr(T_ptr(ccx.tydesc_type))),
ti.size, // size
ti.align, // align
copy_glue, // copy_glue
drop_glue, // drop_glue
free_glue, // free_glue
C_null(glue_fn_ty), // sever_glue
C_null(glue_fn_ty), // mark_glue
C_null(glue_fn_ty), // obj_drop_glue
C_null(glue_fn_ty), // is_stateful
cmp_glue, // cmp_glue
C_shape(ccx, shape), // shape
shape_tables, // shape_tables
C_int(0)]); // n_params
let gvar = ti.tydesc;
llvm::LLVMSetInitializer(gvar, tydesc);
@ -2288,8 +2301,9 @@ fn call_cmp_glue(cx: &@block_ctxt, lhs: ValueRef, rhs: ValueRef, t: &ty::t,
let ti = none[@tydesc_info];
let r = get_tydesc(cx, t, false, ti);
lazily_emit_tydesc_glue(cx, abi::tydesc_field_cmp_glue, ti);
let lltydesc = r.val;
let lltydescs =
r.bcx.build.GEP(r.val,
r.bcx.build.GEP(lltydesc,
~[C_int(0), C_int(abi::tydesc_field_first_param)]);
lltydescs = r.bcx.build.Load(lltydescs);
@ -2297,7 +2311,7 @@ fn call_cmp_glue(cx: &@block_ctxt, lhs: ValueRef, rhs: ValueRef, t: &ty::t,
alt ti {
none. {
let llfnptr =
r.bcx.build.GEP(r.val,
r.bcx.build.GEP(lltydesc,
~[C_int(0), C_int(abi::tydesc_field_cmp_glue)]);
llfn = r.bcx.build.Load(llfnptr);
}
@ -2306,7 +2320,7 @@ fn call_cmp_glue(cx: &@block_ctxt, lhs: ValueRef, rhs: ValueRef, t: &ty::t,
let llcmpresultptr = alloca(r.bcx, T_i1());
let llargs: ValueRef[] =
~[llcmpresultptr, r.bcx.fcx.lltaskptr, C_null(T_ptr(T_nil())),
~[llcmpresultptr, r.bcx.fcx.lltaskptr, lltydesc,
lltydescs, llrawlhsptr, llrawrhsptr, llop];
r.bcx.build.Call(llfn, llargs);
ret rslt(r.bcx, r.bcx.build.Load(llcmpresultptr));
@ -8000,8 +8014,9 @@ fn trans_crate(sess: &session::session, crate: &@ast::crate, tcx: &ty::ctxt,
trans_mod(cx, crate.node.module);
create_crate_map(ccx);
emit_tydescs(ccx);
// Translate the metadata:
shape::gen_shape_tables(ccx);
// Translate the metadata.
write_metadata(cx.ccx, crate);
if ccx.sess.get_opts().stats {
log_err "--- trans stats ---";

View File

@ -597,22 +597,13 @@ fn T_tydesc(taskptr_type: TypeRef) -> TypeRef {
T_ptr(T_fn(~[T_ptr(T_nil()), taskptr_type, T_ptr(T_nil()), tydescpp,
pvoid], T_void()));
let cmp_glue_fn_ty =
T_ptr(T_fn(~[T_ptr(T_i1()), taskptr_type, T_ptr(T_nil()), tydescpp,
T_ptr(T_fn(~[T_ptr(T_i1()), taskptr_type, T_ptr(tydesc), tydescpp,
pvoid, pvoid, T_i8()], T_void()));
let // first_param
// size
// align
// copy_glue
// drop_glue
// free_glue
// sever_glue
// mark_glue
// obj_drop_glue
// is_stateful
elems =
let elems =
~[tydescpp, T_int(), T_int(), glue_fn_ty, glue_fn_ty, glue_fn_ty,
glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, cmp_glue_fn_ty];
glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, cmp_glue_fn_ty,
T_ptr(T_i8()), T_ptr(T_i8()), T_int()];
set_struct_body(tydesc, elems);
ret tydesc;
}
@ -874,3 +865,14 @@ fn C_bytes(bytes : &u8[]) -> ValueRef {
ivec::len(bytes), False);
}
fn C_shape(ccx : &@crate_ctxt, bytes : &u8[]) -> ValueRef {
let llshape = C_bytes(bytes);
let llglobal = llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape),
str::buf(ccx.names.next("shape")));
llvm::LLVMSetInitializer(llglobal, llshape);
llvm::LLVMSetGlobalConstant(llglobal, True);
llvm::LLVMSetLinkage(llglobal,
lib::llvm::LLVMInternalLinkage as llvm::Linkage);
ret llvm::LLVMConstPointerCast(llglobal, T_ptr(T_i8()));
}