Ignore:
Timestamp:
May 31, 2018, 4:24:49 PM (6 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env, with_gc
Children:
0182bfa, 1d7b0a8
Parents:
75308bcc
Message:

stop eagerly copying EqvClass? on lookup

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r75308bcc r8e18b8e  
    1919#include <set>                    // for set
    2020#include <string>                 // for string, operator==, operator!=, bas...
    21 #include <utility>                // for pair
     21#include <utility>                // for pair, move
    2222
    2323#include "Common/PassVisitor.h"   // for PassVisitor
     
    159159                        return false;
    160160                } // if
    161                 EqvClass curClass;
    162                 if ( env.lookup( typeInst->get_name(), curClass ) ) {
    163                         if ( curClass.type ) {
     161                if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) {
     162                        if ( curClass->type ) {
    164163                                Type *common = 0;
    165164                                // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
    166                                 Type* newType = curClass.type->clone();
     165                                Type* newType = curClass->type->clone();
    167166                                newType->get_qualifiers() = typeInst->get_qualifiers();
    168                                 if ( unifyInexact( newType, other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
     167                                if ( unifyInexact( newType, other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {
    169168                                        if ( common ) {
    170169                                                common->get_qualifiers() = Type::Qualifiers();
    171                                                 curClass.type = common;
    172                                                 env.add( curClass );
     170                                                EqvClass newClass = *curClass;
     171                                                newClass.type = common;
     172                                                env.add( std::move(newClass) );
    173173                                        } // if
    174174                                        return true;
     
    177177                                } // if
    178178                        } else {
    179                                 curClass.type = other->clone();
    180                                 curClass.type->get_qualifiers() = Type::Qualifiers();
    181                                 curClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    182                                 env.add( curClass );
     179                                EqvClass newClass = *curClass;
     180                                newClass.type = other->clone();
     181                                newClass.type->get_qualifiers() = Type::Qualifiers();
     182                                newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
     183                                env.add( std::move(newClass) );
    183184                        } // if
    184185                } else {
     
    196197        bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    197198                bool result = true;
    198                 EqvClass class1, class2;
    199                 bool hasClass1 = false, hasClass2 = false;
     199                const EqvClass *class1 = env.lookup( var1->get_name() );
     200                const EqvClass *class2 = env.lookup( var2->get_name() );
    200201                bool widen1 = false, widen2 = false;
    201                 Type *type1 = 0, *type2 = 0;
    202 
    203                 if ( env.lookup( var1->get_name(), class1 ) ) {
    204                         hasClass1 = true;
    205                         if ( class1.type ) {
    206                                 if ( occurs( class1.type, var2->get_name(), env ) ) {
     202                Type *type1 = nullptr, *type2 = nullptr;
     203
     204                if ( class1 ) {
     205                        if ( class1->type ) {
     206                                if ( occurs( class1->type, var2->get_name(), env ) ) {
    207207                                        return false;
    208208                                } // if
    209                                 type1 = class1.type->clone();
    210                         } // if
    211                         widen1 = widenMode.widenFirst && class1.allowWidening;
    212                 } // if
    213                 if ( env.lookup( var2->get_name(), class2 ) ) {
    214                         hasClass2 = true;
    215                         if ( class2.type ) {
    216                                 if ( occurs( class2.type, var1->get_name(), env ) ) {
     209                                type1 = class1->type->clone();
     210                        } // if
     211                        widen1 = widenMode.widenFirst && class1->allowWidening;
     212                } // if
     213                if ( class2 ) {
     214                        if ( class2->type ) {
     215                                if ( occurs( class2->type, var1->get_name(), env ) ) {
    217216                                        return false;
    218217                                } // if
    219                                 type2 = class2.type->clone();
    220                         } // if
    221                         widen2 = widenMode.widenSecond && class2.allowWidening;
     218                                type2 = class2->type->clone();
     219                        } // if
     220                        widen2 = widenMode.widenSecond && class2->allowWidening;
    222221                } // if
    223222
     
    227226                        Type *common = 0;
    228227                        if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
    229                                 class1.vars.insert( class2.vars.begin(), class2.vars.end() );
    230                                 class1.allowWidening = widen1 && widen2;
     228                                EqvClass newClass1 = *class1;
     229                                newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
     230                                newClass1.allowWidening = widen1 && widen2;
    231231                                if ( common ) {
    232232                                        common->get_qualifiers() = Type::Qualifiers();
    233                                         class1.type = common;
     233                                        newClass1.type = common;
    234234                                } // if
    235                                 env.add( class1 );
     235                                env.add( std::move(newClass1) );
    236236                        } else {
    237237                                result = false;
    238238                        } // if
    239                 } else if ( hasClass1 && hasClass2 ) {
     239                } else if ( class1 && class2 ) {
    240240                        if ( type1 ) {
    241                                 class1.vars.insert( class2.vars.begin(), class2.vars.end() );
    242                                 class1.allowWidening = widen1;
    243                                 env.add( class1 );
     241                                EqvClass newClass1 = *class1;
     242                                newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
     243                                newClass1.allowWidening = widen1;
     244                                env.add( std::move(newClass1) );
    244245                        } else {
    245                                 class2.vars.insert( class1.vars.begin(), class1.vars.end() );
    246                                 class2.allowWidening = widen2;
    247                                 env.add( class2 );
    248                         } // if
    249                 } else if ( hasClass1 ) {
    250                         class1.vars.insert( var2->get_name() );
    251                         class1.allowWidening = widen1;
    252                         env.add( class1 );
    253                 } else if ( hasClass2 ) {
    254                         class2.vars.insert( var1->get_name() );
    255                         class2.allowWidening = widen2;
    256                         env.add( class2 );
     246                                EqvClass newClass2 = *class2;
     247                                newClass2.vars.insert( class1->vars.begin(), class1->vars.end() );
     248                                newClass2.allowWidening = widen2;
     249                                env.add( std::move(newClass2) );
     250                        } // if
     251                } else if ( class1 ) {
     252                        EqvClass newClass1 = *class1;
     253                        newClass1.vars.insert( var2->get_name() );
     254                        newClass1.allowWidening = widen1;
     255                        env.add( std::move(newClass1) );
     256                } else if ( class2 ) {
     257                        EqvClass newClass2 = *class2;
     258                        newClass2.vars.insert( var1->get_name() );
     259                        newClass2.allowWidening = widen2;
     260                        env.add( std::move(newClass2) );
    257261                } else {
    258262                        EqvClass newClass;
     
    521525                void premutate( TypeInstType * ) { visit_children = false; }
    522526                Type * postmutate( TypeInstType * typeInst ) {
    523                         EqvClass eqvClass;
    524                         if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) {
    525                                 if ( eqvClass.data.kind == TypeDecl::Ttype ) {
    526                                         // expand ttype parameter into its actual type
    527                                         if ( eqvClass.type ) {
    528                                                 return eqvClass.type->clone();
    529                                         }
     527                        if ( const EqvClass *eqvClass = tenv.lookup( typeInst->get_name() ) ) {
     528                                // expand ttype parameter into its actual type
     529                                if ( eqvClass->data.kind == TypeDecl::Ttype && eqvClass->type ) {
     530                                        return eqvClass->type->clone();
    530531                                }
    531532                        }
Note: See TracChangeset for help on using the changeset viewer.