Changeset b7fd9daf for src/Tuples/TupleExpansionNew.cpp
- Timestamp:
- Nov 10, 2021, 7:47:45 PM (2 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
- Children:
- 3249dd8
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/TupleExpansionNew.cpp
r1622af5 rb7fd9daf 21 21 void previsit( const ast::UntypedMemberExpr * ) { visit_children = false; } 22 22 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 23 27 }; 24 28 } // namespace … … 66 70 } 67 71 } // namespace 72 73 void expandUniqueExpr( ast::TranslationUnit & translationUnit ) { 74 ast::Pass< UniqueExprExpander >::run( translationUnit ); 75 } 76 77 namespace { 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 68 113 } // namespace Tuples
Note: See TracChangeset
for help on using the changeset viewer.