Changes in src/Tuples/TupleExpansion.cc [be9288a:9f10c4b8]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/TupleExpansion.cc
rbe9288a r9f10c4b8 14 14 // 15 15 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" 36 33 37 34 namespace Tuples { 38 35 namespace { 39 class MemberTupleExpander final : public Mutator { 40 public: 36 struct MemberTupleExpander final : public Mutator { 41 37 typedef Mutator Parent; 42 38 using Parent::mutate; … … 45 41 }; 46 42 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 ); 53 45 54 46 std::map< int, Expression * > decls; // not vector, because order added may not be increasing order … … 61 53 }; 62 54 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 ); 69 57 }; 70 58 … … 79 67 }; 80 68 81 class TupleIndexExpander { 82 public: 69 struct TupleIndexExpander { 83 70 Expression * postmutate( TupleIndexExpr * tupleExpr ); 84 71 }; 85 72 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 ); 92 75 }; 93 76 } … … 99 82 100 83 void expandUniqueExpr( std::list< Declaration * > & translationUnit ) { 101 UniqueExprExpanderunqExpander;102 unqExpander.mutateDeclarationList( translationUnit);84 PassVisitor<UniqueExprExpander> unqExpander; 85 mutateAll( translationUnit, unqExpander ); 103 86 } 104 87 105 88 void expandTuples( std::list< Declaration * > & translationUnit ) { 106 TupleAssignExpanderassnExpander;89 PassVisitor<TupleAssignExpander> assnExpander; 107 90 mutateAll( translationUnit, assnExpander ); 108 91 … … 113 96 mutateAll( translationUnit, idxExpander ); 114 97 115 TupleExprExpanderexprExpander;98 PassVisitor<TupleExprExpander> exprExpander; 116 99 mutateAll( translationUnit, exprExpander ); 117 100 } … … 146 129 // aggregate expressions which might be impure must be wrapped in unique expressions 147 130 // 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 ); 149 132 aggr = new UniqueExpr( aggr ); 150 133 for ( Expression *& expr : tupleExpr->get_exprs() ) { … … 164 147 } 165 148 166 Expression * UniqueExprExpander::mutate( UniqueExpr * unqExpr ) { 167 unqExpr = safe_dynamic_cast< UniqueExpr * > ( Parent::mutate( unqExpr ) ); 149 Expression * UniqueExprExpander::postmutate( UniqueExpr * unqExpr ) { 168 150 const int id = unqExpr->get_id(); 169 151 … … 175 157 if ( unqExpr->get_object() ) { 176 158 // 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() ); 178 160 unqExpr->set_object( nullptr ); 179 161 // steal the expr from the unqExpr … … 189 171 ObjectDecl * finished = new ObjectDecl( toString( "_unq", id, "_finished_" ), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::Bool ), 190 172 new SingleInit( new ConstantExpr( Constant::from_int( 0 ) ) ) ); 191 addDeclaration( finished );173 declsToAddBefore.push_back( finished ); 192 174 // (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N)) 193 175 // This pattern ensures that each unique expression is evaluated once, regardless of evaluation order of the generated C code. … … 203 185 } 204 186 205 Expression * TupleAssignExpander::mutate( TupleAssignExpr * assnExpr ) { 206 assnExpr = safe_dynamic_cast< TupleAssignExpr * >( Parent::mutate( assnExpr ) ); 187 Expression * TupleAssignExpander::postmutate( TupleAssignExpr * assnExpr ) { 207 188 StmtExpr * ret = assnExpr->get_stmtExpr(); 208 189 assnExpr->set_stmtExpr( nullptr ); … … 238 219 for ( auto p : group_iterate( tupleType->get_types(), decl->get_parameters() ) ) { 239 220 Type * t = std::get<0>(p); 240 TypeDecl * td = std::get<1>(p);241 221 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 }247 222 } 248 223 delete tupleType; … … 293 268 } 294 269 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 ) { 298 271 Type * result = tupleExpr->get_result(); 299 272 std::list< Expression * > exprs = tupleExpr->get_exprs(); … … 342 315 class ImpurityDetector : public Visitor { 343 316 public: 317 ImpurityDetector( bool ignoreUnique ) : ignoreUnique( ignoreUnique ) {} 318 344 319 typedef Visitor Parent; 345 320 virtual void visit( ApplicationExpr * appExpr ) { … … 355 330 maybeImpure = true; 356 331 } 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 358 343 bool maybeImpure = false; 344 bool ignoreUnique; 359 345 }; 360 346 } // namespace 361 347 362 348 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 ); 364 356 expr->accept( detector ); 365 357 return detector.maybeImpure;
Note:
See TracChangeset
for help on using the changeset viewer.