Skip to content

Commit a4663d2

Browse files
committed
rustc: Add fast paths for vars and param folds. 3x typechecking speedup.
1 parent 73ae684 commit a4663d2

File tree

2 files changed

+70
-61
lines changed

2 files changed

+70
-61
lines changed

src/comp/middle/trans.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,8 +1260,7 @@ fn simplify_type(&@crate_ctxt ccx, &ty::t typ) -> ty::t {
12601260
case (_) { ret typ; }
12611261
}
12621262
}
1263-
auto f = bind simplifier(ccx, _);
1264-
ret ty::fold_ty(ccx.tcx, f, typ);
1263+
ret ty::fold_ty(ccx.tcx, ty::fm_general(bind simplifier(ccx, _)), typ);
12651264
}
12661265

12671266
// Computes the size of the data part of a non-dynamically-sized tag.

src/comp/middle/ty.rs

Lines changed: 69 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -697,10 +697,22 @@ fn walk_ty(&ctxt cx, ty_walk walker, t ty) {
697697
walker(ty);
698698
}
699699

700-
type ty_fold = fn(t) -> t;
700+
tag fold_mode {
701+
fm_var(fn(int)->t);
702+
fm_param(fn(uint)->t);
703+
fm_general(fn(t)->t);
704+
}
701705

702-
fn fold_ty(&ctxt cx, ty_fold fld, t ty_0) -> t {
706+
fn fold_ty(&ctxt cx, fold_mode fld, t ty_0) -> t {
703707
auto ty = ty_0;
708+
709+
// Fast paths.
710+
alt (fld) {
711+
case (fm_var(_)) { if (!type_contains_vars(cx, ty)) { ret ty; } }
712+
case (fm_param(_)) { if (!type_contains_params(cx, ty)) { ret ty; } }
713+
case (fm_general(_)) { /* no fast path */ }
714+
}
715+
704716
alt (struct(cx, ty)) {
705717
case (ty_nil) { /* no-op */ }
706718
case (ty_bot) { /* no-op */ }
@@ -788,11 +800,25 @@ fn fold_ty(&ctxt cx, ty_fold fld, t ty_0) -> t {
788800
}
789801
ty = copy_cname(cx, mk_obj(cx, new_methods), ty);
790802
}
791-
case (ty_var(_)) { /* no-op */ }
792-
case (ty_param(_)) { /* no-op */ }
803+
case (ty_var(?id)) {
804+
alt (fld) {
805+
case (fm_var(?folder)) { ty = folder(id); }
806+
case (_) { /* no-op */ }
807+
}
808+
}
809+
case (ty_param(?id)) {
810+
alt (fld) {
811+
case (fm_param(?folder)) { ty = folder(id); }
812+
case (_) { /* no-op */ }
813+
}
814+
}
793815
}
794816

795-
ret fld(ty);
817+
// If this is a general type fold, then we need to run it now.
818+
alt (fld) {
819+
case (fm_general(?folder)) { ret folder(ty); }
820+
case (_) { ret ty; }
821+
}
796822
}
797823

