Changeset 86ad276 for src/Tuples


Ignore:
Timestamp:
Dec 5, 2017, 1:36:23 PM (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, resolv-new, stuck-waitfor-destruct, with_gc
Children:
12d2dc8
Parents:
f3b9efc (diff), 5da9d6a (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/Tuples
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/TupleAssignment.cc

    rf3b9efc r86ad276  
    2323
    2424#include "CodeGen/OperatorTable.h"
     25#include "Common/PassVisitor.h"
    2526#include "Common/UniqueName.h"             // for UniqueName
    2627#include "Common/utility.h"                // for zipWith
     
    6162                struct Matcher {
    6263                  public:
    63                         Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const 
     64                        Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const
    6465                                ResolvExpr::AltList& rhs );
    6566                        virtual ~Matcher() {}
     
    7576                struct MassAssignMatcher : public Matcher {
    7677                  public:
    77                         MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 
     78                        MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs,
    7879                                const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {}
    7980                        virtual void match( std::list< Expression * > &out );
     
    8283                struct MultipleAssignMatcher : public Matcher {
    8384                  public:
    84                         MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 
     85                        MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs,
    8586                                const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {}
    8687                        virtual void match( std::list< Expression * > &out );
     
    119120        }
    120121
    121         void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, 
     122        void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr,
    122123                                std::vector<ResolvExpr::AlternativeFinder> &args ) {
    123124                TupleAssignSpotter spotter( currentFinder );
     
    128129                : currentFinder(f) {}
    129130
    130         void TupleAssignSpotter::spot( UntypedExpr * expr, 
     131        void TupleAssignSpotter::spot( UntypedExpr * expr,
    131132                        std::vector<ResolvExpr::AlternativeFinder> &args ) {
    132133                if (  NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) {
     
    137138                                if ( args.size() == 0 ) return;
    138139
    139                                 // if an assignment only takes 1 argument, that's odd, but maybe someone wrote 
     140                                // if an assignment only takes 1 argument, that's odd, but maybe someone wrote
    140141                                // the function, in which case AlternativeFinder will handle it normally
    141142                                if ( args.size() == 1 && CodeGen::isAssignment( fname ) ) return;
     
    146147                                        if ( ! refToTuple(lhsAlt.expr) ) continue;
    147148
    148                                         // explode is aware of casts - ensure every LHS expression is sent into explode 
     149                                        // explode is aware of casts - ensure every LHS expression is sent into explode
    149150                                        // with a reference cast
    150                                         // xxx - this seems to change the alternatives before the normal 
     151                                        // xxx - this seems to change the alternatives before the normal
    151152                                        //  AlternativeFinder flow; maybe this is desired?
    152153                                        if ( ! dynamic_cast<CastExpr*>( lhsAlt.expr ) ) {
    153                                                 lhsAlt.expr = new CastExpr( lhsAlt.expr, 
    154                                                                 new ReferenceType( Type::Qualifiers(), 
     154                                                lhsAlt.expr = new CastExpr( lhsAlt.expr,
     155                                                                new ReferenceType( Type::Qualifiers(),
    155156                                                                        lhsAlt.expr->get_result()->clone() ) );
    156157                                        }
     
    160161                                        explode( lhsAlt, currentFinder.get_indexer(), back_inserter(lhs), true );
    161162                                        for ( ResolvExpr::Alternative& alt : lhs ) {
    162                                                 // each LHS value must be a reference - some come in with a cast expression, 
     163                                                // each LHS value must be a reference - some come in with a cast expression,
    163164                                                // if not just cast to reference here
    164165                                                if ( ! dynamic_cast<ReferenceType*>( alt.expr->get_result() ) ) {
    165                                                         alt.expr = new CastExpr( alt.expr, 
    166                                                                 new ReferenceType( Type::Qualifiers(), 
     166                                                        alt.expr = new CastExpr( alt.expr,
     167                                                                new ReferenceType( Type::Qualifiers(),
    167168                                                                        alt.expr->get_result()->clone() ) );
    168169                                                }
     
    178179                                                // TODO build iterative version of this instead of using combos
    179180                                                std::vector< ResolvExpr::AltList > rhsAlts;
    180                                                 combos( std::next(args.begin(), 1), args.end(), 
     181                                                combos( std::next(args.begin(), 1), args.end(),
    181182                                                        std::back_inserter( rhsAlts ) );
    182183                                                for ( const ResolvExpr::AltList& rhsAlt : rhsAlts ) {
    183184                                                        // multiple assignment
    184185                                                        ResolvExpr::AltList rhs;
    185                                                         explode( rhsAlt, currentFinder.get_indexer(), 
     186                                                        explode( rhsAlt, currentFinder.get_indexer(),
    186187                                                                std::back_inserter(rhs), true );
    187188                                                        matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) );
     
    193194                                                        if ( isTuple(rhsAlt.expr) ) {
    194195                                                                // multiple assignment
    195                                                                 explode( rhsAlt, currentFinder.get_indexer(), 
     196                                                                explode( rhsAlt, currentFinder.get_indexer(),
    196197                                                                        std::back_inserter(rhs), true );
    197198                                                                matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) );
     
    222223                ResolvExpr::AltList current;
    223224                // now resolve new assignments
    224                 for ( std::list< Expression * >::iterator i = new_assigns.begin(); 
     225                for ( std::list< Expression * >::iterator i = new_assigns.begin();
    225226                                i != new_assigns.end(); ++i ) {
    226227                        PRINT(
     
    229230                        )
    230231
    231                         ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(), 
     232                        ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(),
    232233                                currentFinder.get_environ() };
    233234                        try {
     
    253254                // xxx -- was push_front
    254255                currentFinder.get_alternatives().push_back( ResolvExpr::Alternative(
    255                         new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, 
     256                        new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv,
    256257                        ResolvExpr::sumCost( current ) + matcher->baseCost ) );
    257258        }
    258259
    259         TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, 
    260                 const ResolvExpr::AltList &lhs, const ResolvExpr::AltList &rhs ) 
    261         : lhs(lhs), rhs(rhs), spotter(spotter), 
     260        TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter,
     261                const ResolvExpr::AltList &lhs, const ResolvExpr::AltList &rhs )
     262        : lhs(lhs), rhs(rhs), spotter(spotter),
    262263          baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) {
    263264                simpleCombineEnvironments( lhs.begin(), lhs.end(), compositeEnv );
     
    277278        // xxx - maybe this should happen in alternative finder for every StmtExpr?
    278279        // xxx - it's possible that these environments could contain some useful information. Maybe the right thing to do is aggregate the environments and pass the aggregate back to be added into the compositeEnv
    279         struct EnvRemover : public Visitor {
    280                 virtual void visit( ExprStmt * stmt ) {
    281                         delete stmt->get_expr()->get_env();
    282                         stmt->get_expr()->set_env( nullptr );
    283                         Visitor::visit( stmt );
     280        struct EnvRemover {
     281                void previsit( ExprStmt * stmt ) {
     282                        delete stmt->expr->env;
     283                        stmt->expr->env = nullptr;
    284284                }
    285285        };
     
    293293                        ret->set_init( ctorInit );
    294294                        ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
    295                         EnvRemover rm; // remove environments from subexpressions of StmtExprs
     295                        PassVisitor<EnvRemover> rm; // remove environments from subexpressions of StmtExprs
    296296                        ctorInit->accept( rm );
    297297                }
  • src/Tuples/TupleExpansion.cc

    rf3b9efc r86ad276  
    315315        namespace {
    316316                /// determines if impurity (read: side-effects) may exist in a piece of code. Currently gives a very crude approximation, wherein any function call expression means the code may be impure
    317                 class ImpurityDetector : public Visitor {
    318                 public:
     317                struct ImpurityDetector : public WithShortCircuiting {
    319318                        ImpurityDetector( bool ignoreUnique ) : ignoreUnique( ignoreUnique ) {}
    320319
    321                         typedef Visitor Parent;
    322                         virtual void visit( ApplicationExpr * appExpr ) {
     320                        void previsit( ApplicationExpr * appExpr ) {
     321                                visit_children = false;
    323322                                if ( DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) {
    324323                                        if ( function->get_linkage() == LinkageSpec::Intrinsic ) {
    325324                                                if ( function->get_name() == "*?" || function->get_name() == "?[?]" ) {
    326325                                                        // intrinsic dereference, subscript are pure, but need to recursively look for impurity
    327                                                         Parent::visit( appExpr );
     326                                                        visit_children = true;
    328327                                                        return;
    329328                                                }
     
    332331                                maybeImpure = true;
    333332                        }
    334                         virtual void visit( UntypedExpr * ) { maybeImpure = true; }
    335                         virtual void visit( UniqueExpr * unq ) {
     333                        void previsit( UntypedExpr * ) { maybeImpure = true; visit_children = false; }
     334                        void previsit( UniqueExpr * ) {
    336335                                if ( ignoreUnique ) {
    337336                                        // bottom out at unique expression.
    338337                                        // The existence of a unique expression doesn't change the purity of an expression.
    339338                                        // That is, even if the wrapped expression is impure, the wrapper protects the rest of the expression.
     339                                        visit_children = false;
    340340                                        return;
    341341                                }
    342                                 maybeAccept( unq->expr, *this );
    343342                        }
    344343
     
    349348
    350349        bool maybeImpure( Expression * expr ) {
    351                 ImpurityDetector detector( false );
     350                PassVisitor<ImpurityDetector> detector( false );
    352351                expr->accept( detector );
    353                 return detector.maybeImpure;
     352                return detector.pass.maybeImpure;
    354353        }
    355354
    356355        bool maybeImpureIgnoreUnique( Expression * expr ) {
    357                 ImpurityDetector detector( true );
     356                PassVisitor<ImpurityDetector> detector( true );
    358357                expr->accept( detector );
    359                 return detector.maybeImpure;
     358                return detector.pass.maybeImpure;
    360359        }
    361360} // namespace Tuples
Note: See TracChangeset for help on using the changeset viewer.