Changeset d9a0e76 for translator/ControlStruct/LabelFixer.cc
- Timestamp:
- Dec 16, 2014, 9:41:50 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- 17cd4eb
- Parents:
- 3848e0e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
translator/ControlStruct/LabelFixer.cc
r3848e0e rd9a0e76 9 9 10 10 namespace ControlStruct { 11 LabelFixer::Entry::Entry( Statement *to, Statement *from ) : 12 definition ( to ) 13 { 14 if ( from != 0 ) 15 usage.push_back( from ); 16 } 11 LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) { 12 if ( from != 0 ) 13 usage.push_back( from ); 14 } 17 15 18 bool LabelFixer::Entry::insideLoop() 19 { 20 return ( dynamic_cast< ForStmt * > ( definition ) || 21 dynamic_cast< WhileStmt * > ( definition ) ); 22 } 16 bool LabelFixer::Entry::insideLoop() { 17 return ( dynamic_cast< ForStmt * > ( definition ) || 18 dynamic_cast< WhileStmt * > ( definition ) ); 19 } 23 20 24 LabelFixer::LabelFixer( LabelGenerator *gen ) : generator ( gen ) 25 { 26 if ( generator == 0 ) 27 generator = LabelGenerator::getGenerator(); 28 } 21 LabelFixer::LabelFixer( LabelGenerator *gen ) : generator ( gen ) { 22 if ( generator == 0 ) 23 generator = LabelGenerator::getGenerator(); 24 } 29 25 30 void LabelFixer::visit(FunctionDecl *functionDecl) 31 { 32 if ( functionDecl->get_statements() != 0 ) 33 functionDecl->get_statements()->accept( *this ); 26 void LabelFixer::visit(FunctionDecl *functionDecl) { 27 if ( functionDecl->get_statements() != 0 ) 28 functionDecl->get_statements()->accept( *this ); 34 29 35 36 37 }30 MLEMutator mlemut( resolveJumps(), generator ); 31 functionDecl->acceptMutator( mlemut ); 32 } 38 33 39 void LabelFixer::visit(Statement *stmt ) 40 { 41 std::list< Label > &labels = stmt->get_labels(); 34 void LabelFixer::visit(Statement *stmt ) { 35 std::list< Label > &labels = stmt->get_labels(); 42 36 43 if ( ! labels.empty() ) { 44 Label current = setLabelsDef( labels, stmt ); 45 labels.clear(); 46 labels.push_front( current ); 37 if ( ! labels.empty() ) { 38 Label current = setLabelsDef( labels, stmt ); 39 labels.clear(); 40 labels.push_front( current ); 41 } // if 47 42 } 48 }49 43 50 void LabelFixer::visit(BranchStmt *branchStmt) 51 { 52 visit ( ( Statement * )branchStmt ); // the labels this statement might have 44 void LabelFixer::visit(BranchStmt *branchStmt) { 45 visit ( ( Statement * )branchStmt ); // the labels this statement might have 53 46 54 55 56 57 58 }47 Label target; 48 if ( (target = branchStmt->get_target()) != "" ) { 49 setLabelsUsg( target, branchStmt ); 50 } //else /* computed goto or normal exit-loop statements */ 51 } 59 52 60 53 61 Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) 62 { 63 assert( definition != 0 ); 64 Entry *entry = new Entry( definition ); 65 bool used = false; 54 Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) { 55 assert( definition != 0 ); 56 Entry *entry = new Entry( definition ); 57 bool used = false; 66 58 67 68 69 { used = true; labelTable[ *i ] = entry; } // undefined and unused70 71 if( labelTable[ *i ]->defined() )72 throw SemanticError("Duplicate definition of label: " + *i );73 else74 labelTable[ *i ]->set_definition( definition );59 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) 60 if ( labelTable.find( *i ) == labelTable.end() ) 61 { used = true; labelTable[ *i ] = entry; } // undefined and unused 62 else 63 if( labelTable[ *i ]->defined() ) 64 throw SemanticError("Duplicate definition of label: " + *i ); 65 else 66 labelTable[ *i ]->set_definition( definition ); 75 67 76 68 if (! used ) delete entry; 77 69 78 return labelTable[ llabel.front() ]->get_label(); // this *must* exist 79 } 80 81 Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) 82 { 83 assert( use != 0 ); 84 85 if ( labelTable.find( orgValue ) != labelTable.end() ) 86 labelTable[ orgValue ]->add_use( use ); // the label has been defined or used before 87 else 88 labelTable[ orgValue ] = new Entry( 0, use ); 89 90 return labelTable[ orgValue ]->get_label(); 91 } 92 93 std::map < Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) 94 { 95 std::map < Statement *, Entry * > def_us; 96 97 for( std::map < Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) { 98 Entry *e = i->second; 99 100 if ( def_us.find ( e->get_definition() ) == def_us.end() ) 101 def_us[ e->get_definition() ] = e; 102 else 103 if(e->used()) 104 def_us[ e->get_definition() ]->add_uses( e->get_uses() ); 70 return labelTable[ llabel.front() ]->get_label(); // this *must* exist 105 71 } 106 72 107 // get rid of labelTable 108 for( std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) { 109 Statement *to = (*i).first; 110 std::list < Statement *> &from = (*i).second->get_uses(); 111 Label finalLabel = generator->newLabel(); 112 (*i).second->set_label( finalLabel ); 73 Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) { 74 assert( use != 0 ); 113 75 114 if ( to == 0 ) { 115 BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back()); 116 Label undef(""); 117 if ( first_use != 0 ) 118 undef = first_use->get_target(); 119 throw SemanticError ( "'" + undef + "' label not defined"); 120 } 76 if ( labelTable.find( orgValue ) != labelTable.end() ) 77 labelTable[ orgValue ]->add_use( use ); // the label has been defined or used before 78 else 79 labelTable[ orgValue ] = new Entry( 0, use ); 121 80 122 to->get_labels().clear(); 123 to->get_labels().push_back( finalLabel ); 124 125 for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) { 126 BranchStmt *jumpTo = dynamic_cast < BranchStmt * > ( *j ); 127 assert( jumpTo != 0 ); 128 jumpTo->set_target( finalLabel ); 129 } 81 return labelTable[ orgValue ]->get_label(); 130 82 } 131 83 132 // reverse table 133 std::map < Label, Statement * > *ret = new std::map < Label, Statement * >(); 134 for(std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) 135 (*ret)[ (*i).second->get_label() ] = (*i).first; 84 std::map < Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) { 85 std::map < Statement *, Entry * > def_us; 136 86 137 return ret; 138 } 87 for ( std::map < Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) { 88 Entry *e = i->second; 139 89 90 if ( def_us.find ( e->get_definition() ) == def_us.end() ) 91 def_us[ e->get_definition() ] = e; 92 else 93 if(e->used()) 94 def_us[ e->get_definition() ]->add_uses( e->get_uses() ); 95 } 96 97 // get rid of labelTable 98 for ( std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) { 99 Statement *to = (*i).first; 100 std::list < Statement *> &from = (*i).second->get_uses(); 101 Label finalLabel = generator->newLabel(); 102 (*i).second->set_label( finalLabel ); 103 104 if ( to == 0 ) { 105 BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back()); 106 Label undef(""); 107 if ( first_use != 0 ) 108 undef = first_use->get_target(); 109 throw SemanticError ( "'" + undef + "' label not defined"); 110 } 111 112 to->get_labels().clear(); 113 to->get_labels().push_back( finalLabel ); 114 115 for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) { 116 BranchStmt *jumpTo = dynamic_cast < BranchStmt * > ( *j ); 117 assert( jumpTo != 0 ); 118 jumpTo->set_target( finalLabel ); 119 } // for 120 } // for 121 122 // reverse table 123 std::map < Label, Statement * > *ret = new std::map < Label, Statement * >(); 124 for (std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) 125 (*ret)[ (*i).second->get_label() ] = (*i).first; 126 127 return ret; 128 } 140 129 } // namespace ControlStruct
Note: See TracChangeset
for help on using the changeset viewer.