Ignore:
Timestamp:
Nov 25, 2020, 3:12:17 AM (13 months ago)
Author:
Fangren Yu <f37yu@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast-unique-expr
Children:
4702a2c
Parents:
7192145
Message:

create dedicated symbol tables for big 3 operators
note: arbitrary this param type is not supported; it is currently allowed although never used

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/SymbolTable.cpp

    r7192145 re5c3811  
    9595}
    9696
     97SymbolTable::SpecialFunctionKind SymbolTable::getSpecialFunctionKind(const std::string & name) {
     98        if (name == "?{}") return CTOR;
     99        if (name == "^?{}") return DTOR;
     100        if (name == "?=?") return ASSIGN;
     101        return NUMBER_OF_KINDS;
     102}
     103
    97104std::vector<SymbolTable::IdData> SymbolTable::lookupId( const std::string &id ) const {
     105        static Stats::Counters::CounterGroup * name_lookup_stats = Stats::Counters::build<Stats::Counters::CounterGroup>("Name Lookup Stats");
     106        static std::map<std::string, Stats::Counters::SimpleCounter *> lookups_by_name;
     107        static std::map<std::string, Stats::Counters::SimpleCounter *> candidates_by_name;
     108
     109        SpecialFunctionKind kind = getSpecialFunctionKind(id);
     110        if (kind != NUMBER_OF_KINDS) return specialLookupId(kind);
     111
    98112        ++*stats().lookup_calls;
    99113        if ( ! idTable ) return {};
     
    107121                out.push_back( decl.second );
    108122        }
     123
     124        if (Stats::Counters::enabled) {
     125                if (! lookups_by_name.count(id)) {
     126                        // leaks some strings, but it is because Counters do not hold them
     127                        auto lookupCounterName = new std::string(id + "%count");
     128                        auto candidatesCounterName = new std::string(id + "%candidate");
     129                        lookups_by_name.emplace(id, new Stats::Counters::SimpleCounter(lookupCounterName->c_str(), name_lookup_stats));
     130                        candidates_by_name.emplace(id, new Stats::Counters::SimpleCounter(candidatesCounterName->c_str(), name_lookup_stats));
     131                }
     132                (*lookups_by_name[id]) ++;
     133                *candidates_by_name[id] += out.size();
     134        }
     135
     136        return out;
     137}
     138
     139std::vector<SymbolTable::IdData> SymbolTable::specialLookupId( SymbolTable::SpecialFunctionKind kind, const std::string & otypeKey ) const {
     140        static Stats::Counters::CounterGroup * special_stats = Stats::Counters::build<Stats::Counters::CounterGroup>("Special Lookups");
     141        static Stats::Counters::SimpleCounter * stat_counts[3] = {
     142                Stats::Counters::build<Stats::Counters::SimpleCounter>("constructor - count", special_stats),
     143                Stats::Counters::build<Stats::Counters::SimpleCounter>("destructor - count", special_stats),
     144                Stats::Counters::build<Stats::Counters::SimpleCounter>("assignment - count", special_stats)
     145        };
     146
     147        static Stats::Counters::SimpleCounter * stat_candidates[3] = {
     148                Stats::Counters::build<Stats::Counters::SimpleCounter>("constructor - candidates", special_stats),
     149                Stats::Counters::build<Stats::Counters::SimpleCounter>("destructor - candidates", special_stats),
     150                Stats::Counters::build<Stats::Counters::SimpleCounter>("assignment - candidates", special_stats)
     151        };
     152
     153        static Stats::Counters::SimpleCounter * num_lookup_with_key
     154                = Stats::Counters::build<Stats::Counters::SimpleCounter>("keyed lookups", special_stats);
     155        static Stats::Counters::SimpleCounter * num_lookup_without_key
     156                = Stats::Counters::build<Stats::Counters::SimpleCounter>("unkeyed lookups", special_stats);
     157
     158        assert (kind != NUMBER_OF_KINDS);
     159        ++*stats().lookup_calls;
     160        if ( ! specialFunctionTable[kind] ) return {};
     161
     162        std::vector<IdData> out;
     163
     164        if (otypeKey.empty()) { // returns everything
     165                ++*num_lookup_without_key;
     166                for (auto & table : *specialFunctionTable[kind]) {
     167                        for (auto & decl : *table.second) {
     168                                out.push_back(decl.second);
     169                        }
     170                }
     171        }
     172        else {
     173                ++*num_lookup_with_key;
     174                ++*stats().map_lookups;
     175                auto decls = specialFunctionTable[kind]->find(otypeKey);
     176                if (decls == specialFunctionTable[kind]->end()) return {};
     177
     178                for (auto decl : *(decls->second)) {
     179                        out.push_back(decl.second);
     180                }
     181        }
     182
     183        ++*stat_counts[kind];
     184        *stat_candidates[kind] += out.size();
     185
    109186        return out;
    110187}
     
    366443namespace {
    367444        /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function
    368         std::string getOtypeKey( const FunctionDecl * function ) {
    369                 const auto & params = function->type->params;
     445        std::string getOtypeKey( const FunctionType * ftype, bool stripParams = true ) {
     446                const auto & params = ftype->params;
    370447                assert( ! params.empty() );
    371448                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
    372449                const Type * base = InitTweak::getPointerBase( params.front() );
    373450                assert( base );
    374                 return Mangle::mangle( base );
     451                if (stripParams) {
     452                        if (dynamic_cast<const PointerType *>(base)) return Mangle::Encoding::pointer;
     453                        return Mangle::mangle( base, Mangle::Type | Mangle::NoGenericParams );
     454                }
     455                else
     456                        return Mangle::mangle( base ); 
    375457        }
    376458
     
    380462                        const DeclWithType * decl, const std::string & otypeKey ) {
    381463                auto func = dynamic_cast< const FunctionDecl * >( decl );
    382                 if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr;
     464                if ( ! func || otypeKey != getOtypeKey( func->type, false ) ) return nullptr;
    383465                return func;
    384466        }
     
    405487        bool dataIsUserDefinedFunc = ! function->linkage.is_overrideable;
    406488        bool dataIsCopyFunc = InitTweak::isCopyFunction( function );
    407         std::string dataOtypeKey = getOtypeKey( function );
     489        std::string dataOtypeKey = getOtypeKey( function->type, false ); // requires exact match to override autogen
    408490
    409491        if ( dataIsUserDefinedFunc && dataIsCopyFunc ) {
     
    577659                const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr,
    578660                const Decl * deleter ) {
     661        SpecialFunctionKind kind = getSpecialFunctionKind(decl->name);
     662        if (kind == NUMBER_OF_KINDS) { // not a special decl
     663                addId(decl, decl->name, idTable, handleConflicts, baseExpr, deleter);
     664        }
     665        else {
     666                std::string key;
     667                if (auto func = dynamic_cast<const FunctionDecl *>(decl)) {
     668                        key = getOtypeKey(func->type);
     669                }
     670                else if (auto obj = dynamic_cast<const ObjectDecl *>(decl)) {
     671                        key = getOtypeKey(obj->type.strict_as<PointerType>()->base.strict_as<FunctionType>());
     672                }
     673                else {
     674                        assertf(false, "special decl with non-function type");
     675                }
     676                addId(decl, key, specialFunctionTable[kind], handleConflicts, baseExpr, deleter);
     677        }
     678}
     679
     680void SymbolTable::addId(
     681                const DeclWithType * decl, const std::string & lookupKey, IdTable::Ptr & table, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr,
     682                const Decl * deleter ) {
    579683        ++*stats().add_calls;
    580684        const std::string &name = decl->name;
     
    607711        // ensure tables exist and add identifier
    608712        MangleTable::Ptr mangleTable;
    609         if ( ! idTable ) {
    610                 idTable = IdTable::new_ptr();
     713        if ( ! table ) {
     714                table = IdTable::new_ptr();
    611715                mangleTable = MangleTable::new_ptr();
    612716        } else {
    613717                ++*stats().map_lookups;
    614                 auto decls = idTable->find( name );
    615                 if ( decls == idTable->end() ) {
     718                auto decls = table->find( lookupKey );
     719                if ( decls == table->end() ) {
    616720                        mangleTable = MangleTable::new_ptr();
    617721                } else {
     
    628732                                                lazyInitScope();
    629733                                                *stats().map_mutations += 2;
    630                                                 idTable = idTable->set(
    631                                                         name,
     734                                                table = table->set(
     735                                                        lookupKey,
    632736                                                        mangleTable->set(
    633737                                                                mangleName,
     
    644748        IdData data{ decl, baseExpr, deleter, scope };
    645749        // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary
    646         if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
     750        if (table != idTable) { // adding to special table
     751                if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
     752        }
    647753        *stats().map_mutations += 2;
    648         idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) );
     754        table = table->set( lookupKey, mangleTable->set( mangleName, std::move(data) ) );
    649755}
    650756
Note: See TracChangeset for help on using the changeset viewer.