Skip to content

Commit 8c6b8bb

Browse files
authored
Rollup merge of rust-lang#116560 - ouz-a:efficient_ids, r=oli-obk
In smir use `FxIndexMap` to store indexed ids Previously we used `vec` for storing indexed types, which is fine for small cases but will lead to huge performance issues when we use `smir` for real world cases. Addresses rust-lang/project-stable-mir#35 r? `@oli-obk`
2 parents 42dcf77 + 0bcb058 commit 8c6b8bb

File tree

6 files changed

+88
-36
lines changed

6 files changed

+88
-36
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4504,6 +4504,7 @@ dependencies = [
45044504
name = "rustc_smir"
45054505
version = "0.0.0"
45064506
dependencies = [
4507+
"rustc_data_structures",
45074508
"rustc_driver",
45084509
"rustc_hir",
45094510
"rustc_interface",

compiler/rustc_smir/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ version = "0.0.0"
44
edition = "2021"
55

66
[dependencies]
7+
rustc_data_structures = { path = "../rustc_data_structures" }
78
rustc_driver = { path = "../rustc_driver" }
89
rustc_hir = { path = "../rustc_hir" }
910
rustc_interface = { path = "../rustc_interface" }

compiler/rustc_smir/src/rustc_internal/mod.rs

+43-29
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,27 @@
33
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
44
//! until stable MIR is complete.
55
6-
use std::ops::{ControlFlow, Index};
7-
86
use crate::rustc_internal;
97
use crate::rustc_smir::Tables;
8+
use rustc_data_structures::fx;
109
use rustc_driver::{Callbacks, Compilation, RunCompiler};
1110
use rustc_interface::{interface, Queries};
1211
use rustc_middle::mir::interpret::AllocId;
1312
use rustc_middle::ty::TyCtxt;
1413
use rustc_span::def_id::{CrateNum, DefId};
1514
use rustc_span::Span;
15+
use stable_mir::ty::IndexedVal;
1616
use stable_mir::CompilerError;
17+
use std::fmt::Debug;
18+
use std::hash::Hash;
19+
use std::ops::{ControlFlow, Index};
1720

1821
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
1922
type Output = DefId;
2023

2124
#[inline(always)]
2225
fn index(&self, index: stable_mir::DefId) -> &Self::Output {
23-
&self.def_ids[index.0]
26+
&self.def_ids[index]
2427
}
2528
}
2629

@@ -29,7 +32,7 @@ impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> {
2932

3033
#[inline(always)]
3134
fn index(&self, index: stable_mir::ty::Span) -> &Self::Output {
32-
&self.spans[index.0]
35+
&self.spans[index]
3336
}
3437
}
3538

@@ -95,36 +98,15 @@ impl<'tcx> Tables<'tcx> {
9598
}
9699

97100
fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId {
98-
// FIXME: this becomes inefficient when we have too many ids
99-
for (i, &d) in self.def_ids.iter().enumerate() {
100-
if d == did {
101-
return stable_mir::DefId(i);
102-
}
103-
}
104-
let id = self.def_ids.len();
105-
self.def_ids.push(did);
106-
stable_mir::DefId(id)
101+
self.def_ids.create_or_fetch(did)
107102
}
108103

109104
fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::AllocId {
110-
// FIXME: this becomes inefficient when we have too many ids
111-
if let Some(i) = self.alloc_ids.iter().position(|a| *a == aid) {
112-
return stable_mir::AllocId(i);
113-
};
114-
let id = self.def_ids.len();
115-
self.alloc_ids.push(aid);
116-
stable_mir::AllocId(id)
105+
self.alloc_ids.create_or_fetch(aid)
117106
}
118107

119108
pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span {
120-
for (i, &sp) in self.spans.iter().enumerate() {
121-
if sp == span {
122-
return stable_mir::ty::Span(i);
123-
}
124-
}
125-
let id = self.spans.len();
126-
self.spans.push(span);
127-
stable_mir::ty::Span(id)
109+
self.spans.create_or_fetch(span)
128110
}
129111
}
130112

@@ -134,7 +116,13 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
134116

