Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/TupleExpansion.cc

    rbe9288a r9f10c4b8  
    1414//
    1515
    16 #include <stddef.h>               // for size_t
    17 #include <cassert>                // for assert
    18 #include <list>                   // for list
    19 
    20 #include "Common/PassVisitor.h"   // for PassVisitor, WithDeclsToAdd, WithGu...
    21 #include "Common/ScopedMap.h"     // for ScopedMap
    22 #include "Common/utility.h"       // for CodeLocation
    23 #include "GenPoly/DeclMutator.h"  // for DeclMutator
    24 #include "InitTweak/InitTweak.h"  // for getFunction
    25 #include "Parser/LinkageSpec.h"   // for Spec, C, Intrinsic
    26 #include "SynTree/Constant.h"     // for Constant
    27 #include "SynTree/Declaration.h"  // for StructDecl, DeclarationWithType
    28 #include "SynTree/Expression.h"   // for UntypedMemberExpr, Expression, Uniq...
    29 #include "SynTree/Label.h"        // for operator==, Label
    30 #include "SynTree/Mutator.h"      // for Mutator
    31 #include "SynTree/Type.h"         // for Type, Type::Qualifiers, TupleType
    32 #include "SynTree/Visitor.h"      // for Visitor
    33 
    34 class CompoundStmt;
    35 class TypeSubstitution;
     16#include <iterator>
     17#include <iostream>
     18#include <cassert>
     19#include "Tuples.h"
     20#include "Common/PassVisitor.h"
     21#include "Common/ScopedMap.h"
     22#include "GenPoly/DeclMutator.h"
     23#include "InitTweak/GenInit.h"
     24#include "InitTweak/InitTweak.h"
     25#include "ResolvExpr/typeops.h"
     26#include "SymTab/Mangler.h"
     27#include "SynTree/Declaration.h"
     28#include "SynTree/Expression.h"
     29#include "SynTree/Initializer.h"
     30#include "SynTree/Mutator.h"
     31#include "SynTree/Statement.h"
     32#include "SynTree/Type.h"
    3633
    3734namespace Tuples {
    3835        namespace {
    39                 class MemberTupleExpander final : public Mutator {
    40                 public:
     36                struct MemberTupleExpander final : public Mutator {
    4137                        typedef Mutator Parent;
    4238                        using Parent::mutate;
     
    4541                };
    4642
    47                 class UniqueExprExpander final : public GenPoly::DeclMutator {
    48                 public:
    49                         typedef GenPoly::DeclMutator Parent;
    50                         using Parent::mutate;
    51 
    52                         virtual Expression * mutate( UniqueExpr * unqExpr ) override;
     43                struct UniqueExprExpander final : public WithDeclsToAdd {
     44                        Expression * postmutate( UniqueExpr * unqExpr );
    5345
    5446                        std::map< int, Expression * > decls; // not vector, because order added may not be increasing order
     
    6153                };
    6254
    63                 class TupleAssignExpander : public Mutator {
    64                 public:
    65                         typedef Mutator Parent;
    66                         using Parent::mutate;
    67 
    68                         virtual Expression * mutate( TupleAssignExpr * tupleExpr );
     55                struct TupleAssignExpander {
     56                        Expression * postmutate( TupleAssignExpr * tupleExpr );
    6957                };
    7058
     
    7967                };
    8068
    81                 class TupleIndexExpander {
    82                 public:
     69                struct TupleIndexExpander {
    8370                        Expression * postmutate( TupleIndexExpr * tupleExpr );
    8471                };
    8572
    86                 class TupleExprExpander final : public Mutator {
    87                 public:
    88                         typedef Mutator Parent;
    89                         using Parent::mutate;
    90 
    91                         virtual Expression * mutate( TupleExpr * tupleExpr ) override;
     73                struct TupleExprExpander final {
     74                        Expression * postmutate( TupleExpr * tupleExpr );
    9275                };
    9376        }
     
    9982
    10083        void expandUniqueExpr( std::list< Declaration * > & translationUnit ) {
    101                 UniqueExprExpander unqExpander;
    102                 unqExpander.mutateDeclarationList( translationUnit );
     84                PassVisitor<UniqueExprExpander> unqExpander;
     85                mutateAll( translationUnit, unqExpander );
    10386        }
    10487
    10588        void expandTuples( std::list< Declaration * > & translationUnit ) {
    106                 TupleAssignExpander assnExpander;
     89                PassVisitor<TupleAssignExpander> assnExpander;
    10790                mutateAll( translationUnit, assnExpander );
    10891
     
    11396                mutateAll( translationUnit, idxExpander );
    11497
    115                 TupleExprExpander exprExpander;
     98                PassVisitor<TupleExprExpander> exprExpander;
    11699                mutateAll( translationUnit, exprExpander );
    117100        }
     
    146129                        // aggregate expressions which might be impure must be wrapped in unique expressions
    147130                        // 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
    148                         // if ( Tuples::maybeImpure( memberExpr->get_aggregate() ) ) aggr = new UniqueExpr( aggr );
     131                        // if ( Tuples::maybeImpureIgnoreUnique( memberExpr->get_aggregate() ) ) aggr = new UniqueExpr( aggr );
    149132                        aggr = new UniqueExpr( aggr );
    150133                        for ( Expression *& expr : tupleExpr->get_exprs() ) {
     
    164147        }
    165148
    166         Expression * UniqueExprExpander::mutate( UniqueExpr * unqExpr ) {
    167                 unqExpr = safe_dynamic_cast< UniqueExpr * > ( Parent::mutate( unqExpr ) );
     149        Expression * UniqueExprExpander::postmutate( UniqueExpr * unqExpr ) {
    168150                const int id = unqExpr->get_id();
    169151
     
    175157                        if ( unqExpr->get_object() ) {
    176158                                // an object was generated to represent this unique expression -- it should be added to the list of declarations now
    177                                 addDeclaration( unqExpr->get_object() );
     159                                declsToAddBefore.push_back( unqExpr->get_object() );
    178160                                unqExpr->set_object( nullptr );
    179161                                // steal the expr from the unqExpr
     
    189171                        ObjectDecl * finished = new ObjectDecl( toString( "_unq", id, "_finished_" ), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::Bool ),
    190172                                                                                                        new SingleInit( new ConstantExpr( Constant::from_int( 0 ) ) ) );
    191                         addDeclaration( finished );
     173                        declsToAddBefore.push_back( finished );
    192174                        // (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N))
    193175                        // This pattern ensures that each unique expression is evaluated once, regardless of evaluation order of the generated C code.
     
    203185        }
    204186
    205         Expression * TupleAssignExpander::mutate( TupleAssignExpr * assnExpr ) {
    206                 assnExpr = safe_dynamic_cast< TupleAssignExpr * >( Parent::mutate( assnExpr ) );
     187        Expression * TupleAssignExpander::postmutate( TupleAssignExpr * assnExpr ) {
    207188                StmtExpr * ret = assnExpr->get_stmtExpr();
    208189                assnExpr->set_stmtExpr( nullptr );
     
    238219                for ( auto p : group_iterate( tupleType->get_types(), decl->get_parameters() ) ) {
    239220                        Type * t = std::get<0>(p);
    240                         TypeDecl * td = std::get<1>(p);
    241221                        newType->get_parameters().push_back( new TypeExpr( t->clone() ) );
    242                         if ( env ) {
    243                                 // add bindings to the type environment.
    244                                 // xxx - This may not be sufficient, it may be necessary to rename type variables on StructInstType?
    245                                 env->add( td->get_name(), t->clone() );
    246                         }
    247222                }
    248223                delete tupleType;
     
    293268        }
    294269
    295         Expression * TupleExprExpander::mutate( TupleExpr * tupleExpr ) {
    296                 // recursively expand sub-tuple-expressions
    297                 tupleExpr = safe_dynamic_cast<TupleExpr *>(Parent::mutate(tupleExpr));
     270        Expression * TupleExprExpander::postmutate( TupleExpr * tupleExpr ) {
    298271                Type * result = tupleExpr->get_result();
    299272                std::list< Expression * > exprs = tupleExpr->get_exprs();
     
    342315                class ImpurityDetector : public Visitor {
    343316                public:
     317                        ImpurityDetector( bool ignoreUnique ) : ignoreUnique( ignoreUnique ) {}
     318
    344319                        typedef Visitor Parent;
    345320                        virtual void visit( ApplicationExpr * appExpr ) {
     
    355330                                maybeImpure = true;
    356331                        }
    357                         virtual void visit( __attribute__((unused)) UntypedExpr * untypedExpr ) { maybeImpure = true; }
     332                        virtual void visit( UntypedExpr * ) { maybeImpure = true; }
     333                        virtual void visit( UniqueExpr * unq ) {
     334                                if ( ignoreUnique ) {
     335                                        // bottom out at unique expression.
     336                                        // The existence of a unique expression doesn't change the purity of an expression.
     337                                        // That is, even if the wrapped expression is impure, the wrapper protects the rest of the expression.
     338                                        return;
     339                                }
     340                                maybeAccept( unq->expr, *this );
     341                        }
     342
    358343                        bool maybeImpure = false;
     344                        bool ignoreUnique;
    359345                };
    360346        } // namespace
    361347
    362348        bool maybeImpure( Expression * expr ) {
    363                 ImpurityDetector detector;
     349                ImpurityDetector detector( false );
     350                expr->accept( detector );
     351                return detector.maybeImpure;
     352        }
     353
     354        bool maybeImpureIgnoreUnique( Expression * expr ) {
     355                ImpurityDetector detector( true );
    364356                expr->accept( detector );
    365357                return detector.maybeImpure;
Note: See TracChangeset for help on using the changeset viewer.