Navigation Menu

Skip to content

Commit

Permalink
Use a Vec instead of an HashMap for the scope hierarchy
Browse files Browse the repository at this point in the history
This increases regionck performance greatly - type-checking on
librustc decreased from 9.1s to 8.1s. Because of Amdahl's law,
total performance is improved only by about 1.5% (LLVM wizards,
this is your opportunity to shine!).

before:
576.91user 4.26system 7:42.36elapsed 125%CPU (0avgtext+0avgdata 1142192maxresident)k
after:
566.50user 4.84system 7:36.84elapsed 125%CPU (0avgtext+0avgdata 1124304maxresident)k

I am somewhat worried really need to find out why we have this Red Queen's
Race going on here. Originally I suspected it may be a problem from RFC1214's
warnings, but it seems to be an effect from other changes.

However, the increase seems to be mostly in LLVM's time, so I guess
it's the LLVM wizards' problem.
  • Loading branch information
Ariel Ben-Yehuda authored and arielb1 committed Aug 24, 2015
1 parent 2bcc6d8 commit fc30438
Show file tree
Hide file tree
Showing 17 changed files with 561 additions and 540 deletions.
43 changes: 37 additions & 6 deletions src/librustc/metadata/tydecode.rs
Expand Up @@ -207,6 +207,8 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
'B' => {
assert_eq!(self.next(), '[');
// this is totally wrong, but nobody relevant cares about
// this field - it will die soon(TM).
let node_id = self.parse_uint() as ast::NodeId;
assert_eq!(self.next(), '|');
let space = self.parse_param_space();
Expand Down Expand Up @@ -246,24 +248,26 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}

fn parse_scope(&mut self) -> region::CodeExtent {
match self.next() {
self.tcx.region_maps.bogus_code_extent(match self.next() {
// the scopes created here are totally bogus with their
// NodeIDs
'P' => {
assert_eq!(self.next(), '[');
let fn_id = self.parse_uint() as ast::NodeId;
assert_eq!(self.next(), '|');
let body_id = self.parse_uint() as ast::NodeId;
assert_eq!(self.next(), ']');
region::CodeExtent::ParameterScope {
region::CodeExtentData::ParameterScope {
fn_id: fn_id, body_id: body_id
}
}
'M' => {
let node_id = self.parse_uint() as ast::NodeId;
region::CodeExtent::Misc(node_id)
region::CodeExtentData::Misc(node_id)
}
'D' => {
let node_id = self.parse_uint() as ast::NodeId;
region::CodeExtent::DestructionScope(node_id)
region::CodeExtentData::DestructionScope(node_id)
}
'B' => {
assert_eq!(self.next(), '[');
Expand All @@ -274,10 +278,10 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
let block_remainder = region::BlockRemainder {
block: node_id, first_statement_index: first_stmt_index,
};
region::CodeExtent::Remainder(block_remainder)
region::CodeExtentData::Remainder(block_remainder)
}
_ => panic!("parse_scope: bad input")
}
})
}

fn parse_destruction_scope_data(&mut self) -> region::DestructionScopeData {
Expand Down Expand Up @@ -619,6 +623,33 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
}

pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
let name = self.parse_name(':');
let def_id = self.parse_def(NominalType);
let space = self.parse_param_space();
assert_eq!(self.next(), '|');
let index = self.parse_u32();
assert_eq!(self.next(), '|');
let mut bounds = vec![];
loop {
match self.next() {
'R' => bounds.push(self.parse_region()),
'.' => { break; }
c => {
panic!("parse_region_param_def: bad bounds ('{}')", c)
}
}
}
ty::RegionParameterDef {
name: name,
def_id: def_id,
space: space,
index: index,
bounds: bounds
}
}


fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault {
match self.next() {
'a' => ty::ObjectLifetimeDefault::Ambiguous,
Expand Down
35 changes: 18 additions & 17 deletions src/librustc/metadata/tyencode.rs
Expand Up @@ -278,14 +278,14 @@ pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
}
}

fn enc_scope(w: &mut Encoder, _cx: &ctxt, scope: region::CodeExtent) {
match scope {
region::CodeExtent::ParameterScope {
fn enc_scope(w: &mut Encoder, cx: &ctxt, scope: region::CodeExtent) {
match cx.tcx.region_maps.code_extent_data(scope) {
region::CodeExtentData::ParameterScope {
fn_id, body_id } => mywrite!(w, "P[{}|{}]", fn_id, body_id),
region::CodeExtent::Misc(node_id) => mywrite!(w, "M{}", node_id),
region::CodeExtent::Remainder(region::BlockRemainder {
region::CodeExtentData::Misc(node_id) => mywrite!(w, "M{}", node_id),
region::CodeExtentData::Remainder(region::BlockRemainder {
block: b, first_statement_index: i }) => mywrite!(w, "B[{}|{}]", b, i),
region::CodeExtent::DestructionScope(node_id) => mywrite!(w, "D{}", node_id),
region::CodeExtentData::DestructionScope(node_id) => mywrite!(w, "D{}", node_id),
}
}

Expand Down Expand Up @@ -396,17 +396,6 @@ pub fn enc_existential_bounds<'a,'tcx>(w: &mut Encoder,
mywrite!(w, ".");
}

pub fn enc_region_bounds<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
rs: &[ty::Region]) {
for &r in rs {
mywrite!(w, "R");
enc_region(w, cx, r);
}

mywrite!(w, ".");
}

pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
v: &ty::TypeParameterDef<'tcx>) {
mywrite!(w, "{}:{}|{}|{}|{}|",
Expand All @@ -416,6 +405,18 @@ pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
enc_object_lifetime_default(w, cx, v.object_lifetime_default);
}

pub fn enc_region_param_def(w: &mut Encoder, cx: &ctxt,
v: &ty::RegionParameterDef) {
mywrite!(w, "{}:{}|{}|{}|",
v.name, (cx.ds)(v.def_id),
v.space.to_uint(), v.index);
for &r in &v.bounds {
mywrite!(w, "R");
enc_region(w, cx, r);
}
mywrite!(w, ".");
}

fn enc_object_lifetime_default<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
default: ty::ObjectLifetimeDefault)
Expand Down

0 comments on commit fc30438

Please sign in to comment.