Ignore:
Timestamp:
Jan 23, 2018, 5:46:43 PM (8 years ago)
Author:
Alan Kennedy <afakenne@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
258e6ad5
Parents:
b158d8f (diff), 15d248e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

add context switch for ARM

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ConversionCost.cc

    rb158d8f rb6838214  
    4444                        EqvClass eqvClass;
    4545                        NamedTypeDecl *namedType;
    46                         PRINT( std::cerr << "type inst " << destAsTypeInst->get_name(); )
    47                         if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
     46                        PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
     47                        if ( env.lookup( destAsTypeInst->name, eqvClass ) ) {
    4848                                if ( eqvClass.type ) {
    4949                                        return conversionCost( src, eqvClass.type, indexer, env );
     
    5151                                        return Cost::infinity;
    5252                                }
    53                         } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
     53                        } else if ( ( namedType = indexer.lookupType( destAsTypeInst->name ) ) ) {
    5454                                PRINT( std::cerr << " found" << std::endl; )
    5555                                TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    5656                                // all typedefs should be gone by this point
    5757                                assert( type );
    58                                 if ( type->get_base() ) {
    59                                         return conversionCost( src, type->get_base(), indexer, env ) + Cost::safe;
     58                                if ( type->base ) {
     59                                        return conversionCost( src, type->base, indexer, env ) + Cost::safe;
    6060                                } // if
    6161                        } // if
     
    7777                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    7878                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    79                         return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const TypeEnvironment & env, const SymTab::Indexer &){
     79                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
    8080                                return ptrsAssignable( t1, t2, env );
    8181                        });
    8282                } else {
    83                         ConversionCost converter( dest, indexer, env );
     83                        PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
    8484                        src->accept( converter );
    85                         if ( converter.get_cost() == Cost::infinity ) {
     85                        if ( converter.pass.get_cost() == Cost::infinity ) {
    8686                                return Cost::infinity;
    8787                        } else {
    88                                 return converter.get_cost() + Cost::zero;
     88                                return converter.pass.get_cost() + Cost::zero;
    8989                        } // if
    9090                } // if
     
    9292
    9393        Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    94                 PRINT( std::cerr << "convert to reference cost... diff " << diff << std::endl; )
     94                PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
    9595                if ( diff > 0 ) {
    9696                        // TODO: document this
    97                         Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->get_base(), dest, diff-1, indexer, env, func );
     97                        Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
    9898                        cost.incReference();
    9999                        return cost;
    100100                } else if ( diff < -1 ) {
    101101                        // TODO: document this
    102                         Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->get_base(), diff+1, indexer, env, func );
     102                        Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
    103103                        cost.incReference();
    104104                        return cost;
     
    108108                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
    109109                                PRINT( std::cerr << "converting between references" << std::endl; )
    110                                 if ( srcAsRef->get_base()->get_qualifiers() <= destAsRef->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), destAsRef->get_base(), indexer, env ) ) {
    111                                         return Cost::safe;
     110                                Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
     111                                Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
     112                                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
     113                                        PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     114                                        if ( tq1 == tq2 ) {
     115                                                // types are the same
     116                                                return Cost::zero;
     117                                        } else {
     118                                                // types are the same, except otherPointer has more qualifiers
     119                                                return Cost::safe;
     120                                        }
    112121                                } else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    113                                         int assignResult = func( srcAsRef->get_base(), destAsRef->get_base(), env, indexer );
     122                                        int assignResult = func( srcAsRef->base, destAsRef->base, indexer, env );
    114123                                        PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
    115124                                        if ( assignResult > 0 ) {
     
    121130                        } else {
    122131                                PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
    123                                 ConversionCost converter( dest, indexer, env );
     132                                PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
    124133                                src->accept( converter );
    125                                 return converter.get_cost();
     134                                return converter.pass.get_cost();
    126135                        } // if
    127136                } else {
     
    129138                        assert( diff == -1 && destAsRef );
    130139                        PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
    131                         if ( typesCompatibleIgnoreQualifiers( src, destAsRef->get_base(), indexer, env ) ) {
     140                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
    132141                                PRINT( std::cerr << "converting compatible base type" << std::endl; )
    133142                                if ( src->get_lvalue() ) {
     
    137146                                        )
    138147                                        // lvalue-to-reference conversion:  cv lvalue T => cv T &
    139                                         if ( src->get_qualifiers() == destAsRef->get_base()->get_qualifiers() ) {
     148                                        if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
    140149                                                return Cost::reference; // cost needs to be non-zero to add cast
    141                                         } if ( src->get_qualifiers() < destAsRef->get_base()->get_qualifiers() ) {
     150                                        } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
    142151                                                return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
    143152                                        } else {
    144153                                                return Cost::unsafe;
    145154                                        } // if
    146                                 } else if ( destAsRef->get_base()->get_const() ) {
     155                                } else if ( destAsRef->base->get_const() ) {
    147156                                        PRINT( std::cerr << "rvalue to const ref conversion" << std::endl; )
    148157                                        // rvalue-to-const-reference conversion: T => const T &
     
    164173        }
    165174
    166         ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
    167                 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ) {
     175        ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     176                : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
    168177        }
    169178
     
    248257        };
    249258
    250         void ConversionCost::visit( __attribute((unused)) VoidType *voidType ) {
     259        void ConversionCost::postvisit( VoidType * ) {
    251260                cost = Cost::infinity;
    252261        }
    253262
    254         void ConversionCost::visit(BasicType *basicType) {
     263        void ConversionCost::postvisit(BasicType *basicType) {
    255264                if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    256265                        int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
     
    269278        }
    270279
    271         void ConversionCost::visit( PointerType * pointerType ) {
     280        void ConversionCost::postvisit( PointerType * pointerType ) {
    272281                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    273                         PRINT( std::cerr << pointerType << " ===> " << destAsPtr; )
    274                         Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers();
    275                         Type::Qualifiers tq2 = destAsPtr->get_base()->get_qualifiers();
    276                         if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
     282                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
     283                        Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
     284                        Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
     285                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
     286                                PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
    277287                                if ( tq1 == tq2 ) {
    278288                                        // types are the same
     
    280290                                } else {
    281291                                        // types are the same, except otherPointer has more qualifiers
    282                                         PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
    283292                                        cost = Cost::safe;
    284293                                }
    285                         } else {  // xxx - this discards qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
     294                        } else {
    286295                                int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
    287296                                PRINT( std::cerr << " :: " << assignResult << std::endl; )
    288                                 if ( assignResult > 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) {
    289                                         cost = Cost::safe;
     297                                if ( assignResult > 0 && tq1 <= tq2 ) {
     298                                        // xxx - want the case where qualifiers are added to be more expensive than the case where qualifiers are the same. Is 1 safe vs. 2 safe correct?
     299                                        if ( tq1 == tq2 ) {
     300                                                cost = Cost::safe;
     301                                        } else if ( tq1 < tq2 ) {
     302                                                cost = Cost::safe+Cost::safe;
     303                                        }
    290304                                } else if ( assignResult < 0 ) {
    291305                                        cost = Cost::unsafe;
     
    298312        }
    299313
    300         void ConversionCost::visit( ArrayType * ) {}
    301 
    302         void ConversionCost::visit( ReferenceType * refType ) {
     314        void ConversionCost::postvisit( ArrayType * ) {}
     315
     316        void ConversionCost::postvisit( ReferenceType * refType ) {
    303317                // Note: dest can never be a reference, since it would have been caught in an earlier check
    304318                assert( ! dynamic_cast< ReferenceType * >( dest ) );
     
    306320                // recursively compute conversion cost from T1 to T2.
    307321                // cv can be safely dropped because of 'implicit dereference' behavior.
    308                 refType->base->accept( *this );
     322                cost = costFunc( refType->base, dest, indexer, env );
    309323                if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
    310324                        cost.incReference();  // prefer exact qualifiers
     
    317331        }
    318332
    319         void ConversionCost::visit( FunctionType * ) {}
    320 
    321         void ConversionCost::visit( StructInstType * inst ) {
     333        void ConversionCost::postvisit( FunctionType * ) {}
     334
     335        void ConversionCost::postvisit( StructInstType * inst ) {
    322336                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    323337                        if ( inst->name == destAsInst->name ) {
     
    327341        }
    328342
    329         void ConversionCost::visit( UnionInstType * inst ) {
     343        void ConversionCost::postvisit( UnionInstType * inst ) {
    330344                if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
    331345                        if ( inst->name == destAsInst->name ) {
     
    335349        }
    336350
    337         void ConversionCost::visit( EnumInstType * ) {
     351        void ConversionCost::postvisit( EnumInstType * ) {
    338352                static Type::Qualifiers q;
    339353                static BasicType integer( q, BasicType::SignedInt );
    340                 integer.accept( *this );  // safe if dest >= int
     354                cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
    341355                if ( cost < Cost::unsafe ) {
    342356                        cost.incSafe();
     
    344358        }
    345359
    346         void ConversionCost::visit( TraitInstType * ) {}
    347 
    348         void ConversionCost::visit( TypeInstType *inst ) {
     360        void ConversionCost::postvisit( TraitInstType * ) {}
     361
     362        void ConversionCost::postvisit( TypeInstType *inst ) {
    349363                EqvClass eqvClass;
    350364                NamedTypeDecl *namedType;
    351                 if ( env.lookup( inst->get_name(), eqvClass ) ) {
    352                         cost = conversionCost( eqvClass.type, dest, indexer, env );
     365                if ( env.lookup( inst->name, eqvClass ) ) {
     366                        cost = costFunc( eqvClass.type, dest, indexer, env );
    353367                } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
    354                         if ( inst->get_name() == destAsInst->get_name() ) {
     368                        if ( inst->name == destAsInst->name ) {
    355369                                cost = Cost::zero;
    356370                        }
    357                 } else if ( ( namedType = indexer.lookupType( inst->get_name() ) ) ) {
     371                } else if ( ( namedType = indexer.lookupType( inst->name ) ) ) {
    358372                        TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    359373                        // all typedefs should be gone by this point
    360374                        assert( type );
    361                         if ( type->get_base() ) {
    362                                 cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost::safe;
    363                         } // if
    364                 } // if
    365         }
    366 
    367         void ConversionCost::visit( TupleType * tupleType ) {
     375                        if ( type->base ) {
     376                                cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
     377                        } // if
     378                } // if
     379        }
     380
     381        void ConversionCost::postvisit( TupleType * tupleType ) {
    368382                Cost c = Cost::zero;
    369383                if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
    370                         std::list< Type * >::const_iterator srcIt = tupleType->get_types().begin();
    371                         std::list< Type * >::const_iterator destIt = destAsTuple->get_types().begin();
    372                         while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
    373                                 Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
     384                        std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
     385                        std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
     386                        while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
     387                                Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
    374388                                if ( newCost == Cost::infinity ) {
    375389                                        return;
     
    377391                                c += newCost;
    378392                        } // while
    379                         if ( destIt != destAsTuple->get_types().end() ) {
     393                        if ( destIt != destAsTuple->types.end() ) {
    380394                                cost = Cost::infinity;
    381395                        } else {
     
    385399        }
    386400
    387         void ConversionCost::visit( VarArgsType * ) {
     401        void ConversionCost::postvisit( VarArgsType * ) {
    388402                if ( dynamic_cast< VarArgsType* >( dest ) ) {
    389403                        cost = Cost::zero;
     
    391405        }
    392406
    393         void ConversionCost::visit( ZeroType * ) {
     407        void ConversionCost::postvisit( ZeroType * ) {
    394408                if ( dynamic_cast< ZeroType * >( dest ) ) {
    395409                        cost = Cost::zero;
     
    408422        }
    409423
    410         void ConversionCost::visit( OneType * ) {
     424        void ConversionCost::postvisit( OneType * ) {
    411425                if ( dynamic_cast< OneType * >( dest ) ) {
    412426                        cost = Cost::zero;
Note: See TracChangeset for help on using the changeset viewer.