Skip to content

Commit e656829

Browse files
committed
Do not pre-calculate reference-symbol map
The are too many references to do this in advance, rather produce this as-needed Signed-of-by: Jonatan Waern <jonatan.waern@intel.com>
1 parent 1ba62e8 commit e656829

File tree

4 files changed

+38
-33
lines changed

4 files changed

+38
-33
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
- Disabled the invariant check for the parameter 'size' to be set on register
1515
objects. Will be re-enabled when constant-folding is added to the DLS.
1616
- Fixed issue where statements under top-level in-eachs were not correctly tracked.
17+
- Moved storage of reference->symbol mapping to on-demand timing, should significantly speed
18+
up device analysises
1719

1820
## 0.9.12
1921
- Added 'simics\_util\_vect' as a known provisional (with no DLS semantics)

src/actions/requests.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use serde::{Deserialize, Serialize};
88
use serde_json::Value;
99
use std::collections::HashSet;
1010
use std::path::Path;
11-
use std::sync::Arc;
1211

1312
use crate::actions::hover;
1413
use crate::actions::{AnalysisProgressKind, AnalysisWaitKind,
@@ -192,7 +191,6 @@ fn fp_to_symbol_refs<O: Output>
192191
for device in analysis.filtered_device_analysises_containing_file(
193192
&canon_path,
194193
filter.as_ref()) {
195-
debug!("reference info is {:?}", device.reference_info.keys());
196194
// NOTE: This ends up being the correct place to warn users
197195
// about references inside uninstantiated templates,
198196
// but we have to perform some extra work to find out we are
@@ -206,12 +204,9 @@ fn fp_to_symbol_refs<O: Output>
206204
any_template_used = true;
207205
}
208206
}
209-
if let Some(defs) = device.reference_info.get(
210-
refr.loc_span()) {
211-
for def in defs {
212-
definitions.push(Arc::clone(def));
213-
}
214-
}
207+
208+
definitions.append(
209+
&mut device.symbols_of_ref(*refr.loc_span()));
215210
}
216211
if let Some(ContextKey::Template(_)) = first_context {
217212
if !any_template_used {

src/analysis/mod.rs

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,9 @@ impl SymbolStorage {
386386
}
387387
}
388388

389-
// This maps non-auth symbol decls to auth decl
390-
// and references to the symbol decl they ref
391-
type ReferenceStorage = HashMap<ZeroSpan, Vec<SymbolRef>>;
389+
// This maps references to the symbol they reference, made as a lock
390+
// because we need to incrementally fill it as requests are made
391+
type ReferenceStorage = Arc<Mutex<HashMap<ZeroSpan, Vec<SymbolRef>>>>;
392392

393393
// Analysis from the perspective of a particular DML device
394394
#[derive(Debug, Clone)]
@@ -1366,7 +1366,7 @@ impl DeviceAnalysis {
13661366
ReferenceMatch::Found(symbols) =>
13671367
for symbol in &symbols {
13681368
let mut sym = symbol.lock().unwrap();
1369-
sym.references.push(*reference.loc_span());
1369+
sym.references.insert(*reference.loc_span());
13701370
if let Some(meth) = sym.source
13711371
.as_object()
13721372
.and_then(DMLObject::as_shallow)
@@ -1632,7 +1632,7 @@ fn template_to_symbol(template: &Arc<DMLTemplate>) -> Option<SymbolRef> {
16321632
Arc::new(Mutex::new(Symbol {
16331633
loc: *location,
16341634
kind: DMLSymbolKind::Template,
1635-
references: vec![],
1635+
references: HashSet::default(),
16361636
definitions: vec![*location],
16371637
declarations: vec![*location],
16381638
implementations: vec![],
@@ -1669,7 +1669,7 @@ fn new_symbol_from_object(object: &DMLCompositeObject) -> SymbolRef {
16691669
definitions: all_decl_defs.clone(),
16701670
declarations: all_decl_defs.clone(),
16711671
bases: all_decl_defs,
1672-
references: vec![],
1672+
references: HashSet::default(),
16731673
implementations: vec![],
16741674
source: SymbolSource::DMLObject(
16751675
DMLObject::CompObject(object.key)),
@@ -1689,7 +1689,7 @@ fn new_symbol_from_arg(methref: &Arc<DMLMethodRef>,
16891689
bases,
16901690
definitions,
16911691
declarations,
1692-
references: vec![],
1692+
references: HashSet::default(),
16931693
implementations: vec![],
16941694
source: SymbolSource::MethodArg(Arc::clone(methref),
16951695
arg.name().clone()),
@@ -1762,7 +1762,7 @@ fn add_new_symbol_from_shallow(shallow: &DMLShallowObject,
17621762
definitions,
17631763
declarations,
17641764
implementations: vec![],
1765-
references: vec![],
1765+
references: HashSet::default(),
17661766
bases,
17671767
source: SymbolSource::DMLObject(
17681768
// TODO: Inefficient clone. Not terribly so, but worth
@@ -1844,7 +1844,7 @@ where
18441844
definitions: vec![*sym.loc_span()],
18451845
declarations: vec![*sym.loc_span()],
18461846
implementations: vec![],
1847-
references: vec![],
1847+
references: HashSet::default(),
18481848
bases: vec![],
18491849
source: SymbolSource::MethodLocal(
18501850
Arc::clone(method),
@@ -2072,18 +2072,6 @@ impl DeviceAnalysis {
20722072
}
20732073
}
20742074

2075-
fn inverse_references(&mut self) {
2076-
info!("Inverse map");
2077-
// Set up the inverse map of references->symbols
2078-
for symbol in self.symbol_info.all_symbols() {
2079-
debug!("Inverse of {:?}", symbol);
2080-
for ref_loc in &symbol.lock().unwrap().references {
2081-
self.reference_info.entry(*ref_loc)
2082-
.or_default().push(Arc::clone(symbol));
2083-
}
2084-
}
2085-
}
2086-
20872075
fn template_object_map(tt_info: &TemplateTraitInfo,
20882076
container: &StructureContainer)
20892077
-> HashMap<ZeroSpan, Vec<StructureKey>>{
@@ -2232,7 +2220,7 @@ impl DeviceAnalysis {
22322220
device_obj: DMLObject::CompObject(device_key),
22332221
templates: tt_info,
22342222
symbol_info,
2235-
reference_info: ReferenceStorage::new(),
2223+
reference_info: ReferenceStorage::default(),
22362224
template_object_implementation_map,
22372225
path: root.path.clone(),
22382226
clientpath: root.path.clone().into(),
@@ -2241,7 +2229,9 @@ impl DeviceAnalysis {
22412229

22422230
device.match_references(&bases, &method_structure, &mut errors);
22432231

2244-
device.inverse_references();
2232+
// NOTE: This is when we previously pre-calculated the ref->symbol map, however
2233+
// the up-front analysis cost of this was too heavy
2234+
// device.inverse_references();
22452235

22462236
info!("Invariant check");
22472237
for obj in device.objects.values() {
@@ -2290,6 +2280,24 @@ impl DeviceAnalysis {
22902280
_ => (),
22912281
}
22922282
}
2283+
2284+
pub fn symbols_of_ref(&self, loc: ZeroSpan) -> Vec<SymbolRef> {
2285+
// Would like to use .entry here, but it does not play nice with the
2286+
// mutable borrow of .reference_info and .symbol_info
2287+
let mut locked_info = self.reference_info.lock().unwrap();
2288+
if let Some(syms) = locked_info.get(&loc) {
2289+
syms.clone()
2290+
} else {
2291+
let mut syms = vec![];
2292+
for sym in self.symbol_info.all_symbols() {
2293+
if sym.lock().unwrap().references.contains(&loc) {
2294+
syms.push(Arc::clone(sym));
2295+
}
2296+
}
2297+
locked_info.insert(loc, syms);
2298+
locked_info.get(&loc).unwrap().clone()
2299+
}
2300+
}
22932301
}
22942302

22952303
pub fn from_device_and_bases<'a>(_device: &'a IsolatedAnalysis,

src/analysis/symbols.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0 and MIT
33
use std::sync::Arc;
44

5-
use std::collections::HashMap;
5+
use std::collections::{HashMap, HashSet};
66

77
use crate::analysis::{Named, LocationSpan};
88

@@ -160,7 +160,7 @@ pub struct Symbol {
160160
pub kind: DMLSymbolKind,
161161
pub definitions: Vec<ZeroSpan>,
162162
pub declarations: Vec<ZeroSpan>,
163-
pub references: Vec<ZeroSpan>,
163+
pub references: HashSet<ZeroSpan>,
164164
// NOTE: The meaning of 'implementation' varies with symbol kind
165165
// For methods and interfaces, this is straightforward
166166
// For templates, it will give all declarations for all objects that

0 commit comments

Comments
 (0)