Ignore:
Timestamp:
Nov 10, 2021, 7:47:45 PM (3 years ago)
Author:
Fangren Yu <f37yu@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
Children:
3249dd8b
Parents:
1622af5 (diff), f95634e (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 'new-ast-unique-expr'

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/TupleExpansionNew.cpp

    r1622af5 rb7fd9daf  
    2121                void previsit( const ast::UntypedMemberExpr * ) { visit_children = false; }
    2222        const ast::Expr * postvisit( const ast::UntypedMemberExpr * memberExpr );
     23        };
     24        struct UniqueExprExpander final : public ast::WithDeclsToAdd<> {
     25                const ast::Expr * postvisit( const ast::UniqueExpr * unqExpr );
     26                std::map< int, ast::ptr<ast::Expr> > decls; // not vector, because order added may not be increasing order
    2327        };
    2428} // namespace
     
    6670        }
    6771} // namespace
     72
     73void expandUniqueExpr( ast::TranslationUnit & translationUnit ) {
     74        ast::Pass< UniqueExprExpander >::run( translationUnit );
     75}
     76
     77namespace {
     78        const ast::Expr * UniqueExprExpander::postvisit( const ast::UniqueExpr * unqExpr ) {
     79                const CodeLocation loc = unqExpr->location;
     80                const int id = unqExpr->id;
     81
     82                // on first time visiting a unique expr with a particular ID, generate the expression that replaces all UniqueExprs with that ID,
     83                // and lookup on subsequent hits. This ensures that all unique exprs with the same ID reference the same variable.
     84                if ( ! decls.count( id ) ) {
     85                        ast::ptr< ast::Expr > assignUnq;
     86                        const ast::VariableExpr * var = unqExpr->var;
     87                        if ( unqExpr->object ) {
     88                                // an object was generated to represent this unique expression -- it should be added to the list of declarations now
     89                                declsToAddBefore.push_back( unqExpr->object.as< ast::Decl >() );
     90                                // deep copy required due to unresolved issues with UniqueExpr
     91                                assignUnq = ast::UntypedExpr::createAssign( loc, var, unqExpr->expr );
     92                        } else {
     93                                const auto commaExpr = unqExpr->expr.strict_as< ast::CommaExpr >();
     94                                assignUnq = commaExpr->arg1;
     95                        }
     96                        auto finished = new ast::ObjectDecl( loc, toString( "_unq", id, "_finished_" ), new ast::BasicType( ast::BasicType::Kind::Bool ),
     97                                new ast::SingleInit( loc, ast::ConstantExpr::from_int( loc, 0 ) ), {}, ast::Linkage::Cforall );
     98                        declsToAddBefore.push_back( finished );
     99                        // (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N))
     100                        // This pattern ensures that each unique expression is evaluated once, regardless of evaluation order of the generated C code.
     101                        auto assignFinished = ast::UntypedExpr::createAssign( loc, new ast::VariableExpr( loc, finished ),
     102                                ast::ConstantExpr::from_int( loc, 1 ) );
     103                        auto condExpr = new ast::ConditionalExpr( loc, new ast::VariableExpr( loc, finished ), var,
     104                                new ast::CommaExpr( loc, new ast::CommaExpr( loc, assignUnq, assignFinished ), var ) );
     105                        condExpr->result = var->result;
     106                        condExpr->env = unqExpr->env;
     107                        decls[id] = condExpr;
     108                }
     109                //delete unqExpr;
     110                return ast::deepCopy(decls[id].get());
     111        }
     112} // namespace
    68113} // namespace Tuples
Note: See TracChangeset for help on using the changeset viewer.