Changes in / [76934fb:db82596]
- Location:
- src/ControlStruct
- Files:
-
- 2 edited
-
LabelFixer.cc (modified) (5 diffs)
-
LabelFixer.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/LabelFixer.cc
r76934fb rdb82596 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 29 15:57:12201513 // Update Count : 8212 // Last Modified On : Wed May 27 16:16:14 2015 13 // Update Count : 4 14 14 // 15 15 … … 23 23 #include "utility.h" 24 24 25 #include <iostream>26 27 25 namespace ControlStruct { 28 LabelFixer::Entry::Entry( Statement *to, BranchStmt *from ) : definition ( to ) {26 LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) { 29 27 if ( from != 0 ) 30 28 usage.push_back( from ); … … 33 31 bool LabelFixer::Entry::insideLoop() { 34 32 return ( dynamic_cast< ForStmt * > ( definition ) || 35 dynamic_cast< WhileStmt * > ( definition ) );33 dynamic_cast< WhileStmt * > ( definition ) ); 36 34 } 37 35 … … 48 46 } 49 47 50 // prune to at most one label definition for each statement51 48 void LabelFixer::visit( Statement *stmt ) { 52 49 std::list< Label > &labels = stmt->get_labels(); 53 50 54 51 if ( ! labels.empty() ) { 55 // only remember one label for each statement56 52 Label current = setLabelsDef( labels, stmt ); 57 53 labels.clear(); … … 61 57 62 58 void LabelFixer::visit( BranchStmt *branchStmt ) { 63 visit ( ( Statement * )branchStmt ); 59 visit ( ( Statement * )branchStmt ); // the labels this statement might have 64 60 65 // for labeled branches, add an entry to the label table 66 Label target = branchStmt->get_target(); 67 if ( target != "" ) { 61 Label target; 62 if ( (target = branchStmt->get_target()) != "" ) { 68 63 setLabelsUsg( target, branchStmt ); 69 } 64 } //else /* computed goto or normal exit-loop statements */ 70 65 } 71 66 72 // sets the definition of the labelTable entry to be the provided73 // statement for every label in the list parameter. Happens for every kind of statement74 67 Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) { 75 68 assert( definition != 0 ); 76 assert( llabel.size() > 0 ); 69 Entry *entry = new Entry( definition ); 70 bool used = false; 77 71 78 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) { 79 if ( labelTable.find( *i ) == labelTable.end() ) { 80 // undefined and unused until now, add an entry 81 labelTable[ *i ] = new Entry( definition ); 82 } else if ( labelTable[ *i ]->defined() ) {\ 83 // defined twice, error 84 throw SemanticError( "Duplicate definition of label: " + *i ); 85 } else { 86 // used previously, but undefined until now -> set its definition to this location 87 labelTable[ *i ]->set_definition( definition ); 88 } // if 89 } // for 72 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) 73 if ( labelTable.find( *i ) == labelTable.end() ) 74 { used = true; labelTable[ *i ] = entry; } // undefined and unused 75 else 76 if ( labelTable[ *i ]->defined() ) 77 throw SemanticError( "Duplicate definition of label: " + *i ); 78 else 79 labelTable[ *i ]->set_definition( definition ); 90 80 91 // produce one of the labels attached to this statement to be92 // temporarily used as the canonical label 93 return labelTable[ llabel.front() ]->get_label(); 81 if ( ! used ) delete entry; 82 83 return labelTable[ llabel.front() ]->get_label(); // this *must* exist 94 84 } 95 85 96 // Remember all uses of a label. 97 void LabelFixer::setLabelsUsg( Label orgValue, BranchStmt *use ) { 86 Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) { 98 87 assert( use != 0 ); 99 88 100 if ( labelTable.find( orgValue ) != labelTable.end() ) { 101 // the label has been defined or used before 102 labelTable[ orgValue ]->add_use( use ); 103 } else { 89 if ( labelTable.find( orgValue ) != labelTable.end() ) 90 labelTable[ orgValue ]->add_use( use ); // the label has been defined or used before 91 else 104 92 labelTable[ orgValue ] = new Entry( 0, use ); 105 } 93 94 return labelTable[ orgValue ]->get_label(); 106 95 } 107 96 108 // Ultimately builds a table that maps a label to its defining statement.109 // In the process,110 97 std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) { 111 98 std::map< Statement *, Entry * > def_us; 112 99 113 // combine the entries for all labels that target the same location 114 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) { 100 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) { 115 101 Entry *e = i->second; 116 102 117 103 if ( def_us.find ( e->get_definition() ) == def_us.end() ) { 118 104 def_us[ e->get_definition() ] = e; 119 } else if ( e->used() ) { 120 def_us[ e->get_definition() ]->add_uses( e->get_uses() ); 105 } else { 106 if ( e->used() ) 107 def_us[ e->get_definition() ]->add_uses( e->get_uses() ); 121 108 } 122 109 } 123 110 124 // create a unique label for each target location.125 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i) {111 // get rid of labelTable 112 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) { 126 113 Statement *to = (*i).first; 127 Entry * entry = (*i).second; 128 std::list< BranchStmt *> &from = entry->get_uses(); 114 std::list< Statement *> &from = (*i).second->get_uses(); 115 Label finalLabel = generator->newLabel(); 116 (*i).second->set_label( finalLabel ); 129 117 130 // no label definition found131 118 if ( to == 0 ) { 132 Label undef = from.back()->get_target(); 119 BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back()); 120 Label undef(""); 121 if ( first_use != 0 ) 122 undef = first_use->get_target(); 133 123 throw SemanticError ( "'" + undef + "' label not defined"); 134 124 } 135 136 // generate a new label, and attach it to its defining statement137 // as the only label on that statement138 Label finalLabel = generator->newLabel();139 entry->set_label( finalLabel );140 125 141 126 to->get_labels().clear(); 142 127 to->get_labels().push_back( finalLabel ); 143 128 144 // redirect each of the source branch statements to the new target label 145 for ( std::list< BranchStmt *>::iterator j = from.begin(); j != from.end(); ++j ) { 146 BranchStmt *jump = *j; 147 assert( jump != 0 ); 148 jump->set_target( finalLabel ); 129 for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) { 130 BranchStmt *jumpTo = dynamic_cast< BranchStmt * > ( *j ); 131 assert( jumpTo != 0 ); 132 jumpTo->set_target( finalLabel ); 149 133 } // for 150 134 } // for 151 135 152 // create a table where each label maps to its defining statement136 // reverse table 153 137 std::map< Label, Statement * > *ret = new std::map< Label, Statement * >(); 154 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {138 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) 155 139 (*ret)[ (*i).second->get_label() ] = (*i).first; 156 }157 140 158 141 return ret; -
src/ControlStruct/LabelFixer.h
r76934fb rdb82596 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 29 15:25:55201513 // Update Count : 1112 // Last Modified On : Tue May 26 12:55:10 2015 13 // Update Count : 4 14 14 // 15 15 … … 55 55 56 56 Label setLabelsDef( std::list< Label > &, Statement *definition ); 57 void setLabelsUsg( Label, BranchStmt *usage = 0 );57 Label setLabelsUsg( Label, Statement *usage = 0 ); 58 58 59 59 private: 60 60 class Entry { 61 61 public: 62 Entry( Statement *to = 0, BranchStmt *from = 0 );62 Entry( Statement *to = 0, Statement *from = 0 ); 63 63 bool used() { return ( usage.empty() ); } 64 64 bool defined() { return ( definition != 0 ); } … … 71 71 void set_definition( Statement *def ) { definition = def; } 72 72 73 std::list< BranchStmt *> &get_uses() { return usage; }74 void add_use ( BranchStmt *use ) { usage.push_back( use ); }75 void add_uses ( std::list< BranchStmt *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }73 std::list< Statement *> &get_uses() { return usage; } 74 void add_use ( Statement *use ) { usage.push_back( use ); } 75 void add_uses ( std::list<Statement *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); } 76 76 private: 77 77 Label label; 78 78 Statement *definition; 79 std::list< BranchStmt *> usage;79 std::list<Statement *> usage; 80 80 }; 81 81
Note:
See TracChangeset
for help on using the changeset viewer.