rustc: Make type_names and named_types tables in trans use @str instead of ~str

Cuts down on bad copies (though there are still a few that can go
away once there are impls of push / append / + for @str)
This commit is contained in:
Tim Chevalier 2013-01-18 14:30:29 -08:00
parent 9c1476e7a4
commit 97b20f8e02
4 changed files with 61 additions and 58 deletions

View File

@ -1251,20 +1251,19 @@ fn SetLinkage(Global: ValueRef, Link: Linkage) {
/* Memory-managed object interface to type handles. */
type type_names = @{type_names: HashMap<TypeRef, ~str>,
named_types: HashMap<~str, TypeRef>};
type type_names = @{type_names: HashMap<TypeRef, @str>,
named_types: HashMap<@str, TypeRef>};
fn associate_type(tn: type_names, +s: ~str, t: TypeRef) {
// XXX: Bad copy, use @str instead?
assert tn.type_names.insert(t, copy s);
fn associate_type(tn: type_names, s: @str, t: TypeRef) {
assert tn.type_names.insert(t, s);
assert tn.named_types.insert(s, t);
}
fn type_has_name(tn: type_names, t: TypeRef) -> Option<~str> {
fn type_has_name(tn: type_names, t: TypeRef) -> Option<@str> {
return tn.type_names.find(t);
}
fn name_has_type(tn: type_names, +s: ~str) -> Option<TypeRef> {
fn name_has_type(tn: type_names, s: @str) -> Option<TypeRef> {
return tn.named_types.find(s);
}
@ -1273,101 +1272,104 @@ fn mk_type_names() -> type_names {
named_types: HashMap()}
}
fn type_to_str(names: type_names, ty: TypeRef) -> ~str {
fn type_to_str(names: type_names, ty: TypeRef) -> @str {
return type_to_str_inner(names, ~[], ty);
}
fn type_to_str_inner(names: type_names, +outer0: ~[TypeRef], ty: TypeRef) ->
~str {
@str {
unsafe {
match type_has_name(names, ty) {
option::Some(ref n) => return (/*bad*/copy *n),
option::Some(n) => return n,
_ => {}
}
// XXX: Bad copy.
// FIXME #2543: Bad copy.
let outer = vec::append_one(copy outer0, ty);
let kind = llvm::LLVMGetTypeKind(ty);
fn tys_str(names: type_names, outer: ~[TypeRef],
tys: ~[TypeRef]) -> ~str {
let mut s: ~str = ~"";
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);
s += type_to_str_inner(names, outer, *t).to_owned();
}
return s;
// [Note at-str] FIXME #2543: Could rewrite this without the copy,
// but need better @str support.
return s.to_managed();
}
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",
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 => {
return ~"i" + int::str(llvm::LLVMGetIntTypeWidth(ty) as int);
// See [Note at-str]
return fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty)
as int).to_managed();
}
Function => {
let mut s = ~"fn(";
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);
unsafe {
llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args));
}
s += tys_str(names, outer, args);
s += ~") -> ";
s += type_to_str_inner(names, outer, out_ty);
return s;
// 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 mut s: ~str = ~"{";
let n_elts = llvm::LLVMCountStructElementTypes(ty) as uint;
let mut elts = vec::from_elem(n_elts, 0 as TypeRef);
if elts.len() > 0 {
if elts.is_not_empty() {
llvm::LLVMGetStructElementTypes(
ty, ptr::to_mut_unsafe_ptr(&mut elts[0]));
}
s += tys_str(names, outer, elts);
s += ~"}";
return s;
// See [Note at-str]
return fmt!("{%s}", tys_str(names, outer, elts)).to_managed();
}
Array => {
let el_ty = llvm::LLVMGetElementType(ty);
return ~"[" + type_to_str_inner(names, outer, el_ty) + ~" x " +
uint::str(llvm::LLVMGetArrayLength(ty) as uint) + ~"]";
// 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: uint = 0u;
let mut i = 0;
for outer0.each |tout| {
i += 1u;
i += 1;
if *tout as int == ty as int {
let n: uint = vec::len::<TypeRef>(outer0) - i;
return ~"*\\" + int::str(n as int);
let n = outer0.len() - i;
// See [Note at-str]
return fmt!("*\\%d", n as int).to_managed();
}
}
let addrstr = {
let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint;
if addrspace == 0u {
if addrspace == 0 {
~""
} else {
fmt!("addrspace(%u)", addrspace)
}
};
return addrstr + ~"*" +
type_to_str_inner(names,
outer,
llvm::LLVMGetElementType(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"
Vector => return @"Vector",
Metadata => return @"Metadata",
X86_MMX => return @"X86_MMAX"
}
}
}

View File

@ -2979,9 +2979,9 @@ fn trans_crate(sess: session::Session,
let float_type = T_float(targ_cfg);
let task_type = T_task(targ_cfg);
let taskptr_type = T_ptr(task_type);
lib::llvm::associate_type(tn, ~"taskptr", taskptr_type);
lib::llvm::associate_type(tn, @"taskptr", taskptr_type);
let tydesc_type = T_tydesc(targ_cfg);
lib::llvm::associate_type(tn, ~"tydesc", tydesc_type);
lib::llvm::associate_type(tn, @"tydesc", tydesc_type);
let crate_map = decl_crate_map(sess, link_meta, llmod);
let dbg_cx = if sess.opts.debuginfo {
Some(debuginfo::mk_ctxt(copy llmod_id, sess.parse_sess.interner))

View File

@ -188,7 +188,8 @@ fn Invoke(cx: block, Fn: ValueRef, Args: ~[ValueRef],
terminate(cx, "Invoke");
debug!("Invoke(%s with arguments (%s))",
val_str(cx.ccx().tn, Fn),
str::connect(vec::map(Args, |a| val_str(cx.ccx().tn, *a)),
str::connect(vec::map(Args, |a| val_str(cx.ccx().tn,
*a).to_owned()),
~", "));
unsafe {
count_insn(cx, "invoke");

View File

@ -645,7 +645,7 @@ impl Result {
}
}
fn ty_str(tn: type_names, t: TypeRef) -> ~str {
fn ty_str(tn: type_names, t: TypeRef) -> @str {
return lib::llvm::type_to_str(tn, t);
}
@ -655,7 +655,7 @@ fn val_ty(v: ValueRef) -> TypeRef {
}
}
fn val_str(tn: type_names, v: ValueRef) -> ~str {
fn val_str(tn: type_names, v: ValueRef) -> @str {
return ty_str(tn, val_ty(v));
}
@ -729,11 +729,11 @@ impl block {
}
}
fn val_str(val: ValueRef) -> ~str {
fn val_str(val: ValueRef) -> @str {
val_str(self.ccx().tn, val)
}
fn llty_str(llty: TypeRef) -> ~str {
fn llty_str(llty: TypeRef) -> @str {
ty_str(self.ccx().tn, llty)
}
@ -924,7 +924,7 @@ fn T_tydesc_field(cx: @crate_ctxt, field: uint) -> TypeRef unsafe {
}
fn T_generic_glue_fn(cx: @crate_ctxt) -> TypeRef {
let s = ~"glue_fn";
let s = @"glue_fn";
match name_has_type(cx.tn, s) {
Some(t) => return t,
_ => ()
@ -1038,7 +1038,7 @@ fn T_taskptr(cx: @crate_ctxt) -> TypeRef { return T_ptr(cx.task_type); }
// This type must never be used directly; it must always be cast away.
fn T_typaram(tn: type_names) -> TypeRef {
let s = ~"typaram";
let s = @"typaram";
match name_has_type(tn, s) {
Some(t) => return t,
_ => ()
@ -1061,7 +1061,7 @@ fn T_enum_discrim(cx: @crate_ctxt) -> TypeRef {
}
fn T_opaque_enum(cx: @crate_ctxt) -> TypeRef {
let s = ~"opaque_enum";
let s = @"opaque_enum";
match name_has_type(cx.tn, s) {
Some(t) => return t,
_ => ()