From 869b2d706493549e1fc4a621fe9a44fa58d83c5c Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 19 Mar 2012 14:06:59 -0700 Subject: [PATCH] Send string concatenation to specialized upcall, shave 17s off librustc compile time. --- src/rt/rust_upcall.cpp | 28 ++++++++++++++++++++++++++++ src/rt/rustrt.def.in | 1 + src/rustc/back/upcall.rs | 4 ++++ src/rustc/middle/trans/tvec.rs | 11 ++++++----- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index dfeeda34994..647e8edf3a8 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -309,6 +309,34 @@ upcall_vec_grow(rust_vec** vp, size_t new_sz) { UPCALL_SWITCH_STACK(&args, upcall_s_vec_grow); } +struct s_str_concat_args { + rust_vec* lhs; + rust_vec* rhs; + rust_vec* retval; +}; + +extern "C" CDECL void +upcall_s_str_concat(s_str_concat_args *args) { + rust_vec *lhs = args->lhs; + rust_vec *rhs = args->rhs; + rust_task *task = rust_task_thread::get_task(); + size_t fill = lhs->fill + rhs->fill - 1; + rust_vec* v = (rust_vec*)task->kernel->malloc(fill + sizeof(rust_vec), + "str_concat"); + v->fill = v->alloc = fill; + memmove(&v->data[0], &lhs->data[0], lhs->fill - 1); + memmove(&v->data[lhs->fill - 1], &rhs->data[0], rhs->fill); + args->retval = v; +} + +extern "C" CDECL rust_vec* +upcall_str_concat(rust_vec* lhs, rust_vec* rhs) { + s_str_concat_args args = {lhs, rhs, 0}; + UPCALL_SWITCH_STACK(&args, upcall_s_str_concat); + return args.retval; +} + + extern "C" _Unwind_Reason_Code __gxx_personality_v0(int version, _Unwind_Action actions, diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 4d2f7b99f72..4383ebf2657 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -67,6 +67,7 @@ upcall_shared_malloc upcall_shared_free upcall_shared_realloc upcall_vec_grow +upcall_str_concat upcall_call_shim_on_c_stack upcall_call_shim_on_rust_stack upcall_new_stack diff --git a/src/rustc/back/upcall.rs b/src/rustc/back/upcall.rs index a0bb2c5937d..cf862d3ca44 100644 --- a/src/rustc/back/upcall.rs +++ b/src/rustc/back/upcall.rs @@ -18,6 +18,7 @@ type upcalls = mark: ValueRef, vec_grow: ValueRef, vec_push: ValueRef, + str_concat: ValueRef, cmp_type: ValueRef, log_type: ValueRef, alloc_c_stack: ValueRef, @@ -69,6 +70,9 @@ fn declare_upcalls(targ_cfg: @session::config, dvi("vec_push", [T_ptr(T_ptr(opaque_vec_t)), T_ptr(tydesc_type), T_ptr(T_i8())]), + str_concat: + d("str_concat", [T_ptr(opaque_vec_t), T_ptr(opaque_vec_t)], + T_ptr(opaque_vec_t)), cmp_type: dv("cmp_type", [T_ptr(T_i1()), T_ptr(tydesc_type), diff --git a/src/rustc/middle/trans/tvec.rs b/src/rustc/middle/trans/tvec.rs index 34e0ccfaffb..c322e9255e0 100644 --- a/src/rustc/middle/trans/tvec.rs +++ b/src/rustc/middle/trans/tvec.rs @@ -194,15 +194,16 @@ fn trans_append_literal(bcx: block, vptrptr: ValueRef, vec_ty: ty::t, fn trans_add(bcx: block, vec_ty: ty::t, lhs: ValueRef, rhs: ValueRef, dest: dest) -> block { let ccx = bcx.ccx(); - let strings = alt ty::get(vec_ty).struct { - ty::ty_str { true } - _ { false } - }; + + if ty::get(vec_ty).struct == ty::ty_str { + let n = Call(bcx, ccx.upcalls.str_concat, [lhs, rhs]); + ret base::store_in_dest(bcx, n, dest); + } + let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); let llunitty = type_of::type_of(ccx, unit_ty); let lhs_fill = get_fill(bcx, lhs); - if strings { lhs_fill = Sub(bcx, lhs_fill, C_int(ccx, 1)); } let rhs_fill = get_fill(bcx, rhs); let new_fill = Add(bcx, lhs_fill, rhs_fill); let {bcx: bcx, val: new_vec_ptr} = alloc_raw(bcx, new_fill, new_fill);