Changeset ce1d721
- Timestamp:
- Jul 29, 2022, 2:08:31 PM (2 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- c0458be3
- Parents:
- b507dcd
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/TupleExpansionNew.cpp
rb507dcd rce1d721 9 9 // Author : Henry Xue 10 10 // Created On : Mon Aug 23 15:36:09 2021 11 // Last Modified By : Henry Xue12 // Last Modified On : Mon Aug 23 15:36:09 202113 // Update Count : 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jul 29 14:06:00 2022 13 // Update Count : 2 14 14 // 15 15 … … 20 20 21 21 namespace Tuples { 22 22 23 namespace { 23 struct MemberTupleExpander final : public ast::WithShortCircuiting, public ast::WithVisitorRef< MemberTupleExpander > { 24 void previsit( const ast::UntypedMemberExpr * ) { visit_children = false; } 25 const ast::Expr * postvisit( const ast::UntypedMemberExpr * memberExpr ); 26 }; 27 struct UniqueExprExpander final : public ast::WithDeclsToAdd<> { 28 const ast::Expr * postvisit( const ast::UniqueExpr * unqExpr ); 29 std::map< int, ast::ptr<ast::Expr> > decls; // not vector, because order added may not be increasing order 30 }; 31 } // namespace 32 33 void expandMemberTuples( ast::TranslationUnit & translationUnit ) { 34 ast::Pass< MemberTupleExpander >::run( translationUnit ); 35 } 36 37 namespace { 38 namespace { 39 /// given a expression representing the member and an expression representing the aggregate, 40 /// reconstructs a flattened UntypedMemberExpr with the right precedence 41 const ast::Expr * reconstructMemberExpr( const ast::Expr * member, const ast::Expr * aggr, const CodeLocation & loc ) { 42 if ( auto memberExpr = dynamic_cast< const ast::UntypedMemberExpr * >( member ) ) { 43 // construct a new UntypedMemberExpr with the correct structure , and recursively 44 // expand that member expression. 45 ast::Pass< MemberTupleExpander > expander; 46 auto inner = new ast::UntypedMemberExpr( loc, memberExpr->aggregate, aggr ); 47 auto newMemberExpr = new ast::UntypedMemberExpr( loc, memberExpr->member, inner ); 48 //delete memberExpr; 49 return newMemberExpr->accept( expander ); 50 } else { 51 // not a member expression, so there is nothing to do but attach and return 52 return new ast::UntypedMemberExpr( loc, member, aggr ); 53 } 54 } 55 } 56 57 const ast::Expr * MemberTupleExpander::postvisit( const ast::UntypedMemberExpr * memberExpr ) { 58 const CodeLocation loc = memberExpr->location; 59 if ( auto tupleExpr = memberExpr->member.as< ast::UntypedTupleExpr >() ) { 60 auto mutExpr = mutate( tupleExpr ); 61 ast::ptr< ast::Expr > aggr = memberExpr->aggregate->accept( *visitor ); 62 // aggregate expressions which might be impure must be wrapped in unique expressions 63 if ( Tuples::maybeImpureIgnoreUnique( memberExpr->aggregate ) ) aggr = new ast::UniqueExpr( loc, aggr ); 64 for ( auto & expr : mutExpr->exprs ) { 65 expr = reconstructMemberExpr( expr, aggr, loc ); 66 } 67 //delete aggr; 68 return mutExpr; 24 25 struct MemberTupleExpander final : public ast::WithShortCircuiting, public ast::WithVisitorRef< MemberTupleExpander > { 26 void previsit( const ast::UntypedMemberExpr * ) { visit_children = false; } 27 const ast::Expr * postvisit( const ast::UntypedMemberExpr * memberExpr ); 28 }; 29 30 struct UniqueExprExpander final : public ast::WithDeclsToAdd<> { 31 const ast::Expr * postvisit( const ast::UniqueExpr * unqExpr ); 32 std::map< int, ast::ptr<ast::Expr> > decls; // not vector, because order added may not be increasing order 33 }; 34 35 /// given a expression representing the member and an expression representing the aggregate, 36 /// reconstructs a flattened UntypedMemberExpr with the right precedence 37 const ast::Expr * reconstructMemberExpr( const ast::Expr * member, const ast::Expr * aggr, const CodeLocation & loc ) { 38 if ( auto memberExpr = dynamic_cast< const ast::UntypedMemberExpr * >( member ) ) { 39 // construct a new UntypedMemberExpr with the correct structure , and recursively 40 // expand that member expression. 41 ast::Pass< MemberTupleExpander > expander; 42 auto inner = new ast::UntypedMemberExpr( loc, memberExpr->aggregate, aggr ); 43 auto newMemberExpr = new ast::UntypedMemberExpr( loc, memberExpr->member, inner ); 44 return newMemberExpr->accept( expander ); 45 } else { 46 // not a member expression, so there is nothing to do but attach and return 47 return new ast::UntypedMemberExpr( loc, member, aggr ); 48 } 49 } 50 51 const ast::Expr * MemberTupleExpander::postvisit( const ast::UntypedMemberExpr * memberExpr ) { 52 const CodeLocation loc = memberExpr->location; 53 if ( auto tupleExpr = memberExpr->member.as< ast::UntypedTupleExpr >() ) { 54 auto mutExpr = mutate( tupleExpr ); 55 ast::ptr< ast::Expr > aggr = memberExpr->aggregate->accept( *visitor ); 56 // aggregate expressions which might be impure must be wrapped in unique expressions 57 if ( Tuples::maybeImpureIgnoreUnique( memberExpr->aggregate ) ) aggr = new ast::UniqueExpr( loc, aggr ); 58 for ( auto & expr : mutExpr->exprs ) { 59 expr = reconstructMemberExpr( expr, aggr, loc ); 60 } 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 } 66 } 67 68 const ast::Expr * UniqueExprExpander::postvisit( const ast::UniqueExpr * unqExpr ) { 69 const CodeLocation loc = unqExpr->location; 70 const int id = unqExpr->id; 71 72 // on first time visiting a unique expr with a particular ID, generate the expression that replaces all UniqueExprs with that ID, 73 // and lookup on subsequent hits. This ensures that all unique exprs with the same ID reference the same variable. 74 if ( ! decls.count( id ) ) { 75 ast::ptr< ast::Expr > assignUnq; 76 const ast::VariableExpr * var = unqExpr->var; 77 if ( unqExpr->object ) { 78 // an object was generated to represent this unique expression -- it should be added to the list of declarations now 79 declsToAddBefore.push_back( unqExpr->object.as< ast::Decl >() ); 80 // deep copy required due to unresolved issues with UniqueExpr 81 assignUnq = ast::UntypedExpr::createAssign( loc, var, unqExpr->expr ); 69 82 } else { 70 // there may be a tuple expr buried in the aggregate 71 return new ast::UntypedMemberExpr( loc, memberExpr->member, memberExpr->aggregate->accept( *visitor ) ); 72 } 73 } 74 } // namespace 75 76 void expandUniqueExpr( ast::TranslationUnit & translationUnit ) { 77 ast::Pass< UniqueExprExpander >::run( translationUnit ); 78 } 79 80 namespace { 81 const ast::Expr * UniqueExprExpander::postvisit( const ast::UniqueExpr * unqExpr ) { 82 const CodeLocation loc = unqExpr->location; 83 const int id = unqExpr->id; 84 85 // on first time visiting a unique expr with a particular ID, generate the expression that replaces all UniqueExprs with that ID, 86 // and lookup on subsequent hits. This ensures that all unique exprs with the same ID reference the same variable. 87 if ( ! decls.count( id ) ) { 88 ast::ptr< ast::Expr > assignUnq; 89 const ast::VariableExpr * var = unqExpr->var; 90 if ( unqExpr->object ) { 91 // an object was generated to represent this unique expression -- it should be added to the list of declarations now 92 declsToAddBefore.push_back( unqExpr->object.as< ast::Decl >() ); 93 // deep copy required due to unresolved issues with UniqueExpr 94 assignUnq = ast::UntypedExpr::createAssign( loc, var, unqExpr->expr ); 95 } else { 96 const auto commaExpr = unqExpr->expr.strict_as< ast::CommaExpr >(); 97 assignUnq = commaExpr->arg1; 98 } 99 auto finished = new ast::ObjectDecl( loc, toString( "_unq", id, "_finished_" ), new ast::BasicType( ast::BasicType::Kind::Bool ), 100 new ast::SingleInit( loc, ast::ConstantExpr::from_int( loc, 0 ) ), {}, ast::Linkage::Cforall ); 101 declsToAddBefore.push_back( finished ); 102 // (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N)) 103 // This pattern ensures that each unique expression is evaluated once, regardless of evaluation order of the generated C code. 104 auto assignFinished = ast::UntypedExpr::createAssign( loc, new ast::VariableExpr( loc, finished ), 105 ast::ConstantExpr::from_int( loc, 1 ) ); 106 auto condExpr = new ast::ConditionalExpr( loc, new ast::VariableExpr( loc, finished ), var, 107 new ast::CommaExpr( loc, new ast::CommaExpr( loc, assignUnq, assignFinished ), var ) ); 108 condExpr->result = var->result; 109 condExpr->env = unqExpr->env; 110 decls[id] = condExpr; 111 } 112 //delete unqExpr; 113 return ast::deepCopy(decls[id].get()); 114 } 115 } // namespace 116 117 namespace { 83 const auto commaExpr = unqExpr->expr.strict_as< ast::CommaExpr >(); 84 assignUnq = commaExpr->arg1; 85 } 86 auto finished = new ast::ObjectDecl( loc, toString( "_unq", id, "_finished_" ), new ast::BasicType( ast::BasicType::Kind::Bool ), 87 new ast::SingleInit( loc, ast::ConstantExpr::from_int( loc, 0 ) ), {}, ast::Linkage::Cforall ); 88 declsToAddBefore.push_back( finished ); 89 // (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N)) 90 // This pattern ensures that each unique expression is evaluated once, regardless of evaluation order of the generated C code. 91 auto assignFinished = ast::UntypedExpr::createAssign( loc, new ast::VariableExpr( loc, finished ), 92 ast::ConstantExpr::from_int( loc, 1 ) ); 93 auto condExpr = new ast::ConditionalExpr( loc, new ast::VariableExpr( loc, finished ), var, 94 new ast::CommaExpr( loc, new ast::CommaExpr( loc, assignUnq, assignFinished ), var ) ); 95 condExpr->result = var->result; 96 condExpr->env = unqExpr->env; 97 decls[id] = condExpr; 98 } 99 return ast::deepCopy(decls[id].get()); 100 } 118 101 119 102 struct TupleAssignExpander { … … 283 266 } // namespace 284 267 268 void expandMemberTuples( ast::TranslationUnit & translationUnit ) { 269 ast::Pass< MemberTupleExpander >::run( translationUnit ); 270 } 271 272 void expandUniqueExpr( ast::TranslationUnit & translationUnit ) { 273 ast::Pass< UniqueExprExpander >::run( translationUnit ); 274 } 275 285 276 void expandTuples( ast::TranslationUnit & translationUnit ) { 286 277 // These may not have to be seperate passes.
Note: See TracChangeset
for help on using the changeset viewer.