Skip to content

Commit b99953a

Browse files
authored
perf: Remove duplicate fix_rel_import_path_with_file (#1714)
* perf: Parser performance optimization: Remove duplicate fix_rel_import_path_with_file Signed-off-by: he1pa <[email protected]> * fix module has been parsed but not belong to same pkg Signed-off-by: he1pa <[email protected]> --------- Signed-off-by: he1pa <[email protected]>
1 parent 99ace3a commit b99953a

File tree

1 file changed

+53
-20
lines changed

1 file changed

+53
-20
lines changed

kclvm/parser/src/lib.rs

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ pub type KCLModuleCache = Arc<RwLock<ModuleCache>>;
317317
#[derive(Default, Debug)]
318318
pub struct ModuleCache {
319319
pub ast_cache: IndexMap<PathBuf, Arc<ast::Module>>,
320+
pub file_pkg: IndexMap<PathBuf, HashSet<PkgFile>>,
320321
pub dep_cache: IndexMap<PkgFile, (Vec<PkgFile>, PkgMap)>,
321322
}
322323
struct Loader {
@@ -367,7 +368,7 @@ fn fix_rel_import_path_with_file(
367368
m: &mut ast::Module,
368369
file: &PkgFile,
369370
pkgmap: &PkgMap,
370-
opts: LoadProgramOptions,
371+
opts: &LoadProgramOptions,
371372
sess: ParseSessionRef,
372373
) {
373374
for stmt in &mut m.body {
@@ -380,15 +381,15 @@ fn fix_rel_import_path_with_file(
380381
);
381382
import_spec.path.node = fix_path.clone();
382383

383-
let pkg = pkgmap.get(&file).expect("file not in pkgmap").clone();
384+
let pkg = pkgmap.get(&file).expect("file not in pkgmap");
384385
import_spec.pkg_name = pkg.pkg_name.clone();
385386
// Load the import package source code and compile.
386387
let pkg_info = find_packages(
387388
pos.into(),
388389
&pkg.pkg_name,
389390
&pkg.pkg_root,
390391
&fix_path,
391-
opts.clone(),
392+
opts,
392393
sess.clone(),
393394
)
394395
.unwrap_or(None);
@@ -415,7 +416,7 @@ fn find_packages(
415416
pkg_name: &str,
416417
pkg_root: &str,
417418
pkg_path: &str,
418-
opts: LoadProgramOptions,
419+
opts: &LoadProgramOptions,
419420
sess: ParseSessionRef,
420421
) -> Result<Option<PkgInfo>> {
421422
if pkg_path.is_empty() {
@@ -558,7 +559,7 @@ fn get_pkg_kfile_list(pkgroot: &str, pkgpath: &str) -> Result<Vec<String>> {
558559
}
559560

560561
if pkgroot.is_empty() {
561-
return Err(anyhow::anyhow!("pkgroot not found"));
562+
return Err(anyhow::anyhow!(format!("pkgroot not found: {:?}", pkgpath)));
562563
}
563564

564565
let mut pathbuf = std::path::PathBuf::new();
@@ -623,7 +624,7 @@ fn get_dir_files(dir: &str) -> Result<Vec<String>> {
623624
///
624625
/// - [`is_external_pkg`] will return an error if the package's source files cannot be found.
625626
/// - The name of the external package could not be resolved from [`pkg_path`].
626-
fn is_external_pkg(pkg_path: &str, opts: LoadProgramOptions) -> Result<Option<PkgInfo>> {
627+
fn is_external_pkg(pkg_path: &str, opts: &LoadProgramOptions) -> Result<Option<PkgInfo>> {
627628
let pkg_name = parse_external_pkg_name(pkg_path)?;
628629
let external_pkg_root = if let Some(root) = opts.package_maps.get(&pkg_name) {
629630
PathBuf::from(root).join(KCL_MOD_FILE)
@@ -682,6 +683,16 @@ pub fn parse_file(
682683
module_cache
683684
.ast_cache
684685
.insert(file.canonicalize(), m.clone());
686+
match module_cache.file_pkg.get_mut(&file.canonicalize()) {
687+
Some(s) => {
688+
s.insert(file.clone());
689+
}
690+
None => {
691+
let mut s = HashSet::new();
692+
s.insert(file.clone());
693+
module_cache.file_pkg.insert(file.canonicalize(), s);
694+
}
695+
}
685696
module_cache
686697
.dep_cache
687698
.insert(file.clone(), (deps.clone(), new_pkgmap));
@@ -722,7 +733,7 @@ pub fn get_deps(
722733
&pkg.pkg_name,
723734
&pkg.pkg_root,
724735
&fix_path,
725-
opts.clone(),
736+
opts,
726737
sess.clone(),
727738
)?;
728739
if let Some(pkg_info) = &pkg_info {
@@ -791,16 +802,18 @@ pub fn parse_entry(
791802
pkgmap: &mut PkgMap,
792803
file_graph: FileGraphCache,
793804
opts: &LoadProgramOptions,
794-
) -> Result<()> {
805+
) -> Result<HashSet<PkgFile>> {
795806
let k_files = entry.get_k_files();
796807
let maybe_k_codes = entry.get_k_codes();
797808
let mut files = vec![];
809+
let mut new_files = HashSet::new();
798810
for (i, f) in k_files.iter().enumerate() {
799811
let file = PkgFile {
800812
path: f.adjust_canonicalization().into(),
801813
pkg_path: MAIN_PKG.to_string(),
802814
};
803815
files.push((file.clone(), maybe_k_codes.get(i).unwrap_or(&None).clone()));
816+
new_files.insert(file.clone());
804817
pkgmap.insert(
805818
file,
806819
Pkg {
@@ -822,6 +835,24 @@ pub fn parse_entry(
822835
let mut parsed_file: HashSet<PkgFile> = HashSet::new();
823836
while let Some(file) = unparsed_file.pop_front() {
824837
if parsed_file.insert(file.clone()) {
838+
match &mut module_cache.write() {
839+
Ok(m_cache) => match m_cache.file_pkg.get_mut(&file.canonicalize()) {
840+
Some(s) => {
841+
// The module ast has been parsed, but does not belong to the same package
842+
if s.insert(file.clone()) {
843+
new_files.insert(file.clone());
844+
}
845+
}
846+
None => {
847+
let mut s = HashSet::new();
848+
s.insert(file.clone());
849+
m_cache.file_pkg.insert(file.canonicalize(), s);
850+
new_files.insert(file.clone());
851+
}
852+
},
853+
Err(e) => return Err(anyhow::anyhow!("Parse file failed: {e}")),
854+
}
855+
825856
let module_cache_read = module_cache.read();
826857
match &module_cache_read {
827858
Ok(m_cache) => match m_cache.ast_cache.get(&file.canonicalize()) {
@@ -849,6 +880,7 @@ pub fn parse_entry(
849880
}
850881
}
851882
None => {
883+
new_files.insert(file.clone());
852884
drop(module_cache_read);
853885
let deps = parse_file(
854886
sess.clone(),
@@ -871,7 +903,7 @@ pub fn parse_entry(
871903
};
872904
}
873905
}
874-
Ok(())
906+
Ok(new_files)
875907
}
876908

877909
pub fn parse_program(
@@ -885,16 +917,17 @@ pub fn parse_program(
885917
let workdir = compile_entries.get_root_path().to_string();
886918
let mut pkgs: HashMap<String, Vec<Module>> = HashMap::new();
887919
let mut pkgmap = PkgMap::new();
920+
let mut new_files = HashSet::new();
888921
for entry in compile_entries.iter() {
889-
parse_entry(
922+
new_files.extend(parse_entry(
890923
sess.clone(),
891924
entry,
892925
module_cache.clone(),
893926
&mut pkgs,
894927
&mut pkgmap,
895928
file_graph.clone(),
896929
&opts,
897-
)?;
930+
)?);
898931
}
899932

900933
let files = match file_graph.read() {
@@ -943,15 +976,15 @@ pub fn parse_program(
943976
.clone(),
944977
Err(e) => return Err(anyhow::anyhow!("Parse program failed: {e}")),
945978
};
946-
let pkg = pkgmap.get(file).expect("file not in pkgmap");
947-
fix_rel_import_path_with_file(
948-
&pkg.pkg_root,
949-
&mut m,
950-
file,
951-
&pkgmap,
952-
opts.clone(),
953-
sess.clone(),
954-
);
979+
if new_files.contains(file) {
980+
let pkg = pkgmap.get(file).expect("file not in pkgmap");
981+
fix_rel_import_path_with_file(&pkg.pkg_root, &mut m, file, &pkgmap, opts, sess.clone());
982+
let m = Arc::new(m.clone());
983+
match &mut module_cache.write() {
984+
Ok(module_cache) => module_cache.ast_cache.insert(file.canonicalize(), m),
985+
Err(e) => return Err(anyhow::anyhow!("Parse program failed: {e}")),
986+
};
987+
}
955988

956989
match pkgs.get_mut(&file.pkg_path) {
957990
Some(modules) => {

0 commit comments

Comments
 (0)