Changeset 90152a4 for src/Tuples


Ignore:
Timestamp:
Aug 27, 2018, 4:40:34 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
Children:
b7c89aa
Parents:
f9feab8 (diff), 305581d (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' into cleanup-dtors

Location:
src/Tuples
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/Explode.h

    rf9feab8 r90152a4  
    4343        /// Append alternative to an OutputIterator of Alternatives
    4444        template<typename OutputIterator>
    45         void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env, 
     45        void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env,
    4646                        const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) {
    4747                *out++ = ResolvExpr::Alternative{ expr, env, cost, cvtCost };
     
    4949
    5050        /// Append alternative to an ExplodedActual
    51         static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr, 
     51        static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr,
    5252                        const ResolvExpr::TypeEnvironment&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
    5353                ea.exprs.emplace_back( expr );
     
    5757        /// helper function used by explode
    5858        template< typename Output >
    59         void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, 
     59        void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt,
    6060                        const SymTab::Indexer & indexer, Output&& out, bool isTupleAssign ) {
    6161                if ( isTupleAssign ) {
     
    6363                        if ( CastExpr * castExpr = isReferenceCast( expr ) ) {
    6464                                ResolvExpr::AltList alts;
    65                                 explodeUnique( 
     65                                explodeUnique(
    6666                                        castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
    6767                                for ( ResolvExpr::Alternative & alt : alts ) {
    6868                                        // distribute reference cast over all components
    69                                         append( std::forward<Output>(out), distributeReference( alt.release_expr() ), 
     69                                        append( std::forward<Output>(out), distributeReference( alt.release_expr() ),
    7070                                                alt.env, alt.cost, alt.cvtCost );
    7171                                }
     
    108108        /// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type
    109109        template< typename Output >
    110         void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, 
     110        void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer,
    111111                        Output&& out, bool isTupleAssign = false ) {
    112112                explodeUnique( alt.expr, alt, indexer, std::forward<Output>(out), isTupleAssign );
     
    115115        // explode list of alternatives
    116116        template< typename AltIterator, typename Output >
    117         void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, 
     117        void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer,
    118118                        Output&& out, bool isTupleAssign = false ) {
    119119                for ( ; altBegin != altEnd; ++altBegin ) {
     
    123123
    124124        template< typename Output >
    125         void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, Output&& out, 
     125        void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, Output&& out,
    126126                        bool isTupleAssign = false ) {
    127127                explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign );
  • src/Tuples/TupleAssignment.cc

    rf9feab8 r90152a4  
    154154                                                lhsAlt.expr = new CastExpr( lhsAlt.expr,
    155155                                                                new ReferenceType( Type::Qualifiers(),
    156                                                                         lhsAlt.expr->get_result()->clone() ) );
     156                                                                        lhsAlt.expr->result->clone() ) );
    157157                                        }
    158158
     
    231231
    232232                        ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(),
    233                                 currentFinder.get_environ() };
     233                                matcher->compositeEnv };
     234
    234235                        try {
    235236                                finder.findWithAdjustment(*i);
     
    272273                // args.push_back( new AddressExpr( new VariableExpr( left ) ) );
    273274                if ( right ) args.push_back( new VariableExpr( right ) );
    274                 return new UntypedExpr( new NameExpr( fname ), args );
    275         }
    276 
    277         // removes environments from subexpressions within statement exprs, which could throw off later passes like those in Box which rely on PolyMutator.
     275                if ( left->type->referenceDepth() > 1 && CodeGen::isConstructor( fname ) ) {
     276                        args.front() = new AddressExpr( args.front() );
     277                        if ( right ) args.back() = new AddressExpr( args.back() );
     278                        return new UntypedExpr( new NameExpr( "?=?" ), args );
     279                } else {
     280                        return new UntypedExpr( new NameExpr( fname ), args );
     281                }
     282        }
     283
     284        // removes environments from subexpressions within statement exprs, which could throw off later passes like those in Box which rely on PolyMutator, and adds the bindings to the compositeEnv
    278285        // xxx - maybe this should happen in alternative finder for every StmtExpr?
    279         // 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
    280286        struct EnvRemover {
    281287                void previsit( ExprStmt * stmt ) {
    282                         delete stmt->expr->env;
    283                         stmt->expr->env = nullptr;
    284                 }
     288                        assert( compositeEnv );
     289                        if ( stmt->expr->env ) {
     290                                compositeEnv->add( *stmt->expr->env );
     291                                delete stmt->expr->env;
     292                                stmt->expr->env = nullptr;
     293                        }
     294                }
     295
     296                ResolvExpr::TypeEnvironment * compositeEnv = nullptr;
    285297        };
    286298
    287299        ObjectDecl * TupleAssignSpotter::Matcher::newObject( UniqueName & namer, Expression * expr ) {
    288300                assert( expr->result && ! expr->get_result()->isVoid() );
    289                 ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) );
     301                ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->result->clone(), new SingleInit( expr->clone() ) );
    290302                // if expression type is a reference, don't need to construct anything, a simple initializer is sufficient.
    291                 if ( ! dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
     303                if ( ! dynamic_cast< ReferenceType * >( expr->result ) ) {
    292304                        ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
    293                         ret->set_init( ctorInit );
     305                        ret->init = ctorInit;
    294306                        ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
    295307                        PassVisitor<EnvRemover> rm; // remove environments from subexpressions of StmtExprs
     308                        rm.pass.compositeEnv = &compositeEnv;
    296309                        ctorInit->accept( rm );
    297310                }
     
    306319                assert( (! lhs.empty() && rhs.size() <= 1) || (lhs.empty() && rhs.empty()) );
    307320
     321                // xxx - may need to split this up into multiple declarations, because potential conversion to references
     322                //  probably should not reference local variable - see MultipleAssignMatcher::match
    308323                ObjectDecl * rtmp = rhs.size() == 1 ? newObject( rhsNamer, rhs.front().expr ) : nullptr;
    309324                for ( ResolvExpr::Alternative & lhsAlt : lhs ) {
     
    324339                        std::list< ObjectDecl * > ltmp;
    325340                        std::list< ObjectDecl * > rtmp;
    326                         std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), [&]( ResolvExpr::Alternative & alt ){
    327                                 return newObject( lhsNamer, alt.expr );
    328                         });
    329                         std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), [&]( ResolvExpr::Alternative & alt ){
    330                                 return newObject( rhsNamer, alt.expr );
    331                         });
    332                         zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), [&](ObjectDecl * obj1, ObjectDecl * obj2 ) { return createFunc(spotter.fname, obj1, obj2); } );
     341                        for ( auto p : group_iterate( lhs, rhs ) ) {
     342                                ResolvExpr::Alternative & lhsAlt = std::get<0>(p);
     343                                ResolvExpr::Alternative & rhsAlt = std::get<1>(p);
     344                                // convert RHS to LHS type minus one reference -- important for the case where LHS is && and RHS is lvalue, etc.
     345                                ReferenceType * lhsType = strict_dynamic_cast<ReferenceType *>( lhsAlt.expr->result );
     346                                rhsAlt.expr = new CastExpr( rhsAlt.expr, lhsType->base->clone() );
     347                                ObjectDecl * lobj = newObject( lhsNamer, lhsAlt.expr );
     348                                ObjectDecl * robj = newObject( rhsNamer, rhsAlt.expr );
     349                                out.push_back( createFunc(spotter.fname, lobj, robj) );
     350                                ltmp.push_back( lobj );
     351                                rtmp.push_back( robj );
     352
     353                                // resolve the cast expression so that rhsAlt return type is bound by the cast type as needed, and transfer the resulting environment
     354                                ResolvExpr::AlternativeFinder finder{ spotter.currentFinder.get_indexer(), compositeEnv };
     355                                finder.findWithAdjustment( rhsAlt.expr );
     356                                assert( finder.get_alternatives().size() == 1 );
     357                                compositeEnv = std::move( finder.get_alternatives().front().env );
     358                        }
    333359                        tmpDecls.splice( tmpDecls.end(), ltmp );
    334360                        tmpDecls.splice( tmpDecls.end(), rtmp );
  • src/Tuples/TupleExpansion.cc

    rf9feab8 r90152a4  
    3030#include "SynTree/Type.h"         // for Type, Type::Qualifiers, TupleType
    3131#include "SynTree/Visitor.h"      // for Visitor
     32#include "Tuples.h"
    3233
    3334class CompoundStmt;
     
    3637namespace Tuples {
    3738        namespace {
    38                 struct MemberTupleExpander final : public Mutator {
    39                         typedef Mutator Parent;
    40                         using Parent::mutate;
    41 
    42                         virtual Expression * mutate( UntypedMemberExpr * memberExpr ) override;
     39                struct MemberTupleExpander final : public WithShortCircuiting, public WithVisitorRef<MemberTupleExpander> {
     40                        void premutate( UntypedMemberExpr * ) { visit_children = false; }
     41                        Expression * postmutate( UntypedMemberExpr * memberExpr );
    4342                };
    4443
     
    7978
    8079        void expandMemberTuples( std::list< Declaration * > & translationUnit ) {
    81                 MemberTupleExpander expander;
     80                PassVisitor<MemberTupleExpander> expander;
    8281                mutateAll( translationUnit, expander );
    8382        }
     
    109108                                // construct a new UntypedMemberExpr with the correct structure , and recursively
    110109                                // expand that member expression.
    111                                 MemberTupleExpander expander;
    112                                 UntypedMemberExpr * inner = new UntypedMemberExpr( memberExpr->get_aggregate(), aggr->clone() );
    113                                 UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->get_member(), inner );
     110                                PassVisitor<MemberTupleExpander> expander;
     111                                UntypedMemberExpr * inner = new UntypedMemberExpr( memberExpr->aggregate, aggr->clone() );
     112                                UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->member, inner );
    114113                                inner->location = newMemberExpr->location = loc;
    115                                 memberExpr->set_member(nullptr);
    116                                 memberExpr->set_aggregate(nullptr);
     114                                memberExpr->member = nullptr;
     115                                memberExpr->aggregate = nullptr;
    117116                                delete memberExpr;
    118117                                return newMemberExpr->acceptMutator( expander );
     
    126125        }
    127126
    128         Expression * MemberTupleExpander::mutate( UntypedMemberExpr * memberExpr ) {
    129                 if ( UntypedTupleExpr * tupleExpr = dynamic_cast< UntypedTupleExpr * > ( memberExpr->get_member() ) ) {
    130                         Expression * aggr = memberExpr->get_aggregate()->clone()->acceptMutator( *this );
     127        Expression * MemberTupleExpander::postmutate( UntypedMemberExpr * memberExpr ) {
     128                if ( UntypedTupleExpr * tupleExpr = dynamic_cast< UntypedTupleExpr * > ( memberExpr->member ) ) {
     129                        Expression * aggr = memberExpr->aggregate->clone()->acceptMutator( *visitor );
    131130                        // aggregate expressions which might be impure must be wrapped in unique expressions
    132                         // xxx - if there's a member-tuple expression nested in the aggregate, this currently generates the wrong code if a UniqueExpr is not used, and it's purely an optimization to remove the UniqueExpr
    133                         // if ( Tuples::maybeImpureIgnoreUnique( memberExpr->get_aggregate() ) ) aggr = new UniqueExpr( aggr );
    134                         aggr = new UniqueExpr( aggr );
    135                         for ( Expression *& expr : tupleExpr->get_exprs() ) {
     131                        if ( Tuples::maybeImpureIgnoreUnique( memberExpr->aggregate ) ) aggr = new UniqueExpr( aggr );
     132                        for ( Expression *& expr : tupleExpr->exprs ) {
    136133                                expr = reconstructMemberExpr( expr, aggr, memberExpr->location );
    137134                                expr->location = memberExpr->location;
     
    143140                        // there may be a tuple expr buried in the aggregate
    144141                        // xxx - this is a memory leak
    145                         UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->get_member()->clone(), memberExpr->get_aggregate()->acceptMutator( *this ) );
     142                        UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->member->clone(), memberExpr->aggregate->acceptMutator( *visitor ) );
    146143                        newMemberExpr->location = memberExpr->location;
    147144                        return newMemberExpr;
     
    202199                        // generate struct type to replace tuple type based on the number of components in the tuple
    203200                        StructDecl * decl = new StructDecl( toString( "_tuple", tupleSize, "_" ) );
     201                        decl->location = tupleType->location;
    204202                        decl->set_body( true );
    205203                        for ( size_t i = 0; i < tupleSize; ++i ) {
     
    228226
    229227        Expression * TupleIndexExpander::postmutate( TupleIndexExpr * tupleExpr ) {
    230                 Expression * tuple = tupleExpr->get_tuple();
     228                Expression * tuple = tupleExpr->tuple;
    231229                assert( tuple );
    232                 tupleExpr->set_tuple( nullptr );
    233                 unsigned int idx = tupleExpr->get_index();
    234                 TypeSubstitution * env = tupleExpr->get_env();
    235                 tupleExpr->set_env( nullptr );
     230                tupleExpr->tuple = nullptr;
     231                unsigned int idx = tupleExpr->index;
     232                TypeSubstitution * env = tupleExpr->env;
     233                tupleExpr->env = nullptr;
    236234                delete tupleExpr;
    237235
    238                 StructInstType * type = strict_dynamic_cast< StructInstType * >( tuple->get_result() );
    239                 StructDecl * structDecl = type->get_baseStruct();
    240                 assert( structDecl->get_members().size() > idx );
    241                 Declaration * member = *std::next(structDecl->get_members().begin(), idx);
     236                if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * > ( tuple ) ) {
     237                        if ( ! maybeImpureIgnoreUnique( tupleExpr ) ) {
     238                                // optimization: definitely pure tuple expr => can reduce to the only relevant component.
     239                                assert( tupleExpr->exprs.size() > idx );
     240                                Expression *& expr = *std::next(tupleExpr->exprs.begin(), idx);
     241                                Expression * ret = expr;
     242                                ret->env = env;
     243                                expr = nullptr; // remove from list so it can safely be deleted
     244                                delete tupleExpr;
     245                                return ret;
     246                        }
     247                }
     248
     249                StructInstType * type = strict_dynamic_cast< StructInstType * >( tuple->result );
     250                StructDecl * structDecl = type->baseStruct;
     251                assert( structDecl->members.size() > idx );
     252                Declaration * member = *std::next(structDecl->members.begin(), idx);
    242253                MemberExpr * memExpr = new MemberExpr( strict_dynamic_cast< DeclarationWithType * >( member ), tuple );
    243                 memExpr->set_env( env );
     254                memExpr->env = env;
    244255                return memExpr;
    245256        }
Note: See TracChangeset for help on using the changeset viewer.