- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/TupleExpansionNew.cpp
rd249e0b rbb9924c 8 8 // 9 9 // Author : Henry Xue 10 // Created On : Mon Aug 23 15:36:09202110 // Created On : Wed Aug 18 12:54:02 2021 11 11 // Last Modified By : Henry Xue 12 // Last Modified On : Mon Aug 23 15:36:09202112 // Last Modified On : Wed Aug 18 12:54:02 2021 13 13 // Update Count : 1 14 14 // 15 16 // Currently not working due to unresolved issues with UniqueExpr 15 17 16 18 #include "Tuples.h" … … 18 20 namespace Tuples { 19 21 namespace { 20 struct MemberTupleExpander final : public ast::WithShortCircuiting, public ast::WithVisitorRef< MemberTupleExpander> {21 void previsit( const ast::UntypedMemberExpr * ) { visit_children = false; }22 const ast::Expr * postvisit( const ast::UntypedMemberExpr * memberExpr ); 22 struct UniqueExprExpander final : public ast::WithDeclsToAdd<> { 23 const ast::Expr * postvisit( const ast::UniqueExpr * unqExpr ); 24 std::map< int, ast::ptr<ast::Expr> > decls; // not vector, because order added may not be increasing order 23 25 }; 24 26 } // namespace 25 27 26 void expand MemberTuples( ast::TranslationUnit & translationUnit ) {27 ast::Pass< MemberTupleExpander >::run( translationUnit );28 void expandUniqueExpr( ast::TranslationUnit & translationUnit ) { 29 ast::Pass< UniqueExprExpander >::run( translationUnit ); 28 30 } 29 31 30 32 namespace { 31 namespace { 32 /// given a expression representing the member and an expression representing the aggregate, 33 /// reconstructs a flattened UntypedMemberExpr with the right precedence 34 const ast::Expr * reconstructMemberExpr( const ast::Expr * member, const ast::Expr * aggr, const CodeLocation & loc ) { 35 if ( auto memberExpr = dynamic_cast< const ast::UntypedMemberExpr * >( member ) ) { 36 // construct a new UntypedMemberExpr with the correct structure , and recursively 37 // expand that member expression. 38 ast::Pass< MemberTupleExpander > expander; 39 auto inner = new ast::UntypedMemberExpr( loc, memberExpr->aggregate, aggr ); 40 auto newMemberExpr = new ast::UntypedMemberExpr( loc, memberExpr->member, inner ); 41 //delete memberExpr; 42 return newMemberExpr->accept( expander ); 33 const ast::Expr * UniqueExprExpander::postvisit( const ast::UniqueExpr * unqExpr ) { 34 const CodeLocation loc = unqExpr->location; 35 const int id = unqExpr->id; 36 37 // on first time visiting a unique expr with a particular ID, generate the expression that replaces all UniqueExprs with that ID, 38 // and lookup on subsequent hits. This ensures that all unique exprs with the same ID reference the same variable. 39 if ( ! decls.count( id ) ) { 40 ast::ptr< ast::Expr > assignUnq; 41 const ast::VariableExpr * var = unqExpr->var; 42 if ( unqExpr->object ) { 43 // an object was generated to represent this unique expression -- it should be added to the list of declarations now 44 declsToAddBefore.push_back( unqExpr->object.as< ast::Decl >() ); 45 // deep copy required due to unresolved issues with UniqueExpr 46 assignUnq = ast::UntypedExpr::createAssign( loc, var, unqExpr->expr ); 43 47 } else { 44 // not a member expression, so there is nothing to do but attach and return45 return new ast::UntypedMemberExpr( loc, member, aggr );48 const auto commaExpr = unqExpr->expr.strict_as< ast::CommaExpr >(); 49 assignUnq = commaExpr->arg1; 46 50 } 51 auto finished = new ast::ObjectDecl( loc, toString( "_unq", id, "_finished_" ), new ast::BasicType( ast::BasicType::Kind::Bool ), 52 new ast::SingleInit( loc, ast::ConstantExpr::from_int( loc, 0 ) ), {}, ast::Linkage::Cforall ); 53 declsToAddBefore.push_back( finished ); 54 // (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N)) 55 // This pattern ensures that each unique expression is evaluated once, regardless of evaluation order of the generated C code. 56 auto assignFinished = ast::UntypedExpr::createAssign( loc, new ast::VariableExpr( loc, finished ), 57 ast::ConstantExpr::from_int( loc, 1 ) ); 58 auto condExpr = new ast::ConditionalExpr( loc, new ast::VariableExpr( loc, finished ), var, 59 new ast::CommaExpr( loc, new ast::CommaExpr( loc, assignUnq, assignFinished ), var ) ); 60 condExpr->result = var->result; 61 condExpr->env = unqExpr->env; 62 decls[id] = condExpr; 47 63 } 48 } 49 50 const ast::Expr * MemberTupleExpander::postvisit( const ast::UntypedMemberExpr * memberExpr ) { 51 const CodeLocation loc = memberExpr->location; 52 if ( auto tupleExpr = memberExpr->member.as< ast::UntypedTupleExpr >() ) { 53 auto mutExpr = mutate( tupleExpr ); 54 ast::ptr< ast::Expr > aggr = memberExpr->aggregate->accept( *visitor ); 55 // aggregate expressions which might be impure must be wrapped in unique expressions 56 if ( Tuples::maybeImpureIgnoreUnique( memberExpr->aggregate ) ) aggr = new ast::UniqueExpr( loc, aggr ); 57 for ( auto & expr : mutExpr->exprs ) { 58 expr = reconstructMemberExpr( expr, aggr, loc ); 59 } 60 //delete aggr; 61 return mutExpr; 62 } else { 63 // there may be a tuple expr buried in the aggregate 64 return new ast::UntypedMemberExpr( loc, memberExpr->member, memberExpr->aggregate->accept( *visitor ) ); 65 } 64 //delete unqExpr; 65 return ast::deepCopy(decls[id].get()); 66 66 } 67 67 } // namespace
Note: See TracChangeset
for help on using the changeset viewer.