Changeset e766208
- Timestamp:
- Jul 30, 2015, 4:05:02 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:
- e01559c
- Parents:
- 51b986f
- Location:
- src/ControlStruct
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/LabelFixer.cc
r51b986f re766208 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Jul 08 12:36:46201513 // Update Count : 1 4512 // Last Modified On : Tue Jul 28 13:32:43 2015 13 // Update Count : 156 14 14 // 15 15 … … 27 27 28 28 namespace ControlStruct { 29 LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {30 if ( from != 0 ) {31 UsageLoc loc; loc.stmt = from;32 usage.push_back( loc );33 }34 }35 36 LabelFixer::Entry::Entry( Statement *to, Expression *from ) : definition ( to ) {37 if ( from != 0 ) {38 UsageLoc loc; loc.expr = from;39 usage.push_back( loc );40 }41 }42 43 44 29 bool LabelFixer::Entry::insideLoop() { 45 30 return ( dynamic_cast< ForStmt * > ( definition ) || 46 31 dynamic_cast< WhileStmt * > ( definition ) ); 47 }48 49 void LabelFixer::Entry::UsageLoc::accept( Visitor & visitor ) {50 if ( dynamic_cast< Statement * >( stmt ) ) {51 stmt->accept( visitor );52 } else {53 expr->accept( visitor );54 }55 32 } 56 33 … … 77 54 // prune to at most one label definition for each statement 78 55 void LabelFixer::visit( Statement *stmt ) { 79 currentStatement = stmt;80 56 std::list< Label > &labels = stmt->get_labels(); 81 57 … … 83 59 // only remember one label for each statement 84 60 Label current = setLabelsDef( labels, stmt ); 85 labels.clear();86 labels.push_front( current );87 61 } // if 88 62 } … … 130 104 } else { 131 105 // used previously, but undefined until now -> link with this entry 132 Entry * oldEntry = labelTable[ *i ]; 133 e->add_uses( *oldEntry ); 106 delete labelTable[ *i ]; 134 107 labelTable[ *i ] = e; 135 108 } // if … … 141 114 } 142 115 143 // Remember all uses of a label.116 // A label was used, add it ot the table if it isn't already there 144 117 template< typename UsageNode > 145 118 void LabelFixer::setLabelsUsg( Label orgValue, UsageNode *use ) { 146 119 assert( use != 0 ); 147 120 148 if ( labelTable.find( orgValue ) != labelTable.end() ) { 149 // the label has been defined or used before 150 labelTable[ orgValue ]->add_use( use ); 151 } else { 152 labelTable[ orgValue ] = new Entry( 0, use ); 121 // add label with an unknown origin 122 if ( labelTable.find( orgValue ) == labelTable.end() ) { 123 labelTable[ orgValue ] = new Entry( 0 ); 153 124 } 154 125 } 155 126 156 class LabelGetter : public Visitor { 157 public: 158 LabelGetter( Label &label ) : label( label ) {} 159 160 virtual void visit( BranchStmt * branchStmt ) { 161 label = branchStmt->get_target(); 162 } 163 164 virtual void visit( UntypedExpr * untyped ) { 165 NameExpr * name = dynamic_cast< NameExpr * >( untyped->get_function() ); 166 assert( name ); 167 assert( name->get_name() == "&&" ); 168 NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() ); 169 assert( arg ); 170 label = arg->get_name(); 171 } 172 173 private: 174 Label &label; 175 }; 176 177 class LabelSetter : public Visitor { 178 public: 179 LabelSetter( Label label ) : label( label ) {} 180 181 virtual void visit( BranchStmt * branchStmt ) { 182 branchStmt->set_target( label ); 183 } 184 185 virtual void visit( UntypedExpr * untyped ) { 186 NameExpr * name = dynamic_cast< NameExpr * >( untyped->get_function() ); 187 assert( name ); 188 assert( name->get_name() == "&&" ); 189 NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() ); 190 assert( arg ); 191 arg->set_name( label ); 192 } 193 194 private: 195 Label label; 196 }; 197 198 // Ultimately builds a table that maps a label to its defining statement. 199 // In the process, 127 // Builds a table that maps a label to its defining statement. 200 128 std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) { 201 std::map< Statement *, Entry * > def_us; 202 203 // combine the entries for all labels that target the same location 204 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) { 205 Entry *e = i->second; 206 207 if ( def_us.find ( e->get_definition() ) == def_us.end() ) { 208 def_us[ e->get_definition() ] = e; 209 } else if ( e->used() ) { 210 def_us[ e->get_definition() ]->add_uses( *e ); 129 std::map< Label, Statement * > *ret = new std::map< Label, Statement * >(); 130 for ( std::map< Label, Entry * >::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) { 131 if ( ! i->second->defined() ) { 132 throw SemanticError( "Use of undefined label: " + i->first ); 211 133 } 212 } 213 214 // create a unique label for each target location. 215 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) { 216 Statement *to = (*i).first; 217 Entry * entry = (*i).second; 218 std::list< Entry::UsageLoc > &from = entry->get_uses(); 219 220 // no label definition found 221 if ( to == 0 ) { 222 Label undef; 223 LabelGetter getLabel( undef ); 224 from.back().accept( getLabel ); 225 // Label undef = getLabel( from.back()->get_target() ); 226 throw SemanticError ( "'" + undef + "' label not defined"); 227 } // if 228 229 // generate a new label, and attach it to its defining statement as the only label on that statement 230 Label finalLabel = generator->newLabel( to->get_labels().back() ); 231 entry->set_label( finalLabel ); 232 233 to->get_labels().clear(); 234 to->get_labels().push_back( finalLabel ); 235 236 // redirect each of the source branch statements to the new target label 237 for ( std::list< Entry::UsageLoc >::iterator j = from.begin(); j != from.end(); ++j ) { 238 LabelSetter setLabel( finalLabel ); 239 (*j).accept( setLabel ); 240 // setLabel( *j, finalLabel ); 241 242 // BranchStmt *jump = *j; 243 // assert( jump != 0 ); 244 // jump->set_target( finalLabel ); 245 } // for 246 } // for 247 248 // create a table where each label maps to its defining statement 249 std::map< Label, Statement * > *ret = new std::map< Label, Statement * >(); 250 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) { 251 (*ret)[ (*i).second->get_label() ] = (*i).first; 134 (*ret)[ i->first ] = i->second->get_definition(); 252 135 } 253 136 -
src/ControlStruct/LabelFixer.h
r51b986f re766208 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Jun 29 17:24:39201513 // Update Count : 2911 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue Jul 28 13:09:02 2015 13 // Update Count : 31 14 14 // 15 15 … … 63 63 class Entry { 64 64 public: 65 union UsageLoc {66 Statement * stmt;67 Expression * expr;68 69 void accept( Visitor &visitor );70 };71 72 65 Entry( Statement *to ) : definition( to ) {} 73 Entry( Statement *to, Statement *from );74 Entry( Statement *to, Expression *from );75 bool used() { return ( usage.empty() ); }76 66 bool defined() { return ( definition != 0 ); } 77 67 bool insideLoop(); … … 83 73 void set_definition( Statement *def ) { definition = def; } 84 74 85 std::list< UsageLoc > &get_uses() { return usage; }86 void add_use( Statement *use ) {87 UsageLoc loc;88 loc.stmt = use;89 usage.push_back( loc );90 }91 void add_use( Expression *use ) {92 UsageLoc loc;93 loc.expr = use;94 usage.push_back( loc );95 }96 97 void add_uses ( Entry &other ) { usage.insert( usage.end(), other.usage.begin(), other.usage.end() ); }98 75 private: 99 76 Label label; 100 77 Statement *definition; 101 std::list<UsageLoc> usage;102 78 }; 103 79 104 80 std::map < Label, Entry *> labelTable; 105 81 LabelGenerator *generator; 106 Statement * currentStatement;107 82 }; 108 83 } // namespace ControlStruct
Note: See TracChangeset
for help on using the changeset viewer.