Changeset 817bb3c
- Timestamp:
- Nov 5, 2021, 7:44:38 PM (3 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
- Children:
- de31a1d
- Parents:
- 21fe17f
- Location:
- src/ControlStruct
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/FixLabels.cpp
r21fe17f r817bb3c 10 10 // Created On : Mon Nov 1 09:39:00 2021 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Nov 5 1 6:05:00 202113 // Update Count : 112 // Last Modified On : Mon Nov 5 19:20:00 2021 13 // Update Count : 2 14 14 // 15 15 … … 58 58 } 59 59 } 60 LabelToStmt * copy = new LabelToStmt( labelTable );61 60 return ast::mutate_field( decl, &ast::FunctionDecl::stmts, 62 multiLevelExitUpdate( decl->stmts.get(), copy, label_gen ) );61 multiLevelExitUpdate( decl->stmts.get(), labelTable, label_gen ) ); 63 62 } 64 63 -
src/ControlStruct/MultiLevelExit.cpp
r21fe17f r817bb3c 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // MultiLevelExit.cpp -- 7 // MultiLevelExit.cpp -- Replaces CFA's local control flow with C's versions. 8 8 // 9 9 // Author : Andrew Beach 10 10 // Created On : Mon Nov 1 13:48:00 2021 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Nov 5 1 2:06:00 202113 // Update Count : 012 // Last Modified On : Mon Nov 5 19:20:00 2021 13 // Update Count : 1 14 14 // 15 15 … … 102 102 } 103 103 104 struct MultiLevelExitCore :104 struct MultiLevelExitCore final : 105 105 public ast::WithVisitorRef<MultiLevelExitCore>, 106 106 public ast::WithShortCircuiting, public ast::WithGuards { 107 MultiLevelExitCore( LabelToStmt * lt, LabelGenerator_new * lg ); 108 ~MultiLevelExitCore(); 107 MultiLevelExitCore( const LabelToStmt & lt, LabelGenerator_new * lg ); 109 108 110 109 void previsit( const ast::FunctionDecl * ); … … 128 127 const ast::Stmt * mutateLoop( const ast::Stmt * body, Entry& ); 129 128 130 LabelToStmt *target_table;129 const LabelToStmt & target_table; 131 130 std::set<ast::Label> fallthrough_labels; 132 131 std::vector<Entry> enclosing_control_structures; … … 142 141 std::list<ast::ptr<ast::Stmt>> fixBlock( 143 142 const std::list<ast::ptr<ast::Stmt>> & kids, bool caseClause ); 143 144 template<typename UnaryPredicate> 145 auto findEnclosingControlStructure( UnaryPredicate pred ) { 146 return std::find_if( enclosing_control_structures.rbegin(), 147 enclosing_control_structures.rend(), pred ); 148 } 144 149 }; 145 150 146 /* 147 template<typename... Args> 148 void MultiLevelExitCore::GuardEntry( Args&&... args ) { 149 enclosing_control_structures.emplace_back( std::forward<Args>(args)... ); 150 GuardAction([this]() { enclosing_control_structures.pop_back(); } ) 151 } 152 153 template<typename UnaryPredicate> 154 void MultiLevelExitCore::findEnclosingControlStructure(UnaryPredicate pred) { 155 return std::find_if( 156 enclosing_control_structures.rbegin(), 157 enclosing_control_structures.rend(), 158 pred ); 159 } 160 161 ast::NullStmt * MultiLevelExitCore::labeledNullStmt( 151 ast::NullStmt * labelledNullStmt( 162 152 const CodeLocation & cl, const ast::Label & label ) { 163 153 return new ast::NullStmt( cl, std::vector<ast::Label>{ label } ); 164 154 } 165 */ 166 167 MultiLevelExitCore::MultiLevelExitCore( LabelToStmt *lt, LabelGenerator_new * lg ) :155 156 MultiLevelExitCore::MultiLevelExitCore( 157 const LabelToStmt & lt, LabelGenerator_new * lg ) : 168 158 target_table( lt ), break_label( CodeLocation(), "" ), label_gen( lg ), 169 159 inFinally( false ) 170 160 {} 171 172 MultiLevelExitCore::~MultiLevelExitCore() {173 delete target_table;174 target_table = nullptr;175 }176 161 177 162 void MultiLevelExitCore::previsit( const ast::FunctionDecl * ) { … … 247 232 if ( stmt->target.empty() ) { 248 233 if ( isContinue ) { 249 targetEntry = std::find_if( 250 enclosing_control_structures.rbegin(), 251 enclosing_control_structures.rend(), 252 isContinueTarget ); 234 targetEntry = findEnclosingControlStructure( isContinueTarget ); 253 235 } else { 254 236 if ( enclosing_control_structures.empty() ) { … … 256 238 "'break' outside a loop, 'switch', or labelled block" ); 257 239 } 258 targetEntry = std::find_if( 259 enclosing_control_structures.rbegin(), 260 enclosing_control_structures.rend(), 261 isBreakTarget ); 240 targetEntry = findEnclosingControlStructure( isBreakTarget ); 262 241 } 263 242 // Handle labeled break and continue. 264 243 } else { 265 244 // Lookup label in table to find attached control structure. 266 targetEntry = std::find_if( 267 enclosing_control_structures.rbegin(), 268 enclosing_control_structures.rend(), 269 [ targetStmt = (*target_table)[stmt->target] ](auto entry){ 245 targetEntry = findEnclosingControlStructure( 246 [ targetStmt = target_table.at(stmt->target) ](auto entry){ 270 247 return entry.stmt == targetStmt; 271 248 } ); … … 283 260 } 284 261 case ast::BranchStmt::FallThrough: { 285 targetEntry = std::find_if( 286 enclosing_control_structures.rbegin(), 287 enclosing_control_structures.rend(), 288 isFallthroughTarget 289 ); 262 targetEntry = findEnclosingControlStructure( isFallthroughTarget ); 290 263 // Check that target is valid. 291 264 if ( targetEntry == enclosing_control_structures.rend() ) { … … 303 276 } 304 277 case ast::BranchStmt::FallThroughDefault: { 305 targetEntry = std::find_if( enclosing_control_structures.rbegin(), enclosing_control_structures.rend(),isFallthroughDefaultTarget );278 targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget ); 306 279 307 280 // Check that this is in a switch or choose statement. … … 397 370 // If it is the default, mark the default as seen. 398 371 if ( stmt->isDefault() ) { 372 assert( !enclosing_control_structures.empty() ); 399 373 enclosing_control_structures.back().seenDefault(); 400 374 } … … 422 396 Entry & entry = enclosing_control_structures.back(); 423 397 if ( entry.isFallUsed() ) { 424 mutStmt->stmts.push_back( new ast::NullStmt( 425 mutStmt->location, 426 std::vector<ast::Label>{ entry.useFallExit() } 427 ) ); 398 mutStmt->stmts.push_back( 399 labelledNullStmt( mutStmt->location, entry.useFallExit() ) ); 428 400 } 429 401 } … … 436 408 if ( entry.isFallDefaultUsed() ) { 437 409 // Add fallthrough default label if necessary. 438 push_front( mutStmt->stmts, new ast::NullStmt( 439 stmt->location, 440 std::vector<ast::Label>{ enclosing_control_structures.back().useFallDefaultExit() } 410 push_front( mutStmt->stmts, labelledNullStmt( 411 stmt->location, entry.useFallDefaultExit() 441 412 ) ); 442 413 } … … 568 539 ast::CompoundStmt * new_body = new ast::CompoundStmt( body->location ); 569 540 new_body->kids.push_back( body ); 570 571 new_body->kids.push_back( new ast::NullStmt( 572 body->location, 573 std::vector<ast::Label>{ entry.useContExit() } 574 ) ); 575 541 new_body->kids.push_back( 542 labelledNullStmt( body->location, entry.useContExit() ) ); 576 543 return new_body; 577 544 } … … 624 591 625 592 if ( !break_label.empty() ) { 626 ret.push_back( new ast::NullStmt( 627 ret.back()->location, 628 std::vector<ast::Label>{ break_label } 629 ) ); 593 ret.push_back( 594 labelledNullStmt( ret.back()->location, break_label ) ); 630 595 break_label = ast::Label( CodeLocation(), "" ); 631 596 } … … 642 607 const ast::CompoundStmt * multiLevelExitUpdate( 643 608 const ast::CompoundStmt * stmt, 644 LabelToStmt *labelTable,609 const LabelToStmt & labelTable, 645 610 LabelGenerator_new * labelGen ) { 646 611 // Must start in the body, so FunctionDecls can be a stopping point. 647 612 ast::Pass<MultiLevelExitCore> visitor( labelTable, labelGen ); 648 return stmt->accept( visitor ); 613 const ast::CompoundStmt * ret = stmt->accept( visitor ); 614 return ret; 649 615 } 650 616 -
src/ControlStruct/MultiLevelExit.hpp
r21fe17f r817bb3c 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // MultiLevelExit.hpp -- 7 // MultiLevelExit.hpp -- Replaces CFA's local control flow with C's versions. 8 8 // 9 9 // Author : Andrew Beach 10 10 // Created On : Mon Nov 1 13:49:00 2021 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Nov 2 10:26:00 202113 // Update Count : 012 // Last Modified On : Mon Nov 5 19:20:00 2021 13 // Update Count : 1 14 14 // 15 15 … … 20 20 namespace ast { 21 21 class CompoundStmt; 22 22 class Label; 23 23 class Stmt; 24 24 } … … 31 31 /// Mutate a function body to handle multi-level exits. 32 32 const ast::CompoundStmt * multiLevelExitUpdate( 33 const ast::CompoundStmt *, LabelToStmt *, LabelGenerator_new *);33 const ast::CompoundStmt *, const LabelToStmt &, LabelGenerator_new *); 34 34 35 35 }
Note: See TracChangeset
for help on using the changeset viewer.