Changeset cac8a6e for src/ResolvExpr


Ignore:
Timestamp:
May 22, 2018, 11:08:22 AM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
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, with_gc
Children:
639991a
Parents:
4a333d35 (diff), 2f0a0678 (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:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/ResolvExpr
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r4a333d35 rcac8a6e  
    12851285                AlternativeFinder finder( indexer, env );
    12861286                finder.targetType = toType;
    1287                 finder.findWithAdjustment( castExpr->get_arg() );
     1287                finder.findWithAdjustment( castExpr->arg );
    12881288
    12891289                AltList candidates;
     
    12961296                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    12971297                        // to.
    1298                         int discardedValues = alt.expr->get_result()->size() - castExpr->get_result()->size();
     1298                        int discardedValues = alt.expr->result->size() - castExpr->result->size();
    12991299                        if ( discardedValues < 0 ) continue;
    13001300                        // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
    13011301                        // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
    13021302                        // unification run for side-effects
    1303                         unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions,
     1303                        unify( castExpr->result, alt.expr->result, alt.env, needAssertions,
    13041304                                haveAssertions, openVars, indexer );
    1305                         Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer,
     1305                        Cost thisCost = castCost( alt.expr->result, castExpr->result, indexer,
    13061306                                alt.env );
    13071307                        PRINT(
     
    17261726                                // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
    17271727                                // unification run for side-effects
    1728                                 unify( toType, alt.expr->get_result(), newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type??
     1728                                unify( toType, alt.expr->result, newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type??
    17291729
    17301730                                Cost thisCost = castCost( alt.expr->get_result(), toType, indexer, newEnv );
  • src/ResolvExpr/Resolver.cc

    r4a333d35 rcac8a6e  
    127127
    128128        namespace {
    129                 void finishExpr( Expression *expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
     129                struct StripCasts {
     130                        Expression * postmutate( CastExpr * castExpr ) {
     131                                if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) {
     132                                        // generated cast is to the same type as its argument, so it's unnecessary -- remove it
     133                                        Expression * expr = castExpr->arg;
     134                                        castExpr->arg = nullptr;
     135                                        std::swap( expr->env, castExpr->env );
     136                                        return expr;
     137                                }
     138                                return castExpr;
     139                        }
     140
     141                        static void strip( Expression *& expr ) {
     142                                PassVisitor<StripCasts> stripper;
     143                                expr = expr->acceptMutator( stripper );
     144                        }
     145                };
     146
     147                void finishExpr( Expression *&expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
    130148                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    131                         env.makeSubstitution( *expr->get_env() );
     149                        env.makeSubstitution( *expr->env );
     150                        StripCasts::strip( expr ); // remove unnecessary casts that may be buried in an expression
    132151                }
    133152
     
    414433
    415434        void Resolver::previsit( CaseStmt *caseStmt ) {
    416                 if ( caseStmt->get_condition() ) {
     435                if ( caseStmt->condition ) {
    417436                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    418437                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
     
    420439                        Expression * newExpr = new CastExpr( caseStmt->condition, initAlts.front().type->clone() );
    421440                        findSingleExpression( newExpr, indexer );
    422                         CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
    423                         caseStmt->condition = castExpr->arg;
    424                         castExpr->arg = nullptr;
    425                         delete castExpr;
     441                        // case condition cannot have a cast in C, so it must be removed, regardless of whether it performs a conversion.
     442                        // Ideally we would perform the conversion internally here.
     443                        if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( newExpr ) ) {
     444                                newExpr = castExpr->arg;
     445                                castExpr->arg = nullptr;
     446                                std::swap( newExpr->env, castExpr->env );
     447                                delete castExpr;
     448                        }
     449                        caseStmt->condition = newExpr;
    426450                }
    427451        }
     
    718742                initExpr->expr = nullptr;
    719743                std::swap( initExpr->env, newExpr->env );
    720                 std::swap( initExpr->inferParams, newExpr->inferParams ) ;
     744                // InitExpr may have inferParams in the case where the expression specializes a function pointer,
     745                // and newExpr may already have inferParams of its own, so a simple swap is not sufficient.
     746                newExpr->spliceInferParams( initExpr );
    721747                delete initExpr;
    722748
  • src/ResolvExpr/TypeEnvironment.h

    r4a333d35 rcac8a6e  
    3737        //
    3838        // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.
     39        //
     40        // Note: since this compares pointers for position, minor changes in the source file that affect
     41        // memory layout can alter compilation time in unpredictable ways. For example, the placement
     42        // of a line directive can reorder type pointers with respect to each other so that assertions
     43        // are seen in different orders, causing a potentially different number of unification calls when
     44        // resolving assertions. I've seen a TU go from 36 seconds to 27 seconds by reordering line directives
     45        // alone, so it would be nice to fix this comparison so that assertions compare more consistently.
     46        // I've tried to modify this to compare on mangle name instead of type as the second comparator, but
     47        // this causes some assertions to never be recorded. More investigation is needed.
    3948        struct AssertCompare {
    4049                bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const {
  • src/ResolvExpr/Unify.cc

    r4a333d35 rcac8a6e  
    324324                } else if ( isopen1 ) {
    325325                        result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    326                 } else if ( isopen2 ) {
     326                } else if ( isopen2 ) { // TODO: swap widenMode values in call, since type positions are flipped?
    327327                        result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    328328                } else {
Note: See TracChangeset for help on using the changeset viewer.