135117
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
136118
stable_mir::run(
137-
Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] },
119+
Tables {
120+
tcx,
121+
def_ids: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() },
122+
alloc_ids: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() },
123+
spans: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() },
124+
types: vec![],
125+
},
138126
f,
139127
);
140128
}
@@ -197,3 +185,29 @@ where
197185
})
198186
}
199187
}
188+
189+
/// Simmilar to rustc's `FxIndexMap`, `IndexMap` with extra
190+
/// safety features added.
191+
pub struct IndexMap<K, V> {
192+
index_map: fx::FxIndexMap<K, V>,
193+
}
194+
195+
impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> IndexMap<K, V> {
196+
pub fn create_or_fetch(&mut self, key: K) -> V {
197+
let len = self.index_map.len();
198+
let v = self.index_map.entry(key).or_insert(V::to_val(len));
199+
*v
200+
}
201+
}
202+
203+
impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V>
204+
for IndexMap<K, V>
205+
{
206+
type Output = K;
207+
208+
fn index(&self, index: V) -> &Self::Output {
209+
let (k, v) = self.index_map.get_index(index.to_index()).unwrap();
210+
assert_eq!(*v, index, "Provided value doesn't match with indexed value");
211+
k
212+
}
213+
}

compiler/rustc_smir/src/rustc_smir/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//!
88
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
99
10+
use crate::rustc_internal::IndexMap;
1011
use crate::rustc_smir::hir::def::DefKind;
1112
use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region};
1213
use rustc_hir as hir;
@@ -201,9 +202,9 @@ impl<S, R: PartialEq> PartialEq<R> for MaybeStable<S, R> {
201202

202203
pub struct Tables<'tcx> {
203204
pub tcx: TyCtxt<'tcx>,
204-
pub def_ids: Vec<DefId>,
205-
pub alloc_ids: Vec<AllocId>,
206-
pub spans: Vec<rustc_span::Span>,
205+
pub def_ids: IndexMap<DefId, stable_mir::DefId>,
206+
pub alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
207+
pub spans: IndexMap<rustc_span::Span, Span>,
207208
pub types: Vec<MaybeStable<stable_mir::ty::TyKind, Ty<'tcx>>>,
208209
}
209210

compiler/stable_mir/src/lib.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ use std::fmt;
2222
use std::fmt::Debug;
2323

2424
use self::ty::{
25-
GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind,
25+
GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, Span, TraitDecl, TraitDef, Ty,
26+
TyKind,
2627
};
2728

2829
#[macro_use]
@@ -41,7 +42,7 @@ pub type CrateNum = usize;
4142

4243
/// A unique identification number for each item accessible for the current compilation unit.
4344
#[derive(Clone, Copy, PartialEq, Eq)]
44-
pub struct DefId(pub usize);
45+
pub struct DefId(usize);
4546

4647
impl Debug for DefId {
4748
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -52,9 +53,28 @@ impl Debug for DefId {
5253
}
5354
}
5455

56+
impl IndexedVal for DefId {
57+
fn to_val(index: usize) -> Self {
58+
DefId(index)
59+
}
60+
61+
fn to_index(&self) -> usize {
62+
self.0
63+
}
64+
}
65+
5566
/// A unique identification number for each provenance
5667
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
57-
pub struct AllocId(pub usize);
68+
pub struct AllocId(usize);
69+
70+
impl IndexedVal for AllocId {
71+
fn to_val(index: usize) -> Self {
72+
AllocId(index)
73+
}
74+
fn to_index(&self) -> usize {
75+
self.0
76+
}
77+
}
5878

5979
/// A list of crate items.
6080
pub type CrateItems = Vec<CrateItem>;

compiler/stable_mir/src/ty.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub struct Placeholder<T> {
7575
}
7676

7777
#[derive(Clone, Copy, PartialEq, Eq)]
78-
pub struct Span(pub usize);
78+
pub struct Span(usize);
7979

8080
impl Debug for Span {
8181
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@@ -86,6 +86,15 @@ impl Debug for Span {
8686
}
8787
}
8888

89+
impl IndexedVal for Span {
90+
fn to_val(index: usize) -> Self {
91+
Span(index)
92+
}
93+
fn to_index(&self) -> usize {
94+
self.0
95+
}
96+
}
97+
8998
#[derive(Clone, Debug)]
9099
pub enum TyKind {
91100
RigidTy(RigidTy),
@@ -565,3 +574,9 @@ pub enum ImplPolarity {
565574
Negative,
566575
Reservation,
567576
}
577+
578+
pub trait IndexedVal {
579+
fn to_val(index: usize) -> Self;
580+
581+
fn to_index(&self) -> usize;
582+
}

0 commit comments

Comments
 (0)