From 38c82f3945a7ac2e9381d355f7776bb9e6258409 Mon Sep 17 00:00:00 2001 From: Volkan Sagcan Date: Mon, 13 May 2024 09:52:57 +0200 Subject: [PATCH 1/2] perf: Use FxHash --- Cargo.lock | 9 +++- Cargo.toml | 3 +- compiler/plc_driver/src/pipelines.rs | 7 +-- compiler/plc_xml/src/model/fbd.rs | 53 ++++++++----------- compiler/plc_xml/src/xml_parser/fbd.rs | 7 +-- src/builtins.rs | 7 ++- src/codegen.rs | 4 +- src/codegen/debug.rs | 9 ++-- src/codegen/generators/data_type_generator.rs | 6 +-- .../generators/expression_generator.rs | 5 +- src/codegen/generators/pou_generator.rs | 15 +++--- src/codegen/generators/statement_generator.rs | 5 +- src/codegen/generators/variable_generator.rs | 5 +- src/codegen/llvm_index.rs | 38 ++++++------- src/index.rs | 28 +++++++--- src/index/symbol.rs | 7 +-- src/resolver.rs | 52 +++++++++--------- src/resolver/generics.rs | 27 +++++----- src/validation/global.rs | 8 ++- src/validation/recursive.rs | 22 ++++---- src/validation/statement.rs | 11 ++-- 21 files changed, 171 insertions(+), 157 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a9e101de4..05a04a6343 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1459,7 +1459,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2 0.5.6", "tokio", "tower-service", "tracing", @@ -2896,6 +2896,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.37.27" @@ -2962,6 +2968,7 @@ dependencies = [ "plc_xml", "pretty_assertions", "regex", + "rustc-hash", "section_mangler", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 7ab184da55..061525eb82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ shell-words = "1.1.0" plc_derive = { path = "./compiler/plc_derive" } lld_rs = "140.0.0" which = "4.2.5" +rustc-hash = "1.1.0" log.workspace = true inkwell.workspace = true chrono.workspace = true @@ -48,7 +49,7 @@ num = "0.4" insta = "1.31.0" pretty_assertions = "1.3.0" driver = { path = "./compiler/plc_driver/", package = "plc_driver" } -project = { path = "./compiler/plc_project/", package = "plc_project", features = ["integration"]} +project = { path = "./compiler/plc_project/", package = "plc_project", features = ["integration"] } plc_xml = { path = "./compiler/plc_xml" } serial_test = "*" tempfile = "3" diff --git a/compiler/plc_driver/src/pipelines.rs b/compiler/plc_driver/src/pipelines.rs index 63d0cb81ef..67d8991311 100644 --- a/compiler/plc_driver/src/pipelines.rs +++ b/compiler/plc_driver/src/pipelines.rs @@ -10,7 +10,8 @@ use ast::{ ast::{pre_process, CompilationUnit, LinkageType}, provider::IdProvider, }; -use indexmap::IndexSet; + +use plc::index::FxIndexSet; use plc::{ codegen::{CodegenContext, GeneratedModule}, index::Index, @@ -192,7 +193,7 @@ impl IndexedProject { /// A project that has been annotated with information about different types and used units pub struct AnnotatedProject { pub project: Project, - pub units: Vec<(CompilationUnit, IndexSet, StringLiterals)>, + pub units: Vec<(CompilationUnit, FxIndexSet, StringLiterals)>, pub index: Index, pub annotations: AstAnnotations, } @@ -266,7 +267,7 @@ impl AnnotatedProject { context: &'ctx CodegenContext, compile_options: &CompileOptions, unit: &CompilationUnit, - dependencies: &IndexSet, + dependencies: &FxIndexSet, literals: &StringLiterals, ) -> Result, Diagnostic> { let mut code_generator = plc::codegen::CodeGen::new( diff --git a/compiler/plc_xml/src/model/fbd.rs b/compiler/plc_xml/src/model/fbd.rs index 2d0ab3426c..0b60a952c9 100644 --- a/compiler/plc_xml/src/model/fbd.rs +++ b/compiler/plc_xml/src/model/fbd.rs @@ -1,4 +1,5 @@ -use indexmap::{IndexMap, IndexSet}; +use indexmap::IndexSet; +use plc::index::FxIndexMap; use plc_diagnostics::diagnostics::Diagnostic; use plc_source::source_location::SourceLocationFactory; use quick_xml::events::{BytesStart, Event}; @@ -15,7 +16,7 @@ use super::{ /// Represent either a `localId` or `refLocalId` pub(crate) type NodeId = usize; -pub(crate) type NodeIndex<'xml> = IndexMap>; +pub(crate) type NodeIndex<'xml> = FxIndexMap>; #[derive(Debug, Default)] pub(crate) struct FunctionBlockDiagram<'xml> { @@ -113,7 +114,7 @@ impl<'xml> Node<'xml> { impl<'xml> Parseable for FunctionBlockDiagram<'xml> { fn visit(reader: &mut Reader, _tag: Option) -> Result { - let mut nodes = IndexMap::new(); + let mut nodes = FxIndexMap::default(); loop { match reader.read_event().map_err(Error::ReadEvent)? { @@ -304,6 +305,7 @@ mod tests { xml_parser::Parseable, }; use insta::assert_debug_snapshot; + use plc::index::FxIndexMap; use plc_source::source_location::SourceLocationFactory; use super::Node; @@ -336,7 +338,7 @@ mod tests { let mut pou = Pou { name: "TestProg".into(), ..Default::default() }; let fbd = FunctionBlockDiagram { - nodes: [ + nodes: FxIndexMap::from_iter([ ( 1, Node::FunctionBlockVariable(FunctionBlockVariable { @@ -359,8 +361,7 @@ mod tests { ref_local_id: Some(1), }), ), - ] - .into(), + ]), }; pou.body.function_block_diagram = fbd; model.pous.push(pou); @@ -375,7 +376,7 @@ mod tests { let mut model = Project::default(); let mut pou = Pou { name: "TestProg".into(), ..Default::default() }; let fbd = FunctionBlockDiagram { - nodes: [ + nodes: FxIndexMap::from_iter([ ( 1, Node::FunctionBlockVariable(FunctionBlockVariable { @@ -418,8 +419,7 @@ mod tests { formal_parameter: None, }), ), - ] - .into(), + ]), }; pou.body.function_block_diagram = fbd; model.pous.push(pou); @@ -434,7 +434,7 @@ mod tests { let mut model = Project::default(); let mut pou = Pou { name: "TestProg".into(), ..Default::default() }; let fbd = FunctionBlockDiagram { - nodes: [ + nodes: FxIndexMap::from_iter([ ( 1, Node::FunctionBlockVariable(FunctionBlockVariable { @@ -498,8 +498,7 @@ mod tests { ref_local_id: Some(5), }), ), - ] - .into(), + ]), }; pou.body.function_block_diagram = fbd; model.pous.push(pou); @@ -514,7 +513,7 @@ mod tests { let mut model = Project::default(); let mut pou = Pou { name: "TestProg".into(), ..Default::default() }; let fbd = FunctionBlockDiagram { - nodes: [ + nodes: FxIndexMap::from_iter([ ( 1, Node::FunctionBlockVariable(FunctionBlockVariable { @@ -577,8 +576,7 @@ mod tests { formal_parameter: None, }), ), - ] - .into(), + ]), }; pou.body.function_block_diagram = fbd; model.pous.push(pou); @@ -593,7 +591,7 @@ mod tests { let mut model = Project::default(); let mut pou = Pou { name: "TestProg".into(), ..Default::default() }; let fbd = FunctionBlockDiagram { - nodes: [ + nodes: FxIndexMap::from_iter([ ( 1, Node::FunctionBlockVariable(FunctionBlockVariable { @@ -626,8 +624,7 @@ mod tests { formal_parameter: None, }), ), - ] - .into(), + ]), }; pou.body.function_block_diagram = fbd; model.pous.push(pou); @@ -642,7 +639,7 @@ mod tests { let mut model = Project::default(); let mut pou = Pou { name: "TestProg".into(), ..Default::default() }; let fbd = FunctionBlockDiagram { - nodes: [ + nodes: FxIndexMap::from_iter([ ( 1, Node::FunctionBlockVariable(FunctionBlockVariable { @@ -675,8 +672,7 @@ mod tests { formal_parameter: None, }), ), - ] - .into(), + ]), }; pou.body.function_block_diagram = fbd; model.pous.push(pou); @@ -693,7 +689,7 @@ mod tests { let mut model = Project::default(); let mut pou = Pou { name: "TestProg".into(), ..Default::default() }; let fbd = FunctionBlockDiagram { - nodes: [ + nodes: FxIndexMap::from_iter([ ( 1, Node::FunctionBlockVariable(FunctionBlockVariable { @@ -756,8 +752,7 @@ mod tests { formal_parameter: None, }), ), - ] - .into(), + ]), }; pou.body.function_block_diagram = fbd; model.pous.push(pou); @@ -773,7 +768,7 @@ mod tests { let mut model = Project::default(); let mut pou = Pou { name: "TestProg".into(), ..Default::default() }; let fbd = FunctionBlockDiagram { - nodes: [ + nodes: FxIndexMap::from_iter([ ( 1, Node::FunctionBlockVariable(FunctionBlockVariable { @@ -816,8 +811,7 @@ mod tests { formal_parameter: None, }), ), - ] - .into(), + ]), }; pou.body.function_block_diagram = fbd; model.pous.push(pou); @@ -834,7 +828,7 @@ mod tests { let mut model = Project::default(); let mut pou = Pou { name: "TestProg".into(), ..Default::default() }; let fbd = FunctionBlockDiagram { - nodes: [ + nodes: FxIndexMap::from_iter([ ( 1, Node::FunctionBlockVariable(FunctionBlockVariable { @@ -919,8 +913,7 @@ mod tests { formal_parameter: None, }), ), - ] - .into(), + ]), }; pou.body.function_block_diagram = fbd; model.pous.push(pou); diff --git a/compiler/plc_xml/src/xml_parser/fbd.rs b/compiler/plc_xml/src/xml_parser/fbd.rs index 3169909df8..a87cdb420a 100644 --- a/compiler/plc_xml/src/xml_parser/fbd.rs +++ b/compiler/plc_xml/src/xml_parser/fbd.rs @@ -1,5 +1,6 @@ use ast::ast::{AstFactory, AstNode, AstStatement}; -use indexmap::IndexMap; + +use plc::index::FxIndexMap; use plc_source::source_location::SourceLocation; use crate::model::fbd::{FunctionBlockDiagram, Node, NodeId}; @@ -10,7 +11,7 @@ impl<'xml> FunctionBlockDiagram<'xml> { /// Transforms the body of a function block diagram to their AST-equivalent, in order of execution. /// Only statements that are necessary for execution logic will be selected. pub(crate) fn transform(&self, session: &mut ParseSession) -> Vec { - let mut ast_association = IndexMap::new(); + let mut ast_association = FxIndexMap::default(); // transform each node to an ast-statement. since we might see and transform a node multiple times, we use an // ast-association map to keep track of the latest statement for each id @@ -36,7 +37,7 @@ impl<'xml> FunctionBlockDiagram<'xml> { &self, id: NodeId, session: &mut ParseSession, - ast_association: &IndexMap, + ast_association: &FxIndexMap, ) -> (AstNode, Option) { let Some(current_node) = self.nodes.get(&id) else { unreachable!() }; diff --git a/src/builtins.rs b/src/builtins.rs index d344cdd664..b7b78e6e86 100644 --- a/src/builtins.rs +++ b/src/builtins.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use inkwell::{ basic_block::BasicBlock, types::BasicType, @@ -17,6 +15,7 @@ use plc_ast::{ use plc_diagnostics::diagnostics::Diagnostic; use plc_source::source_location::{SourceLocation, SourceLocationFactory}; +use crate::index::FxHashMap; use crate::{ codegen::generators::expression_generator::{self, ExpressionCodeGenerator, ExpressionValue}, index::Index, @@ -32,7 +31,7 @@ use crate::{ // Defines a set of functions that are always included in a compiled application lazy_static! { - static ref BUILTIN: HashMap<&'static str, BuiltIn> = HashMap::from([ + static ref BUILTIN: FxHashMap<&'static str, BuiltIn> = FxHashMap::from_iter([ ( "ADR", BuiltIn { @@ -893,7 +892,7 @@ fn generate_variable_length_array_bound_function<'ink>( } type AnnotationFunction = fn(&mut TypeAnnotator, &AstNode, &AstNode, Option<&AstNode>, VisitorContext); -type GenericNameResolver = fn(&str, &[GenericBinding], &HashMap) -> String; +type GenericNameResolver = fn(&str, &[GenericBinding], &FxHashMap) -> String; type CodegenFunction = for<'ink, 'b> fn( &'b ExpressionCodeGenerator<'ink, 'b>, &[&AstNode], diff --git a/src/codegen.rs b/src/codegen.rs index f6f012fa50..b141c368ef 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -23,7 +23,7 @@ use crate::{ }; use super::index::*; -use indexmap::IndexSet; + use inkwell::{ context::Context, execution_engine::{ExecutionEngine, JitFunction}, @@ -102,7 +102,7 @@ impl<'ink> CodeGen<'ink> { context: &'ink CodegenContext, annotations: &AstAnnotations, literals: &StringLiterals, - dependencies: &IndexSet, + dependencies: &FxIndexSet, global_index: &Index, ) -> Result, Diagnostic> { let llvm = Llvm::new(context, context.create_builder()); diff --git a/src/codegen/debug.rs b/src/codegen/debug.rs index 29a88dbae4..157732f370 100644 --- a/src/codegen/debug.rs +++ b/src/codegen/debug.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, ops::Range, path::Path}; +use std::{ops::Range, path::Path}; use inkwell::{ basic_block::BasicBlock, @@ -16,6 +16,7 @@ use plc_ast::ast::LinkageType; use plc_diagnostics::diagnostics::Diagnostic; use plc_source::source_location::SourceLocation; +use crate::index::FxHashMap; use crate::{ datalayout::{Bytes, DataLayout, MemoryLocation}, index::{ImplementationType, Index, PouIndexEntry, VariableIndexEntry}, @@ -147,10 +148,10 @@ pub struct DebugBuilder<'ink> { context: &'ink Context, debug_info: DebugInfoBuilder<'ink>, compile_unit: DICompileUnit<'ink>, - types: HashMap>, - variables: HashMap>, + types: FxHashMap>, + variables: FxHashMap>, optimization: OptimizationLevel, - files: HashMap<&'static str, DIFile<'ink>>, + files: FxHashMap<&'static str, DIFile<'ink>>, } /// A wrapper that redirects to correct debug builder implementation based on the debug context. diff --git a/src/codegen/generators/data_type_generator.rs b/src/codegen/generators/data_type_generator.rs index c0e7ee42d2..d3516c6f56 100644 --- a/src/codegen/generators/data_type_generator.rs +++ b/src/codegen/generators/data_type_generator.rs @@ -1,6 +1,6 @@ // Copyright (c) 2020 Ghaith Hachem and Mathias Rieder use crate::codegen::debug::Debug; -use crate::index::{Index, VariableIndexEntry, VariableType}; +use crate::index::{FxIndexSet, Index, VariableIndexEntry, VariableType}; use crate::resolver::{AstAnnotations, Dependency}; use crate::typesystem::{self, DataTypeInformation, Dimension, StringEncoding, StructSource}; use crate::{ @@ -11,7 +11,7 @@ use crate::{ }, typesystem::DataType, }; -use indexmap::IndexSet; + use inkwell::{ types::{BasicType, BasicTypeEnum}, values::{BasicValue, BasicValueEnum}, @@ -50,7 +50,7 @@ pub struct DataTypeGenerator<'ink, 'b> { pub fn generate_data_types<'ink>( llvm: &Llvm<'ink>, debug: &mut DebugBuilderEnum<'ink>, - dependencies: &IndexSet, + dependencies: &FxIndexSet, index: &Index, annotations: &AstAnnotations, ) -> Result, Diagnostic> { diff --git a/src/codegen/generators/expression_generator.rs b/src/codegen/generators/expression_generator.rs index 68c43b92fa..8914d8f9af 100644 --- a/src/codegen/generators/expression_generator.rs +++ b/src/codegen/generators/expression_generator.rs @@ -1,4 +1,5 @@ // Copyright (c) 2020 Ghaith Hachem and Mathias Rieder +use crate::index::FxHashSet; use crate::{ codegen::{ debug::{Debug, DebugBuilderEnum}, @@ -34,7 +35,7 @@ use plc_ast::{ use plc_diagnostics::diagnostics::{Diagnostic, INTERNAL_LLVM_ERROR}; use plc_source::source_location::SourceLocation; use plc_util::convention::qualified_name; -use std::{collections::HashSet, vec}; +use std::vec; use super::{llvm::Llvm, statement_generator::FunctionContext, ADDRESS_SPACE_CONST, ADDRESS_SPACE_GENERIC}; /// the generator for expressions @@ -1870,7 +1871,7 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> { if let DataTypeInformation::Struct { name: struct_name, members, .. } = self.get_type_hint_info_for(assignments)? { - let mut uninitialized_members: HashSet<&VariableIndexEntry> = HashSet::from_iter(members); + let mut uninitialized_members: FxHashSet<&VariableIndexEntry> = FxHashSet::from_iter(members); let mut member_values: Vec<(u32, BasicValueEnum<'ink>)> = Vec::new(); for assignment in flatten_expression_list(assignments) { if let AstStatement::Assignment(data) = assignment.get_stmt() { diff --git a/src/codegen/generators/pou_generator.rs b/src/codegen/generators/pou_generator.rs index 9172f06037..ace0d2d081 100644 --- a/src/codegen/generators/pou_generator.rs +++ b/src/codegen/generators/pou_generator.rs @@ -17,18 +17,19 @@ use crate::{ resolver::{AstAnnotations, Dependency}, typesystem::{DataType, DataTypeInformation, VarArgs, DINT_TYPE}, }; -use std::collections::HashMap; /// The pou_generator contains functions to generate the code for POUs (PROGRAM, FUNCTION, FUNCTION_BLOCK) /// # responsibilities /// - generates a struct-datatype for the POU's members /// - generates a function for the pou /// - declares a global instance if the POU is a PROGRAM -use crate::index::{ArgumentType, ImplementationIndexEntry, VariableIndexEntry}; +use crate::index::{ + ArgumentType, FxHashMap, FxIndexMap, FxIndexSet, ImplementationIndexEntry, VariableIndexEntry, +}; use crate::index::Index; use index::VariableType; -use indexmap::{IndexMap, IndexSet}; + use inkwell::{ module::Module, types::{BasicMetadataTypeEnum, BasicTypeEnum, FunctionType}, @@ -56,7 +57,7 @@ pub struct PouGenerator<'ink, 'cg> { pub fn generate_implementation_stubs<'ink>( module: &Module<'ink>, llvm: Llvm<'ink>, - dependencies: &IndexSet, + dependencies: &FxIndexSet, index: &Index, annotations: &AstAnnotations, types_index: &LlvmTypedIndex<'ink>, @@ -73,7 +74,7 @@ pub fn generate_implementation_stubs<'ink>( None } }) - .collect::>(); + .collect::>(); for (name, implementation) in implementations { if !implementation.is_generic() { let curr_f = @@ -92,7 +93,7 @@ pub fn generate_implementation_stubs<'ink>( pub fn generate_global_constants_for_pou_members<'ink>( module: &Module<'ink>, llvm: &Llvm<'ink>, - dependencies: &IndexSet, + dependencies: &FxIndexSet, index: &Index, annotations: &AstAnnotations, llvm_index: &LlvmTypedIndex<'ink>, @@ -372,7 +373,7 @@ impl<'ink, 'cg> PouGenerator<'ink, 'cg> { let block = context.append_basic_block(current_function, "entry"); //Create all labels this function will have - let mut blocks = HashMap::new(); + let mut blocks = FxHashMap::default(); if let Some(labels) = self.index.get_labels(&implementation.name) { for name in labels.keys() { blocks.insert(name.to_string(), self.llvm.context.append_basic_block(current_function, name)); diff --git a/src/codegen/generators/statement_generator.rs b/src/codegen/generators/statement_generator.rs index 513bc167cf..1a57a6d1e9 100644 --- a/src/codegen/generators/statement_generator.rs +++ b/src/codegen/generators/statement_generator.rs @@ -1,10 +1,9 @@ -use std::collections::HashMap; - // Copyright (c) 2020 Ghaith Hachem and Mathias Rieder use super::{ expression_generator::{to_i1, ExpressionCodeGenerator}, llvm::Llvm, }; +use crate::index::FxHashMap; use crate::{ codegen::{debug::Debug, llvm_typesystem::cast_if_needed}, codegen::{debug::DebugBuilderEnum, LlvmTypedIndex}, @@ -35,7 +34,7 @@ pub struct FunctionContext<'ink, 'b> { /// the llvm function to generate statements into pub function: FunctionValue<'ink>, /// The blocks/labels this function can use - pub blocks: HashMap>, + pub blocks: FxHashMap>, } /// the StatementCodeGenerator is used to generate statements (For, If, etc.) or expressions (references, literals, etc.) diff --git a/src/codegen/generators/variable_generator.rs b/src/codegen/generators/variable_generator.rs index ffe8e23c51..55a8194b05 100644 --- a/src/codegen/generators/variable_generator.rs +++ b/src/codegen/generators/variable_generator.rs @@ -6,7 +6,7 @@ use crate::{ index::{get_initializer_name, Index, PouIndexEntry, VariableIndexEntry}, resolver::{AnnotationMap, AstAnnotations, Dependency}, }; -use indexmap::IndexSet; + use inkwell::{module::Module, values::GlobalValue}; use plc_ast::ast::LinkageType; use plc_diagnostics::diagnostics::Diagnostic; @@ -17,6 +17,7 @@ use super::{ llvm::{GlobalValueExt, Llvm}, }; use crate::codegen::debug::DebugBuilderEnum; +use crate::index::FxIndexSet; pub struct VariableGenerator<'ctx, 'b> { module: &'b Module<'ctx>, @@ -41,7 +42,7 @@ impl<'ctx, 'b> VariableGenerator<'ctx, 'b> { pub fn generate_global_variables( &mut self, - dependencies: &IndexSet, + dependencies: &FxIndexSet, location: &'b str, ) -> Result, Diagnostic> { let mut index = LlvmTypedIndex::default(); diff --git a/src/codegen/llvm_index.rs b/src/codegen/llvm_index.rs index 89137f3c47..d0d9a9fd5b 100644 --- a/src/codegen/llvm_index.rs +++ b/src/codegen/llvm_index.rs @@ -1,40 +1,40 @@ // Copyright (c) 2020 Ghaith Hachem and Mathias Rieder +use crate::index::FxHashMap; use inkwell::types::BasicTypeEnum; use inkwell::values::{BasicValueEnum, FunctionValue, GlobalValue, PointerValue}; use plc_diagnostics::diagnostics::Diagnostic; use plc_source::source_location::SourceLocation; use plc_util::convention::qualified_name; -use std::collections::HashMap; /// Index view containing declared values for the current context /// Parent Index is the a fallback lookup index for values not declared locally #[derive(Debug, Clone, Default)] pub struct LlvmTypedIndex<'ink> { parent_index: Option<&'ink LlvmTypedIndex<'ink>>, - type_associations: HashMap>, - pou_type_associations: HashMap>, - global_values: HashMap>, - initial_value_associations: HashMap>, - loaded_variable_associations: HashMap>, - implementations: HashMap>, - constants: HashMap>, - utf08_literals: HashMap>, - utf16_literals: HashMap>, + type_associations: FxHashMap>, + pou_type_associations: FxHashMap>, + global_values: FxHashMap>, + initial_value_associations: FxHashMap>, + loaded_variable_associations: FxHashMap>, + implementations: FxHashMap>, + constants: FxHashMap>, + utf08_literals: FxHashMap>, + utf16_literals: FxHashMap>, } impl<'ink> LlvmTypedIndex<'ink> { pub fn create_child(parent: &'ink LlvmTypedIndex<'ink>) -> LlvmTypedIndex<'ink> { LlvmTypedIndex { parent_index: Some(parent), - type_associations: HashMap::new(), - pou_type_associations: HashMap::new(), - global_values: HashMap::new(), - initial_value_associations: HashMap::new(), - loaded_variable_associations: HashMap::new(), - implementations: HashMap::new(), - constants: HashMap::new(), - utf08_literals: HashMap::new(), - utf16_literals: HashMap::new(), + type_associations: FxHashMap::default(), + pou_type_associations: FxHashMap::default(), + global_values: FxHashMap::default(), + initial_value_associations: FxHashMap::default(), + loaded_variable_associations: FxHashMap::default(), + implementations: FxHashMap::default(), + constants: FxHashMap::default(), + utf08_literals: FxHashMap::default(), + utf16_literals: FxHashMap::default(), } } diff --git a/src/index.rs b/src/index.rs index 02ef8243d6..f96577089a 100644 --- a/src/index.rs +++ b/src/index.rs @@ -1,9 +1,11 @@ // Copyright (c) 2020 Ghaith Hachem and Mathias Rieder -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; +use std::hash::BuildHasherDefault; -use indexmap::IndexMap; +use indexmap::{IndexMap, IndexSet}; use itertools::Itertools; +use rustc_hash::FxHasher; use plc_ast::ast::{ AstId, AstNode, AstStatement, DirectAccessType, GenericBinding, HardwareAccessType, LinkageType, PouType, @@ -32,6 +34,18 @@ pub mod symbol; mod tests; pub mod visitor; +/// Type alias for a HashMap using the `fx` hashing algorithm, see https://github.com/rust-lang/rustc-hash +pub type FxHashMap = HashMap>; + +/// Type alias for a HashSet using the `fx` hashing algorithm, see https://github.com/rust-lang/rustc-hash +pub type FxHashSet = HashSet>; + +/// Type alias for an IndexMap using the `fx` hashing algorithm, see https://github.com/rust-lang/rustc-hash +pub type FxIndexMap = IndexMap>; + +/// Type alias for a IndexSet using the `fx` hashing algorithm, see https://github.com/rust-lang/rustc-hash +pub type FxIndexSet = IndexSet>; + /// A label represents a possible jump point in the source. /// It can be referenced by jump elements in the same unit #[derive(Debug, PartialEq, Eq, Clone, Hash)] @@ -815,7 +829,7 @@ impl TypeIndex { #[derive(Debug, Default)] pub struct Index { /// all global variables - global_variables: SymbolMap, // IndexMap>, + global_variables: SymbolMap, /// all struct initializers global_initializers: SymbolMap, @@ -829,7 +843,7 @@ pub struct Index { /// all implementations // we keep an IndexMap for implementations since duplication issues regarding implementations // is handled by the `pous` SymbolMap - implementations: IndexMap, + implementations: FxIndexMap, /// an index with all type-information type_index: TypeIndex, @@ -840,7 +854,7 @@ pub struct Index { data_layout: DataLayout, /// The labels contained in each pou - labels: IndexMap>, + labels: FxIndexMap>, } impl Index { @@ -1158,7 +1172,7 @@ impl Index { /// Returns all enum variants defined in the given POU pub fn get_enum_variants_in_pou(&self, pou: &str) -> Vec<&VariableIndexEntry> { - let mut hs: HashSet<&VariableIndexEntry> = HashSet::new(); + let mut hs: FxHashSet<&VariableIndexEntry> = FxHashSet::default(); for member in self.get_pou_members(pou) { if self.type_index.find_type(member.get_type_name()).is_some_and(|it| it.is_enum()) { hs.insert(member); @@ -1363,7 +1377,7 @@ impl Index { self.enum_global_variables.values().collect() } - pub fn get_implementations(&self) -> &IndexMap { + pub fn get_implementations(&self) -> &FxIndexMap { &self.implementations } diff --git a/src/index/symbol.rs b/src/index/symbol.rs index e4558d5052..50ab7ca6fc 100644 --- a/src/index/symbol.rs +++ b/src/index/symbol.rs @@ -1,6 +1,7 @@ // Copyright (c) 2022 Ghaith Hachem and Mathias Rieder -use indexmap::{Equivalent, IndexMap}; +use crate::index::FxIndexMap; +use indexmap::Equivalent; use std::hash::Hash; /// A multi-map implementation with a stable order of elements. When iterating @@ -9,7 +10,7 @@ use std::hash::Hash; pub struct SymbolMap { /// internal storage of the SymbolMap that uses an * /// IndexMap of Vectors - inner_map: IndexMap>, + inner_map: FxIndexMap>, } impl Default for SymbolMap { @@ -47,7 +48,7 @@ where } /// removes and returns all elements in the SymbolMap - pub fn drain(&mut self, range: std::ops::RangeFull) -> indexmap::map::Drain<'_, K, std::vec::Vec> { + pub fn drain(&mut self, range: std::ops::RangeFull) -> indexmap::map::Drain<'_, K, Vec> { self.inner_map.drain(range) } diff --git a/src/resolver.rs b/src/resolver.rs index 2d5e714671..dabc731597 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -5,12 +5,7 @@ //! Recursively visits all statements and expressions of a `CompilationUnit` and //! records all resulting types associated with the statement's id. -use std::{ - collections::{HashMap, HashSet}, - hash::Hash, -}; - -use indexmap::{IndexMap, IndexSet}; +use std::{collections::HashSet, hash::Hash}; use plc_ast::{ ast::{ @@ -26,6 +21,7 @@ use plc_ast::{ use plc_source::source_location::SourceLocation; use plc_util::convention::internal_type_name; +use crate::index::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use crate::typesystem::VOID_INTERNAL_NAME; use crate::{ builtins::{self, BuiltIn}, @@ -151,10 +147,10 @@ pub struct TypeAnnotator<'i> { pub(crate) index: &'i Index, pub(crate) annotation_map: AnnotationMapImpl, string_literals: StringLiterals, - dependencies: IndexSet, + dependencies: FxIndexSet, /// A map containing every jump encountered in a file, and the label of where this jump should /// point. This is later used to annotate all jumps after the initial visit is done. - jumps_to_annotate: HashMap>>, + jumps_to_annotate: FxHashMap>>, } impl TypeAnnotator<'_> { @@ -163,16 +159,18 @@ impl TypeAnnotator<'_> { StatementAnnotation::Function { return_type, qualified_name, call_name } => { let name = call_name.as_ref().unwrap_or(qualified_name); self.dependencies.insert(Dependency::Call(name.to_string())); - self.dependencies.extend(self.get_datatype_dependencies(name, IndexSet::new())); - self.dependencies.extend(self.get_datatype_dependencies(return_type, IndexSet::new())); + self.dependencies.extend(self.get_datatype_dependencies(name, FxIndexSet::default())); + self.dependencies.extend(self.get_datatype_dependencies(return_type, FxIndexSet::default())); } StatementAnnotation::Program { qualified_name } => { self.dependencies.insert(Dependency::Call(qualified_name.to_string())); - self.dependencies.extend(self.get_datatype_dependencies(qualified_name, IndexSet::new())); + self.dependencies + .extend(self.get_datatype_dependencies(qualified_name, FxIndexSet::default())); } StatementAnnotation::Variable { resulting_type, qualified_name, argument_type, .. } => { if matches!(argument_type.get_inner(), VariableType::Global) { - self.dependencies.extend(self.get_datatype_dependencies(resulting_type, IndexSet::new())); + self.dependencies + .extend(self.get_datatype_dependencies(resulting_type, FxIndexSet::default())); self.dependencies.insert(Dependency::Variable(qualified_name.to_string())); } } @@ -276,7 +274,7 @@ impl TypeAnnotator<'_> { }; let operator_qualifier = &self.get_call_name(operator); - let mut generics_candidates: HashMap> = HashMap::new(); + let mut generics_candidates: FxHashMap> = FxHashMap::default(); let mut params = vec![]; let mut parameters = parameters.into_iter(); @@ -608,16 +606,16 @@ impl AstAnnotations { #[derive(Default, Debug)] pub struct AnnotationMapImpl { /// maps a statement to the type it resolves to - type_map: IndexMap, + type_map: FxIndexMap, /// maps a statement to the target-type it should eventually resolve to /// example: /// x : BYTE := 1; //1's actual type is DINT, 1's target type is BYTE /// x : INT := 1; //1's actual type is DINT, 1's target type is INT - type_hint_map: IndexMap, + type_hint_map: FxIndexMap, /// A map from a call to the generic function name of that call - generic_nature_map: IndexMap, + generic_nature_map: FxIndexMap, /// maps a function to a statement /// @@ -628,7 +626,7 @@ pub struct AnnotationMapImpl { /// ... /// x : BYTE(0..100); /// x := 10; // a call to `CheckRangeUnsigned` is maped to `10` - hidden_function_calls: IndexMap, + hidden_function_calls: FxIndexMap, //An index of newly created types pub new_index: Index, @@ -702,8 +700,8 @@ impl AnnotationMap for AnnotationMapImpl { #[derive(Default)] pub struct StringLiterals { - pub utf08: HashSet, - pub utf16: HashSet, + pub utf08: FxHashSet, + pub utf16: FxHashSet, } impl StringLiterals { @@ -719,9 +717,9 @@ impl<'i> TypeAnnotator<'i> { TypeAnnotator { annotation_map: AnnotationMapImpl::new(), index, - dependencies: IndexSet::new(), - string_literals: StringLiterals { utf08: HashSet::new(), utf16: HashSet::new() }, - jumps_to_annotate: HashMap::new(), + dependencies: FxIndexSet::default(), + string_literals: StringLiterals { utf08: HashSet::default(), utf16: HashSet::default() }, + jumps_to_annotate: FxHashMap::default(), } } @@ -731,7 +729,7 @@ impl<'i> TypeAnnotator<'i> { index: &Index, unit: &'i CompilationUnit, id_provider: IdProvider, - ) -> (AnnotationMapImpl, IndexSet, StringLiterals) { + ) -> (AnnotationMapImpl, FxIndexSet, StringLiterals) { let mut visitor = TypeAnnotator::new(index); let ctx = &VisitorContext { pou: None, @@ -759,7 +757,7 @@ impl<'i> TypeAnnotator<'i> { let body_ctx = ctx.enter_body(); for i in &unit.implementations { - visitor.dependencies.extend(visitor.get_datatype_dependencies(&i.name, IndexSet::new())); + visitor.dependencies.extend(visitor.get_datatype_dependencies(&i.name, FxIndexSet::default())); i.statements.iter().for_each(|s| visitor.visit_statement(&body_ctx.with_pou(i.name.as_str()), s)); } @@ -1118,7 +1116,7 @@ impl<'i> TypeAnnotator<'i> { fn visit_data_type_declaration(&mut self, ctx: &VisitorContext, declaration: &DataTypeDeclaration) { if let Some(name) = declaration.get_name() { - let deps = self.get_datatype_dependencies(name, IndexSet::new()); + let deps = self.get_datatype_dependencies(name, FxIndexSet::default()); self.dependencies.extend(deps); } if let DataTypeDeclaration::DataTypeDefinition { data_type, .. } = declaration { @@ -1129,8 +1127,8 @@ impl<'i> TypeAnnotator<'i> { fn get_datatype_dependencies( &self, datatype_name: &str, - resolved: IndexSet, - ) -> IndexSet { + resolved: FxIndexSet, + ) -> FxIndexSet { let mut resolved_names = resolved; let Some(datatype) = self .index diff --git a/src/resolver/generics.rs b/src/resolver/generics.rs index 2a90620605..60ded59d26 100644 --- a/src/resolver/generics.rs +++ b/src/resolver/generics.rs @@ -1,8 +1,7 @@ -use std::collections::HashMap; - use plc_ast::ast::{flatten_expression_list, AstNode, AstStatement, GenericBinding, LinkageType, TypeNature}; use plc_source::source_location::SourceLocation; +use crate::index::FxHashMap; use crate::{ builtins, codegen::generators::expression_generator::get_implicit_call_parameter, @@ -62,7 +61,7 @@ impl<'i> TypeAnnotator<'i> { /// then chooses the best fitting function signature and reannotates the function with the found information. pub(crate) fn update_generic_call_statement( &mut self, - generics_candidates: HashMap>, + generics_candidates: FxHashMap>, implementation_name: &str, operator: &AstNode, parameters: Option<&AstNode>, @@ -128,7 +127,7 @@ impl<'i> TypeAnnotator<'i> { generic_function: &PouIndexEntry, return_type: &str, new_name: &str, - generics: &HashMap, + generics: &FxHashMap, ) { // the generic implementation if let Some(generic_implementation) = generic_function.find_implementation(self.index) { @@ -191,7 +190,7 @@ impl<'i> TypeAnnotator<'i> { fn find_or_create_datatype( &mut self, member_name: &str, - generics: &HashMap, + generics: &FxHashMap, ) -> String { match self.index.find_effective_type_info(member_name) { Some(DataTypeInformation::Generic { generic_symbol, .. }) => { @@ -233,7 +232,7 @@ impl<'i> TypeAnnotator<'i> { &mut self, s: &AstNode, function_name: &str, - generic_map: &HashMap, + generic_map: &FxHashMap, ) { /// An internal struct used to hold the type and nature of a generic parameter struct TypeAndNature<'a> { @@ -322,7 +321,7 @@ impl<'i> TypeAnnotator<'i> { generics: &[GenericBinding], generic_qualified_name: &str, generic_return_type: &str, - generic_map: &HashMap, + generic_map: &FxHashMap, generic_name_resolver: GenericNameResolver, ) -> (String, StatementAnnotation) { let call_name = generic_name_resolver(generic_qualified_name, generics, generic_map); @@ -356,9 +355,9 @@ impl<'i> TypeAnnotator<'i> { pub fn derive_generic_types( &self, generics: &[GenericBinding], - generics_candidates: HashMap>, - ) -> HashMap { - let mut generic_map: HashMap = HashMap::new(); + generics_candidates: FxHashMap>, + ) -> FxHashMap { + let mut generic_map: FxHashMap = FxHashMap::default(); for GenericBinding { name, nature } in generics { let smallest_possible_type = self.index.find_effective_type_info(get_smallest_possible_type(nature)); @@ -425,13 +424,13 @@ impl<'i> TypeAnnotator<'i> { } } -type GenericNameResolver = fn(&str, &[GenericBinding], &HashMap) -> String; +type GenericNameResolver = fn(&str, &[GenericBinding], &FxHashMap) -> String; /// Builds the correct generic name from the given information pub fn generic_name_resolver( qualified_name: &str, generics: &[GenericBinding], - generic_map: &HashMap, + generic_map: &FxHashMap, ) -> String { generics .iter() @@ -445,9 +444,9 @@ pub fn generic_name_resolver( pub fn no_generic_name_resolver( qualified_name: &str, _: &[GenericBinding], - _: &HashMap, + _: &FxHashMap, ) -> String { - generic_name_resolver(qualified_name, &[], &HashMap::new()) + generic_name_resolver(qualified_name, &[], &FxHashMap::default()) } pub fn get_smallest_possible_type(nature: &TypeNature) -> &str { diff --git a/src/validation/global.rs b/src/validation/global.rs index 78930a77de..57457100c8 100644 --- a/src/validation/global.rs +++ b/src/validation/global.rs @@ -1,10 +1,8 @@ -use std::collections::HashMap; - use plc_ast::ast::PouType; use plc_diagnostics::diagnostics::Diagnostic; use plc_source::source_location::SourceLocation; -use crate::index::VariableIndexEntry; +use crate::index::{FxHashMap, VariableIndexEntry}; use crate::{ index::{symbol::SymbolMap, Index, PouIndexEntry}, typesystem::{DataTypeInformation, StructSource}, @@ -95,7 +93,7 @@ impl GlobalValidator { // Report name conflicts between any member variables in the VAR block for ty in index.get_types().values().chain(index.get_pou_types().values()) { - let mut groups: HashMap<&str, Vec<&VariableIndexEntry>> = HashMap::new(); + let mut groups: FxHashMap<&str, Vec<&VariableIndexEntry>> = FxHashMap::default(); for variable in ty.get_members() { let group = groups.entry(variable.get_qualified_name()).or_default(); group.push(variable); @@ -109,7 +107,7 @@ impl GlobalValidator { // Report name conflicts between enum variants and any other member variable in the VAR block for pou in index.get_pou_types().values() { - let mut groups: HashMap<&str, Vec<&VariableIndexEntry>> = HashMap::new(); + let mut groups: FxHashMap<&str, Vec<&VariableIndexEntry>> = FxHashMap::default(); let variants = index.get_enum_variants_in_pou(pou.get_name()); for variant in variants { diff --git a/src/validation/recursive.rs b/src/validation/recursive.rs index c1fe347584..272946f538 100644 --- a/src/validation/recursive.rs +++ b/src/validation/recursive.rs @@ -1,9 +1,9 @@ -use indexmap::IndexSet; use itertools::Itertools; use plc_ast::ast::PouType; use plc_diagnostics::diagnostics::Diagnostic; +use crate::index::FxIndexSet; use crate::{ index::{Index, VariableIndexEntry}, typesystem::{DataType, DataTypeInformation, DataTypeInformationProvider, StructSource}, @@ -39,8 +39,8 @@ impl RecursiveValidator { /// Entry point of finding and reporting all recursive data structures. pub fn validate(&mut self, index: &Index) { - let mut nodes_all: IndexSet<&DataType> = IndexSet::new(); - let mut nodes_visited = IndexSet::new(); + let mut nodes_all: FxIndexSet<&DataType> = FxIndexSet::default(); + let mut nodes_visited = FxIndexSet::default(); // Structs (includes arrays defined in structs) nodes_all.extend(index.get_types().values().filter(|x| x.get_type_information().is_struct())); @@ -60,10 +60,10 @@ impl RecursiveValidator { fn find_cycle<'idx>( &mut self, index: &'idx Index, - nodes_all: IndexSet<&'idx DataType>, - nodes_visited: &mut IndexSet<&'idx DataType>, + nodes_all: FxIndexSet<&'idx DataType>, + nodes_visited: &mut FxIndexSet<&'idx DataType>, ) { - let mut path = IndexSet::new(); + let mut path = FxIndexSet::default(); for node in &nodes_all { if !nodes_visited.contains(node) { @@ -80,15 +80,15 @@ impl RecursiveValidator { fn dfs<'idx>( &mut self, index: &'idx Index, - path: &mut IndexSet<&'idx DataType>, + path: &mut FxIndexSet<&'idx DataType>, node_curr: &'idx DataType, - nodes_visited: &mut IndexSet<&'idx DataType>, + nodes_visited: &mut FxIndexSet<&'idx DataType>, ) { nodes_visited.insert(node_curr); path.insert(node_curr); for node in - node_curr.get_struct_members().iter().map(|x| self.get_type(index, x)).collect::>() + node_curr.get_struct_members().iter().map(|x| self.get_type(index, x)).collect::>() { if path.contains(node) { self.report(node, path); @@ -102,7 +102,7 @@ impl RecursiveValidator { /// Generates and reports the minimal path of a cycle. Specifically `path` contains all nodes visited up /// until a cycle, e.g. `A -> B -> C -> B`. We are only interested in `B -> C -> B` as such this method /// finds the first occurence of `B` to create a vector slice of `B -> C -> B` for the diagnostician. - fn report<'idx>(&mut self, node: &'idx DataType, path: &mut IndexSet<&'idx DataType>) { + fn report<'idx>(&mut self, node: &'idx DataType, path: &mut FxIndexSet<&'idx DataType>) { match path.get_index_of(node) { Some(idx) => { let mut slice = path.iter().skip(idx).copied().collect::>(); @@ -128,7 +128,7 @@ impl RecursiveValidator { self.diagnostics.push(diagnostic); } - None => unreachable!("Node has to be in the IndexSet"), + None => unreachable!("Node has to be in the FxIndexSet"), } } diff --git a/src/validation/statement.rs b/src/validation/statement.rs index f6cd015d8e..c5001a57de 100644 --- a/src/validation/statement.rs +++ b/src/validation/statement.rs @@ -1,4 +1,4 @@ -use std::{collections::HashSet, mem::discriminant}; +use std::mem::discriminant; use plc_ast::control_statements::ForLoopStatement; use plc_ast::{ @@ -12,7 +12,7 @@ use plc_ast::{ use plc_diagnostics::diagnostics::Diagnostic; use plc_source::source_location::SourceLocation; -use crate::index::ImplementationType; +use crate::index::{FxHashMap, FxHashSet, ImplementationType}; use crate::validation::statement::helper::{get_datatype_name_or_slice, get_literal_int_or_const_expr_value}; use crate::{ builtins::{self, BuiltIn}, @@ -1259,7 +1259,7 @@ fn validate_case_statement( ) { visit_statement(validator, selector, context); - let mut cases = HashSet::new(); + let mut cases = FxHashSet::default(); case_blocks.iter().for_each(|b| { let condition = b.condition.as_ref(); @@ -1388,14 +1388,13 @@ fn validate_assignment_type_sizes( right: &AstNode, context: &ValidationContext, ) { - use std::collections::HashMap; fn get_expression_types_and_locations<'b, T: AnnotationMap>( expression: &AstNode, context: &'b ValidationContext, lhs_is_signed_int: bool, is_builtin_call: bool, - ) -> HashMap<&'b DataType, Vec> { - let mut map: HashMap<&DataType, Vec> = HashMap::new(); + ) -> FxHashMap<&'b DataType, Vec> { + let mut map: FxHashMap<&DataType, Vec> = FxHashMap::default(); match expression.get_stmt_peeled() { AstStatement::BinaryExpression(BinaryExpression { operator, left, right, .. }) if !operator.is_comparison_operator() => From 8364b52bebaa36a7689e3726224022503a05a9aa Mon Sep 17 00:00:00 2001 From: Volkan Sagcan Date: Tue, 14 May 2024 12:17:51 +0200 Subject: [PATCH 2/2] refactor: Cache find_type calls in resolver --- src/resolver.rs | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/resolver.rs b/src/resolver.rs index dabc731597..c8f19fee7f 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -5,6 +5,7 @@ //! Recursively visits all statements and expressions of a `CompilationUnit` and //! records all resulting types associated with the statement's id. +use std::cell::RefCell; use std::{collections::HashSet, hash::Hash}; use plc_ast::{ @@ -151,8 +152,27 @@ pub struct TypeAnnotator<'i> { /// A map containing every jump encountered in a file, and the label of where this jump should /// point. This is later used to annotate all jumps after the initial visit is done. jumps_to_annotate: FxHashMap>>, + lowercase_cache: RefCell>>, } +impl TypeAnnotator<'_> { + fn find_type(&self, input: &str) -> Option<&typesystem::DataType> { + if let Some(ty) = self.lowercase_cache.borrow().get(input) { + return Some(ty.as_ref()?); + } + + match self.index.find_type(input) { + Some(value) => { + self.lowercase_cache.borrow_mut().insert(input.to_string(), Some(value)); + Some(value) + } + None => { + self.lowercase_cache.borrow_mut().insert(input.to_string(), None); + None + } + } + } +} impl TypeAnnotator<'_> { pub fn annotate(&mut self, s: &AstNode, annotation: StatementAnnotation) { match &annotation { @@ -176,7 +196,6 @@ impl TypeAnnotator<'_> { } StatementAnnotation::Value { resulting_type } => { if let Some(dt) = self - .index .find_type(resulting_type) .or_else(|| self.annotation_map.new_index.find_type(resulting_type)) { @@ -720,6 +739,7 @@ impl<'i> TypeAnnotator<'i> { dependencies: FxIndexSet::default(), string_literals: StringLiterals { utf08: HashSet::default(), utf16: HashSet::default() }, jumps_to_annotate: FxHashMap::default(), + lowercase_cache: RefCell::new(FxHashMap::default()), } } @@ -1130,10 +1150,8 @@ impl<'i> TypeAnnotator<'i> { resolved: FxIndexSet, ) -> FxIndexSet { let mut resolved_names = resolved; - let Some(datatype) = self - .index - .find_type(datatype_name) - .or_else(|| self.annotation_map.new_index.find_type(datatype_name)) + let Some(datatype) = + self.find_type(datatype_name).or_else(|| self.annotation_map.new_index.find_type(datatype_name)) else { return resolved_names; }; @@ -1641,13 +1659,11 @@ impl<'i> TypeAnnotator<'i> { AstStatement::Literal(..) => { self.visit_statement_literals(ctx, reference); let literal_annotation = self.annotation_map.get(reference).cloned(); // return what we just annotated //TODO not elegant, we need to clone - if let Some((base_type, literal_type)) = - qualifier.and_then(|base| self.index.find_type(base)).zip( - literal_annotation - .as_ref() - .and_then(|a| self.annotation_map.get_type_for_annotation(self.index, a)), - ) - { + if let Some((base_type, literal_type)) = qualifier.and_then(|base| self.find_type(base)).zip( + literal_annotation + .as_ref() + .and_then(|a| self.annotation_map.get_type_for_annotation(self.index, a)), + ) { // see if this was casted if base_type != literal_type { return Some(StatementAnnotation::value(base_type.get_name())); @@ -2077,6 +2093,7 @@ impl ResolvingScope { ResolvingScope::DataType => { if qualifier.is_none() { // look for datatype with name "name" + // TODO: Here index .find_type(name) .map(|data_type| StatementAnnotation::data_type(data_type.get_name()))