Changeset 937e51d for src/ControlStruct/LabelFixer.cc
- Timestamp:
- Jun 26, 2015, 4:00:26 PM (10 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:
- 0df292b, e0ff3e6
- Parents:
- eb50842 (diff), 1869adf (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/LabelFixer.cc
reb50842 r937e51d 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 : Tue May 19 15:25:59201513 // Update Count : 1 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Jun 24 16:24:34 2015 13 // Update Count : 141 14 14 // 15 15 … … 19 19 #include "LabelFixer.h" 20 20 #include "MLEMutator.h" 21 #include "SynTree/Expression.h" 21 22 #include "SynTree/Statement.h" 22 23 #include "SynTree/Declaration.h" 23 24 #include "utility.h" 24 25 26 #include <iostream> 27 25 28 namespace ControlStruct { 26 29 LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) { 27 if ( from != 0 ) 28 usage.push_back( from ); 29 } 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 30 43 31 44 bool LabelFixer::Entry::insideLoop() { 32 45 return ( dynamic_cast< ForStmt * > ( definition ) || 33 dynamic_cast< WhileStmt * > ( definition ) ); 46 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 } 34 55 } 35 56 … … 40 61 41 62 void LabelFixer::visit( FunctionDecl *functionDecl ) { 42 if ( functionDecl->get_statements() != 0 ) 43 functionDecl->get_statements()->accept( *this ); 63 maybeAccept( functionDecl->get_statements(), *this ); 44 64 45 65 MLEMutator mlemut( resolveJumps(), generator ); … … 47 67 } 48 68 69 // prune to at most one label definition for each statement 49 70 void LabelFixer::visit( Statement *stmt ) { 71 currentStatement = stmt; 50 72 std::list< Label > &labels = stmt->get_labels(); 51 73 52 74 if ( ! labels.empty() ) { 75 // only remember one label for each statement 53 76 Label current = setLabelsDef( labels, stmt ); 54 77 labels.clear(); … … 58 81 59 82 void LabelFixer::visit( BranchStmt *branchStmt ) { 60 visit ( ( Statement * )branchStmt ); // the labels this statement might have 61 62 Label target; 63 if ( (target = branchStmt->get_target()) != "" ) { 83 visit ( ( Statement * )branchStmt ); 84 85 // for labeled branches, add an entry to the label table 86 Label target = branchStmt->get_target(); 87 if ( target != "" ) { 64 88 setLabelsUsg( target, branchStmt ); 65 } //else /* computed goto or normal exit-loop statements */ 66 } 67 89 } 90 } 91 92 void LabelFixer::visit( UntypedExpr *untyped ) { 93 if ( NameExpr * func = dynamic_cast< NameExpr * >( untyped->get_function() ) ) { 94 if ( func->get_name() == "&&" ) { 95 NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() ); 96 Label target = arg->get_name(); 97 assert( target != "" ); 98 setLabelsUsg( target, untyped ); 99 } else { 100 Visitor::visit( untyped ); 101 } 102 } 103 } 104 105 106 // sets the definition of the labelTable entry to be the provided 107 // statement for every label in the list parameter. Happens for every kind of statement 68 108 Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) { 69 109 assert( definition != 0 ); 70 Entry *entry = new Entry( definition ); 71 bool used = false; 72 73 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) 74 if ( labelTable.find( *i ) == labelTable.end() ) 75 { used = true; labelTable[ *i ] = entry; } // undefined and unused 76 else 77 if ( labelTable[ *i ]->defined() ) 78 throw SemanticError( "Duplicate definition of label: " + *i ); 79 else 80 labelTable[ *i ]->set_definition( definition ); 81 82 if ( ! used ) delete entry; 83 84 return labelTable[ llabel.front() ]->get_label(); // this *must* exist 85 } 86 87 Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) { 110 assert( llabel.size() > 0 ); 111 112 Entry * e = new Entry( definition ); 113 114 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) { 115 if ( labelTable.find( *i ) == labelTable.end() ) { 116 // all labels on this statement need to use the same entry, so this should only be created once 117 // undefined and unused until now, add an entry 118 labelTable[ *i ] = e; 119 } else if ( labelTable[ *i ]->defined() ) { 120 // defined twice, error 121 throw SemanticError( "Duplicate definition of label: " + *i ); 122 } else { 123 // used previously, but undefined until now -> link with this entry 124 Entry * oldEntry = labelTable[ *i ]; 125 e->add_uses( *oldEntry ); 126 labelTable[ *i ] = e; 127 } // if 128 } // for 129 130 // produce one of the labels attached to this statement to be 131 // temporarily used as the canonical label 132 return labelTable[ llabel.front() ]->get_label(); 133 } 134 135 // Remember all uses of a label. 136 template< typename UsageNode > 137 void LabelFixer::setLabelsUsg( Label orgValue, UsageNode *use ) { 88 138 assert( use != 0 ); 89 139 90 if ( labelTable.find( orgValue ) != labelTable.end() ) 91 labelTable[ orgValue ]->add_use( use ); // the label has been defined or used before 92 else 140 if ( labelTable.find( orgValue ) != labelTable.end() ) { 141 // the label has been defined or used before 142 labelTable[ orgValue ]->add_use( use ); 143 } else { 93 144 labelTable[ orgValue ] = new Entry( 0, use ); 94 95 return labelTable[ orgValue ]->get_label(); 96 } 97 145 } 146 } 147 148 class LabelGetter : public Visitor { 149 public: 150 LabelGetter( Label &label ) : label( label ) {} 151 152 virtual void visit( BranchStmt * branchStmt ) { 153 label = branchStmt->get_target(); 154 } 155 156 virtual void visit( UntypedExpr * untyped ) { 157 NameExpr * name = dynamic_cast< NameExpr * >( untyped->get_function() ); 158 assert( name ); 159 assert( name->get_name() == "&&" ); 160 NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() ); 161 assert( arg ); 162 label = arg->get_name(); 163 } 164 165 private: 166 Label &label; 167 }; 168 169 class LabelSetter : public Visitor { 170 public: 171 LabelSetter( Label label ) : label( label ) {} 172 173 virtual void visit( BranchStmt * branchStmt ) { 174 branchStmt->set_target( label ); 175 } 176 177 virtual void visit( UntypedExpr * untyped ) { 178 NameExpr * name = dynamic_cast< NameExpr * >( untyped->get_function() ); 179 assert( name ); 180 assert( name->get_name() == "&&" ); 181 NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() ); 182 assert( arg ); 183 arg->set_name( label ); 184 } 185 186 private: 187 Label label; 188 }; 189 190 // Ultimately builds a table that maps a label to its defining statement. 191 // In the process, 98 192 std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) { 99 193 std::map< Statement *, Entry * > def_us; 100 194 101 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) { 195 // combine the entries for all labels that target the same location 196 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) { 102 197 Entry *e = i->second; 103 198 104 if ( def_us.find ( e->get_definition() ) == def_us.end() ) 199 if ( def_us.find ( e->get_definition() ) == def_us.end() ) { 105 200 def_us[ e->get_definition() ] = e; 106 else107 if ( e->used() )108 def_us[ e->get_definition() ]->add_uses( e->get_uses() );109 } 110 111 // get rid of labelTable112 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++) {201 } else if ( e->used() ) { 202 def_us[ e->get_definition() ]->add_uses( *e ); 203 } 204 } 205 206 // create a unique label for each target location. 207 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) { 113 208 Statement *to = (*i).first; 114 std::list< Statement *> &from = (*i).second->get_uses();115 Label finalLabel = generator->newLabel();116 (*i).second->set_label( finalLabel ); 117 209 Entry * entry = (*i).second; 210 std::list< Entry::UsageLoc > &from = entry->get_uses(); 211 212 // no label definition found 118 213 if ( to == 0 ) { 119 BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());120 Label undef("");121 if ( first_use != 0 )122 undef = first_use->get_target();214 Label undef; 215 LabelGetter getLabel( undef ); 216 from.back().accept( getLabel ); 217 // Label undef = getLabel( from.back()->get_target() ); 123 218 throw SemanticError ( "'" + undef + "' label not defined"); 124 } 219 } // if 220 221 // generate a new label, and attach it to its defining statement as the only label on that statement 222 Label finalLabel = generator->newLabel( to->get_labels().back() ); 223 entry->set_label( finalLabel ); 125 224 126 225 to->get_labels().clear(); 127 226 to->get_labels().push_back( finalLabel ); 128 227 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 ); 228 // redirect each of the source branch statements to the new target label 229 for ( std::list< Entry::UsageLoc >::iterator j = from.begin(); j != from.end(); ++j ) { 230 LabelSetter setLabel( finalLabel ); 231 (*j).accept( setLabel ); 232 // setLabel( *j, finalLabel ); 233 234 // BranchStmt *jump = *j; 235 // assert( jump != 0 ); 236 // jump->set_target( finalLabel ); 133 237 } // for 134 238 } // for 135 239 136 // reverse table240 // create a table where each label maps to its defining statement 137 241 std::map< Label, Statement * > *ret = new std::map< Label, Statement * >(); 138 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ )242 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) { 139 243 (*ret)[ (*i).second->get_label() ] = (*i).first; 244 } 140 245 141 246 return ret;
Note:
See TracChangeset
for help on using the changeset viewer.