- File:
-
- 1 edited
-
src/ControlStruct/LabelFixer.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/LabelFixer.cc
r1869adf r843054c2 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Wed Jun 24 16:24:34201513 // Update Count : 1 4111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 15:25:59 2015 13 // Update Count : 1 14 14 // 15 15 … … 19 19 #include "LabelFixer.h" 20 20 #include "MLEMutator.h" 21 #include "SynTree/Expression.h"22 21 #include "SynTree/Statement.h" 23 22 #include "SynTree/Declaration.h" 24 23 #include "utility.h" 25 24 26 #include <iostream>27 28 25 namespace ControlStruct { 29 26 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 } 27 if ( from != 0 ) 28 usage.push_back( from ); 34 29 } 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 30 44 31 bool LabelFixer::Entry::insideLoop() { 45 32 return ( dynamic_cast< ForStmt * > ( 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 } 33 dynamic_cast< WhileStmt * > ( definition ) ); 55 34 } 56 35 … … 61 40 62 41 void LabelFixer::visit( FunctionDecl *functionDecl ) { 63 maybeAccept( functionDecl->get_statements(), *this ); 42 if ( functionDecl->get_statements() != 0 ) 43 functionDecl->get_statements()->accept( *this ); 64 44 65 45 MLEMutator mlemut( resolveJumps(), generator ); … … 67 47 } 68 48 69 // prune to at most one label definition for each statement70 49 void LabelFixer::visit( Statement *stmt ) { 71 currentStatement = stmt;72 50 std::list< Label > &labels = stmt->get_labels(); 73 51 74 52 if ( ! labels.empty() ) { 75 // only remember one label for each statement76 53 Label current = setLabelsDef( labels, stmt ); 77 54 labels.clear(); … … 81 58 82 59 void LabelFixer::visit( BranchStmt *branchStmt ) { 83 visit ( ( Statement * )branchStmt ); 60 visit ( ( Statement * )branchStmt ); // the labels this statement might have 84 61 85 // for labeled branches, add an entry to the label table 86 Label target = branchStmt->get_target(); 87 if ( target != "" ) { 62 Label target; 63 if ( (target = branchStmt->get_target()) != "" ) { 88 64 setLabelsUsg( target, branchStmt ); 89 } 65 } //else /* computed goto or normal exit-loop statements */ 90 66 } 91 67 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 } 68 Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) { 69 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 103 85 } 104 86 87 Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) { 88 assert( use != 0 ); 105 89 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 108 Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) { 109 assert( definition != 0 ); 110 assert( llabel.size() > 0 ); 90 if ( labelTable.find( orgValue ) != labelTable.end() ) 91 labelTable[ orgValue ]->add_use( use ); // the label has been defined or used before 92 else 93 labelTable[ orgValue ] = new Entry( 0, use ); 111 94 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(); 95 return labelTable[ orgValue ]->get_label(); 133 96 } 134 97 135 // Remember all uses of a label.136 template< typename UsageNode >137 void LabelFixer::setLabelsUsg( Label orgValue, UsageNode *use ) {138 assert( use != 0 );139 140 if ( labelTable.find( orgValue ) != labelTable.end() ) {141 // the label has been defined or used before142 labelTable[ orgValue ]->add_use( use );143 } else {144 labelTable[ orgValue ] = new Entry( 0, use );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,192 98 std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) { 193 99 std::map< Statement *, Entry * > def_us; 194 100 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 ) { 101 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) { 197 102 Entry *e = i->second; 198 103 199 if ( def_us.find ( e->get_definition() ) == def_us.end() ) {104 if ( def_us.find ( e->get_definition() ) == def_us.end() ) 200 105 def_us[ e->get_definition() ] = e; 201 } else if ( e->used() ) {202 def_us[ e->get_definition() ]->add_uses( *e );203 }106 else 107 if ( e->used() ) 108 def_us[ e->get_definition() ]->add_uses( e->get_uses() ); 204 109 } 205 110 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) {111 // get rid of labelTable 112 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) { 208 113 Statement *to = (*i).first; 209 Entry * entry = (*i).second; 210 std::list< Entry::UsageLoc > &from = entry->get_uses(); 114 std::list< Statement *> &from = (*i).second->get_uses(); 115 Label finalLabel = generator->newLabel(); 116 (*i).second->set_label( finalLabel ); 211 117 212 // no label definition found213 118 if ( to == 0 ) { 214 Label undef;215 Label Getter getLabel( undef);216 from.back().accept( getLabel );217 // Label undef = getLabel( 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(); 218 123 throw SemanticError ( "'" + undef + "' label not defined"); 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 ); 124 } 224 125 225 126 to->get_labels().clear(); 226 127 to->get_labels().push_back( finalLabel ); 227 128 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 ); 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 ); 237 133 } // for 238 134 } // for 239 135 240 // create a table where each label maps to its defining statement136 // reverse table 241 137 std::map< Label, Statement * > *ret = new std::map< Label, Statement * >(); 242 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++ ) 243 139 (*ret)[ (*i).second->get_label() ] = (*i).first; 244 }245 140 246 141 return ret;
Note:
See TracChangeset
for help on using the changeset viewer.