From 0f27c1b5b550deef02c3916fa81ea3c6edf8145e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20A=C4=9Fcayaz=C4=B1?= Date: Mon, 9 Oct 2023 12:56:14 +0300 Subject: [PATCH 1/4] defids are indexmapped --- Cargo.lock | 1 + compiler/rustc_smir/Cargo.toml | 1 + compiler/rustc_smir/src/rustc_internal/mod.rs | 25 +++++++++++-------- compiler/rustc_smir/src/rustc_smir/mod.rs | 3 ++- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 082bb4be93c..2882ec0682e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4504,6 +4504,7 @@ dependencies = [ name = "rustc_smir" version = "0.0.0" dependencies = [ + "rustc_data_structures", "rustc_driver", "rustc_hir", "rustc_interface", diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index 3e0d6baab6a..2b77044d6bf 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.0" edition = "2021" [dependencies] +rustc_data_structures = { path = "../rustc_data_structures" } rustc_driver = { path = "../rustc_driver" } rustc_hir = { path = "../rustc_hir" } rustc_interface = { path = "../rustc_interface" } diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 36eb2247253..2f4bc5a0499 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -7,6 +7,7 @@ use std::ops::{ControlFlow, Index}; use crate::rustc_internal; use crate::rustc_smir::Tables; +use rustc_data_structures::fx; use rustc_driver::{Callbacks, Compilation, RunCompiler}; use rustc_interface::{interface, Queries}; use rustc_middle::mir::interpret::AllocId; @@ -20,7 +21,7 @@ impl<'tcx> Index for Tables<'tcx> { #[inline(always)] fn index(&self, index: stable_mir::DefId) -> &Self::Output { - &self.def_ids[index.0] + &self.def_ids.get_index(index.0).unwrap().0 } } @@ -95,15 +96,13 @@ impl<'tcx> Tables<'tcx> { } fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId { - // FIXME: this becomes inefficient when we have too many ids - for (i, &d) in self.def_ids.iter().enumerate() { - if d == did { - return stable_mir::DefId(i); - } + if let Some(i) = self.def_ids.get(&did) { + return *i; + } else { + let id = self.def_ids.len(); + self.def_ids.insert(did, stable_mir::DefId(id)); + stable_mir::DefId(id) } - let id = self.def_ids.len(); - self.def_ids.push(did); - stable_mir::DefId(id) } fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::AllocId { @@ -134,7 +133,13 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) { stable_mir::run( - Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] }, + Tables { + tcx, + def_ids: fx::FxIndexMap::default(), + alloc_ids: vec![], + spans: vec![], + types: vec![], + }, f, ); } diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 7d1122c2fd2..144f1625b04 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,6 +9,7 @@ use crate::rustc_smir::hir::def::DefKind; use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region}; +use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_middle::mir; use rustc_middle::mir::interpret::{alloc_range, AllocId}; @@ -194,7 +195,7 @@ impl PartialEq for MaybeStable { pub struct Tables<'tcx> { pub tcx: TyCtxt<'tcx>, - pub def_ids: Vec, + pub def_ids: FxIndexMap, pub alloc_ids: Vec, pub spans: Vec, pub types: Vec>>, From 5f079dd2ffd0d09a3f2f9250c7d302efff1df4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20A=C4=9Fcayaz=C4=B1?= Date: Mon, 9 Oct 2023 12:58:41 +0300 Subject: [PATCH 2/4] alloc id is indexmapped --- compiler/rustc_smir/src/rustc_internal/mod.rs | 15 ++++++++------- compiler/rustc_smir/src/rustc_smir/mod.rs | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 2f4bc5a0499..d0515df9ad5 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -107,12 +107,13 @@ impl<'tcx> Tables<'tcx> { fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::AllocId { // FIXME: this becomes inefficient when we have too many ids - if let Some(i) = self.alloc_ids.iter().position(|a| *a == aid) { - return stable_mir::AllocId(i); - }; - let id = self.def_ids.len(); - self.alloc_ids.push(aid); - stable_mir::AllocId(id) + if let Some(i) = self.alloc_ids.get(&aid) { + return *i; + } else { + let id = self.def_ids.len(); + self.alloc_ids.insert(aid, stable_mir::AllocId(id)); + stable_mir::AllocId(id) + } } pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span { @@ -136,7 +137,7 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) { Tables { tcx, def_ids: fx::FxIndexMap::default(), - alloc_ids: vec![], + alloc_ids: fx::FxIndexMap::default(), spans: vec![], types: vec![], }, diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 144f1625b04..42688613a61 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -196,7 +196,7 @@ impl PartialEq for MaybeStable { pub struct Tables<'tcx> { pub tcx: TyCtxt<'tcx>, pub def_ids: FxIndexMap, - pub alloc_ids: Vec, + pub alloc_ids: FxIndexMap, pub spans: Vec, pub types: Vec>>, } From 77df2cd9a5cbb461a0fd430f7d36f2e181a0386a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20A=C4=9Fcayaz=C4=B1?= Date: Mon, 9 Oct 2023 13:03:58 +0300 Subject: [PATCH 3/4] spans are now indexmapped --- compiler/rustc_smir/src/rustc_internal/mod.rs | 18 ++++++++---------- compiler/rustc_smir/src/rustc_smir/mod.rs | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index d0515df9ad5..25c7bd748ee 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -30,7 +30,7 @@ impl<'tcx> Index for Tables<'tcx> { #[inline(always)] fn index(&self, index: stable_mir::ty::Span) -> &Self::Output { - &self.spans[index.0] + &self.spans.get_index(index.0).unwrap().0 } } @@ -106,7 +106,6 @@ impl<'tcx> Tables<'tcx> { } fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::AllocId { - // FIXME: this becomes inefficient when we have too many ids if let Some(i) = self.alloc_ids.get(&aid) { return *i; } else { @@ -117,14 +116,13 @@ impl<'tcx> Tables<'tcx> { } pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span { - for (i, &sp) in self.spans.iter().enumerate() { - if sp == span { - return stable_mir::ty::Span(i); - } + if let Some(i) = self.spans.get(&span) { + return *i; + } else { + let id = self.spans.len(); + self.spans.insert(span, stable_mir::ty::Span(id)); + stable_mir::ty::Span(id) } - let id = self.spans.len(); - self.spans.push(span); - stable_mir::ty::Span(id) } } @@ -138,7 +136,7 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) { tcx, def_ids: fx::FxIndexMap::default(), alloc_ids: fx::FxIndexMap::default(), - spans: vec![], + spans: fx::FxIndexMap::default(), types: vec![], }, f, diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 42688613a61..757cfa82d3c 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -197,7 +197,7 @@ pub struct Tables<'tcx> { pub tcx: TyCtxt<'tcx>, pub def_ids: FxIndexMap, pub alloc_ids: FxIndexMap, - pub spans: Vec, + pub spans: FxIndexMap, pub types: Vec>>, } From 0bcb058fb13242bf6804e66413315a784484ab09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20A=C4=9Fcayaz=C4=B1?= Date: Tue, 10 Oct 2023 11:28:45 +0300 Subject: [PATCH 4/4] add new wrapper for FxIndexMap --- compiler/rustc_smir/src/rustc_internal/mod.rs | 66 +++++++++++-------- compiler/rustc_smir/src/rustc_smir/mod.rs | 8 +-- compiler/stable_mir/src/lib.rs | 26 +++++++- compiler/stable_mir/src/ty.rs | 17 ++++- 4 files changed, 81 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 25c7bd748ee..e3c84f06543 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -3,8 +3,6 @@ //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs //! until stable MIR is complete. -use std::ops::{ControlFlow, Index}; - use crate::rustc_internal; use crate::rustc_smir::Tables; use rustc_data_structures::fx; @@ -14,14 +12,18 @@ use rustc_middle::mir::interpret::AllocId; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::Span; +use stable_mir::ty::IndexedVal; use stable_mir::CompilerError; +use std::fmt::Debug; +use std::hash::Hash; +use std::ops::{ControlFlow, Index}; impl<'tcx> Index for Tables<'tcx> { type Output = DefId; #[inline(always)] fn index(&self, index: stable_mir::DefId) -> &Self::Output { - &self.def_ids.get_index(index.0).unwrap().0 + &self.def_ids[index] } } @@ -30,7 +32,7 @@ impl<'tcx> Index for Tables<'tcx> { #[inline(always)] fn index(&self, index: stable_mir::ty::Span) -> &Self::Output { - &self.spans.get_index(index.0).unwrap().0 + &self.spans[index] } } @@ -96,33 +98,15 @@ impl<'tcx> Tables<'tcx> { } fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId { - if let Some(i) = self.def_ids.get(&did) { - return *i; - } else { - let id = self.def_ids.len(); - self.def_ids.insert(did, stable_mir::DefId(id)); - stable_mir::DefId(id) - } + self.def_ids.create_or_fetch(did) } fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::AllocId { - if let Some(i) = self.alloc_ids.get(&aid) { - return *i; - } else { - let id = self.def_ids.len(); - self.alloc_ids.insert(aid, stable_mir::AllocId(id)); - stable_mir::AllocId(id) - } + self.alloc_ids.create_or_fetch(aid) } pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span { - if let Some(i) = self.spans.get(&span) { - return *i; - } else { - let id = self.spans.len(); - self.spans.insert(span, stable_mir::ty::Span(id)); - stable_mir::ty::Span(id) - } + self.spans.create_or_fetch(span) } } @@ -134,9 +118,9 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) { stable_mir::run( Tables { tcx, - def_ids: fx::FxIndexMap::default(), - alloc_ids: fx::FxIndexMap::default(), - spans: fx::FxIndexMap::default(), + def_ids: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() }, + alloc_ids: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() }, + spans: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() }, types: vec![], }, f, @@ -201,3 +185,29 @@ where }) } } + +/// Simmilar to rustc's `FxIndexMap`, `IndexMap` with extra +/// safety features added. +pub struct IndexMap { + index_map: fx::FxIndexMap, +} + +impl IndexMap { + pub fn create_or_fetch(&mut self, key: K) -> V { + let len = self.index_map.len(); + let v = self.index_map.entry(key).or_insert(V::to_val(len)); + *v + } +} + +impl Index + for IndexMap +{ + type Output = K; + + fn index(&self, index: V) -> &Self::Output { + let (k, v) = self.index_map.get_index(index.to_index()).unwrap(); + assert_eq!(*v, index, "Provided value doesn't match with indexed value"); + k + } +} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 757cfa82d3c..09dc7475ec8 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,9 +7,9 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. +use crate::rustc_internal::IndexMap; use crate::rustc_smir::hir::def::DefKind; use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region}; -use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_middle::mir; use rustc_middle::mir::interpret::{alloc_range, AllocId}; @@ -195,9 +195,9 @@ impl PartialEq for MaybeStable { pub struct Tables<'tcx> { pub tcx: TyCtxt<'tcx>, - pub def_ids: FxIndexMap, - pub alloc_ids: FxIndexMap, - pub spans: FxIndexMap, + pub def_ids: IndexMap, + pub alloc_ids: IndexMap, + pub spans: IndexMap, pub types: Vec>>, } diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 104985493ef..0a5c62eee04 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -22,7 +22,8 @@ use std::fmt; use std::fmt::Debug; use self::ty::{ - GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind, + GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, Span, TraitDecl, TraitDef, Ty, + TyKind, }; #[macro_use] @@ -41,7 +42,7 @@ pub type CrateNum = usize; /// A unique identification number for each item accessible for the current compilation unit. #[derive(Clone, Copy, PartialEq, Eq)] -pub struct DefId(pub usize); +pub struct DefId(usize); impl Debug for DefId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -52,9 +53,28 @@ impl Debug for DefId { } } +impl IndexedVal for DefId { + fn to_val(index: usize) -> Self { + DefId(index) + } + + fn to_index(&self) -> usize { + self.0 + } +} + /// A unique identification number for each provenance #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct AllocId(pub usize); +pub struct AllocId(usize); + +impl IndexedVal for AllocId { + fn to_val(index: usize) -> Self { + AllocId(index) + } + fn to_index(&self) -> usize { + self.0 + } +} /// A list of crate items. pub type CrateItems = Vec; diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 6029e3c11ad..691af15da8c 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -75,7 +75,7 @@ pub struct Placeholder { } #[derive(Clone, Copy, PartialEq, Eq)] -pub struct Span(pub usize); +pub struct Span(usize); impl Debug for Span { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -86,6 +86,15 @@ impl Debug for Span { } } +impl IndexedVal for Span { + fn to_val(index: usize) -> Self { + Span(index) + } + fn to_index(&self) -> usize { + self.0 + } +} + #[derive(Clone, Debug)] pub enum TyKind { RigidTy(RigidTy), @@ -565,3 +574,9 @@ pub enum ImplPolarity { Negative, Reservation, } + +pub trait IndexedVal { + fn to_val(index: usize) -> Self; + + fn to_index(&self) -> usize; +}