798824
// Type utilities
@@ -2101,29 +2127,23 @@ mod unify {
21012127
fn resolve_all_vars(&ty_ctxt tcx, &@var_bindings vb, t typ) -> t {
21022128
if (!type_contains_vars(tcx, typ)) { ret typ; }
21032129

2104-
fn folder(ty_ctxt tcx, @var_bindings vb, t typ) -> t {
2105-
alt (struct(tcx, typ)) {
2106-
case (ty_var(?vid)) {
2107-
// It's possible that we haven't even created the var set.
2108-
// Handle this case gracefully.
2109-
if ((vid as uint) >= ufind::set_count(vb.sets)) {
2110-
ret typ;
2111-
}
2130+
fn folder(ty_ctxt tcx, @var_bindings vb, int vid) -> t {
2131+
// It's possible that we haven't even created the var set.
2132+
// Handle this case gracefully.
2133+
if ((vid as uint) >= ufind::set_count(vb.sets)) {
2134+
ret ty::mk_var(tcx, vid);
2135+
}
21122136

2113-
auto root_id = ufind::find(vb.sets, vid as uint);
2114-
alt (smallintmap::find[t](vb.types, root_id)) {
2115-
case (some[t](?typ2)) {
2116-
ret fold_ty(tcx, bind folder(tcx, vb, _), typ2);
2117-
}
2118-
case (none[t]) { ret typ; }
2119-
}
2137+
auto root_id = ufind::find(vb.sets, vid as uint);
2138+
alt (smallintmap::find[t](vb.types, root_id)) {
2139+
case (some[t](?typ2)) {
2140+
ret fold_ty(tcx, fm_var(bind folder(tcx, vb, _)), typ2);
21202141
}
2121-
2122-
case (_) { ret typ; }
2142+
case (none[t]) { ret ty::mk_var(tcx, vid); }
21232143
}
21242144
}
21252145

2126-
ret fold_ty(tcx, bind folder(tcx, vb, _), typ);
2146+
ret fold_ty(tcx, fm_var(bind folder(tcx, vb, _)), typ);
21272147
}
21282148

21292149
// If the given type is a variable, returns the structure of that type.
@@ -2542,32 +2562,29 @@ mod unify {
25422562

25432563
fn fixup_vars(ty_ctxt tcx, @var_bindings vb, t typ) -> fixup_result {
25442564
fn subst_vars(ty_ctxt tcx, @var_bindings vb,
2545-
@mutable option::t[int] unresolved, t typ) -> t {
2546-
alt (struct(tcx, typ)) {
2547-
case (ty::ty_var(?vid)) {
2548-
if ((vid as uint) >= ufind::set_count(vb.sets)) {
2549-
*unresolved = some[int](vid);
2550-
ret typ;
2551-
}
2565+
@mutable option::t[int] unresolved, int vid) -> t {
2566+
if ((vid as uint) >= ufind::set_count(vb.sets)) {
2567+
*unresolved = some[int](vid);
2568+
ret ty::mk_var(tcx, vid);
2569+
}
25522570

2553-
auto root_id = ufind::find(vb.sets, vid as uint);
2554-
alt (smallintmap::find[t](vb.types, root_id)) {
2555-
case (none[t]) {
2556-
*unresolved = some[int](vid);
2557-
ret typ;
2558-
}
2559-
case (some[t](?rt)) {
2560-
ret fold_ty(tcx,
2561-
bind subst_vars(tcx, vb, unresolved, _), rt);
2562-
}
2563-
}
2571+
auto root_id = ufind::find(vb.sets, vid as uint);
2572+
alt (smallintmap::find[t](vb.types, root_id)) {
2573+
case (none[t]) {
2574+
*unresolved = some[int](vid);
2575+
ret ty::mk_var(tcx, vid);
2576+
}
2577+
case (some[t](?rt)) {
2578+
ret fold_ty(tcx,
2579+
fm_var(bind subst_vars(tcx, vb, unresolved, _)), rt);
25642580
}
2565-
case (_) { ret typ; }
25662581
}
25672582
}
25682583

25692584
auto unresolved = @mutable none[int];
2570-
auto rty = fold_ty(tcx, bind subst_vars(tcx, vb, unresolved, _), typ);
2585+
auto rty = fold_ty(tcx,
2586+
fm_var(bind subst_vars(tcx, vb, unresolved, _)),
2587+
typ);
25712588

25722589
auto ur = *unresolved;
25732590
alt (ur) {
@@ -2641,25 +2658,21 @@ fn type_err_to_str(&ty::type_err err) -> str {
26412658
// Converts type parameters in a type to type variables and returns the
26422659
// resulting type along with a list of type variable IDs.
26432660
fn bind_params_in_type(&ctxt cx, fn()->int next_ty_var, t typ,
2644-
uint ty_param_count)
2645-
-> tup(vec[int], t) {
2661+
uint ty_param_count) -> tup(vec[int], t) {
26462662
let vec[int] param_var_ids = [];
26472663
auto i = 0u;
26482664
while (i < ty_param_count) {
26492665
param_var_ids += [next_ty_var()];
26502666
i += 1u;
26512667
}
26522668

2653-
fn binder(ctxt cx, vec[int] param_var_ids, fn()->int next_ty_var, t typ)
2654-
-> t {
2655-
alt (struct(cx, typ)) {
2656-
case (ty_param(?index)) { ret mk_var(cx, param_var_ids.(index)); }
2657-
case (_) { ret typ; }
2658-
}
2669+
fn binder(ctxt cx, vec[int] param_var_ids, fn()->int next_ty_var,
2670+
uint index) -> t {
2671+
ret mk_var(cx, param_var_ids.(index));
26592672
}
26602673

2661-
auto f = bind binder(cx, param_var_ids, next_ty_var, _);
2662-
auto new_typ = fold_ty(cx, f, typ);
2674+
auto new_typ = fold_ty(cx,
2675+
fm_param(bind binder(cx, param_var_ids, next_ty_var, _)), typ);
26632676
ret tup(param_var_ids, new_typ);
26642677
}
26652678

@@ -2668,14 +2681,11 @@ fn bind_params_in_type(&ctxt cx, fn()->int next_ty_var, t typ,
26682681
fn substitute_type_params(&ctxt cx, vec[ty::t] substs, t typ) -> t {
26692682
if (!type_contains_params(cx, typ)) { ret typ; }
26702683

2671-
fn substituter(ctxt cx, vec[ty::t] substs, t typ) -> t {
2672-
alt (struct(cx, typ)) {
2673-
case (ty_param(?idx)) { ret substs.(idx); }
2674-
case (_) { ret typ; }
2675-
}
2684+
fn substituter(ctxt cx, vec[ty::t] substs, uint idx) -> t {
2685+
ret substs.(idx);
26762686
}
26772687

2678-
ret fold_ty(cx, bind substituter(cx, substs, _), typ);
2688+
ret fold_ty(cx, fm_param(bind substituter(cx, substs, _)), typ);
26792689
}
26802690

26812691
fn def_has_ty_params(&ast::def def) -> bool {

0 commit comments

Comments
 (0)