Changeset 937e51d for src/ControlStruct
- 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. - Location:
- src/ControlStruct
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/ChooseMutator.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:31:39201513 // Update Count : 211 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Jun 03 15:30:20 2015 13 // Update Count : 5 14 14 // 15 15 … … 44 44 std::list< Statement * > &stmts = caseStmt->get_statements(); 45 45 46 // the difference between switch and choose is that switch has an implicit fallthrough 47 // to the next case, whereas choose has an implicit break at the end of the current case. 48 // thus to transform a choose statement into a switch, we only need to insert breaks at the 49 // end of any case that doesn't already end in a break and that doesn't end in a fallthru 50 46 51 if ( insideChoose ) { 47 52 BranchStmt *posBrk; -
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; -
src/ControlStruct/LabelFixer.h
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:31:55 201513 // Update Count : 311 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue Jun 23 15:47:25 2015 13 // Update Count : 28 14 14 // 15 15 … … 53 53 virtual void visit( DeclStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 54 54 virtual void visit( BranchStmt *branchStmt ); 55 virtual void visit( UntypedExpr *untyped ); 55 56 56 57 Label setLabelsDef( std::list< Label > &, Statement *definition ); 57 Label setLabelsUsg( Label, Statement *usage = 0 ); 58 template< typename UsageNode > 59 void setLabelsUsg( Label, UsageNode *usage = 0 ); 58 60 59 61 private: 60 62 class Entry { 61 public: 62 Entry( Statement *to = 0, Statement *from = 0 ); 63 public: 64 union UsageLoc { 65 Statement * stmt; 66 Expression * expr; 67 68 void accept( Visitor &visitor ); 69 }; 70 71 Entry( Statement *to ) : definition( to ) {} 72 Entry( Statement *to, Statement *from ); 73 Entry( Statement *to, Expression *from ); 63 74 bool used() { return ( usage.empty() ); } 64 75 bool defined() { return ( definition != 0 ); } … … 66 77 67 78 Label get_label() const { return label; } 79 void set_label( Label lab ) { label = lab; } 80 68 81 Statement *get_definition() const { return definition; } 69 std::list< Statement *> &get_uses() { return usage; }70 71 void add_use ( Statement *use ) { usage.push_back( use ); }72 void add_uses ( std::list<Statement *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }73 82 void set_definition( Statement *def ) { definition = def; } 74 83 75 void set_label( Label lab ) { label = lab; } 76 Label gset_label() const { return label; } 84 std::list< UsageLoc > &get_uses() { return usage; } 85 void add_use( Statement *use ) { 86 UsageLoc loc; 87 loc.stmt = use; 88 usage.push_back( loc ); 89 } 90 void add_use( Expression *use ) { 91 UsageLoc loc; 92 loc.expr = use; 93 usage.push_back( loc ); 94 } 95 96 void add_uses ( Entry &other ) { usage.insert( usage.end(), other.usage.begin(), usage.end() ); } 77 97 private: 78 98 Label label; 79 99 Statement *definition; 80 std::list< Statement *> usage;100 std::list<UsageLoc> usage; 81 101 }; 82 102 83 103 std::map < Label, Entry *> labelTable; 84 104 LabelGenerator *generator; 105 Statement * currentStatement; 85 106 }; 86 107 } // namespace ControlStruct -
src/ControlStruct/LabelGenerator.cc
reb50842 r937e51d 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 15:32:04 201513 // Update Count : 212 // Last Modified On : Tue Jun 23 12:18:34 2015 13 // Update Count : 13 14 14 // 15 15 16 16 #include <iostream> 17 #include <s trstream>17 #include <sstream> 18 18 19 19 #include "LabelGenerator.h" … … 29 29 } 30 30 31 Label LabelGenerator::newLabel() { 32 std::ostrstream os; 33 os << "__L" << current++ << "__";// << std::ends; 34 os.freeze( false ); 35 std::string ret = std::string (os.str(), os.pcount()); 31 Label LabelGenerator::newLabel( std::string suffix ) { 32 std::ostringstream os; 33 os << "__L" << current++ << "__" << suffix; 34 std::string ret = os.str(); 36 35 return Label( ret ); 37 36 } -
src/ControlStruct/LabelGenerator.h
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:33:20201513 // Update Count : 311 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Jun 03 14:16:26 2015 13 // Update Count : 5 14 14 // 15 15 … … 18 18 19 19 #include "SynTree/SynTree.h" 20 #include <string> 20 21 21 22 namespace ControlStruct { … … 23 24 public: 24 25 static LabelGenerator *getGenerator(); 25 Label newLabel( );26 Label newLabel(std::string suffix = ""); 26 27 void reset() { current = 0; } 27 28 void rewind() { current--; } -
src/ControlStruct/LabelTypeChecker.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:32:15201513 // Update Count : 211 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Jun 24 16:24:48 2015 13 // Update Count : 3 14 14 // 15 15 … … 29 29 NameExpr *fname; 30 30 if ( ((fname = dynamic_cast<NameExpr *>(untypedExpr->get_function())) != 0) 31 && fname->get_name() == std::string(" LabAddress") )31 && fname->get_name() == std::string("&&") ) 32 32 std::cerr << "Taking the label of an address." << std::endl; 33 33 else { -
src/ControlStruct/MLEMutator.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 : T ue May 19 15:32:26201513 // Update Count : 211 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Jun 04 15:12:33 2015 13 // Update Count : 173 14 14 // 15 15 … … 19 19 #include "MLEMutator.h" 20 20 #include "SynTree/Statement.h" 21 #include "SynTree/Expression.h" 21 22 22 23 namespace ControlStruct { … … 26 27 } 27 28 28 CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) { 29 bool labeledBlock = false; 30 if ( !((cmpndStmt->get_labels()).empty()) ) { 31 labeledBlock = true; 32 enclosingBlocks.push_back( Entry( cmpndStmt ) ); 33 } // if 34 35 std::list< Statement * > &kids = cmpndStmt->get_kids(); 29 // break labels have to come after the statement they break out of, 30 // so mutate a statement, then if they inform us through the breakLabel field 31 // tha they need a place to jump to on a break statement, add the break label 32 // to the body of statements 33 void MLEMutator::fixBlock( std::list< Statement * > &kids ) { 36 34 for ( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) { 37 35 *k = (*k)->acceptMutator(*this); 38 36 39 37 if ( ! get_breakLabel().empty() ) { 40 std::list< Statement * >::iterator next = k ; next++;38 std::list< Statement * >::iterator next = k+1; 41 39 if ( next == kids.end() ) { 42 40 std::list<Label> ls; ls.push_back( get_breakLabel() ); 43 41 kids.push_back( new NullStmt( ls ) ); 44 } else 42 } else { 45 43 (*next)->get_labels().push_back( get_breakLabel() ); 44 } 46 45 47 46 set_breakLabel(""); 48 47 } // if 49 48 } // for 49 } 50 51 CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) { 52 bool labeledBlock = !(cmpndStmt->get_labels().empty()); 53 if ( labeledBlock ) { 54 Label brkLabel = generator->newLabel("blockBreak"); 55 enclosingBlocks.push_back( Entry( cmpndStmt, brkLabel ) ); 56 } // if 57 58 // a child statement may set the break label 59 // - if they do, attach it to the next statement 60 std::list< Statement * > &kids = cmpndStmt->get_kids(); 61 fixBlock( kids ); 50 62 51 63 if ( labeledBlock ) { 52 64 assert( ! enclosingBlocks.empty() ); 53 if ( ! enclosingBlocks.back().get_breakExit().empty() ) 54 set_breakLabel( enclosingBlocks.back().get_breakExit() ); 65 if ( ! enclosingBlocks.back().useBreakExit().empty() ) { 66 set_breakLabel( enclosingBlocks.back().useBreakExit() ); 67 } 55 68 enclosingBlocks.pop_back(); 56 69 } // if 57 70 58 //mutateAll( cmpndStmt->get_kids(), *this );59 71 return cmpndStmt; 60 72 } 61 73 62 Statement *MLEMutator::mutate( WhileStmt *whileStmt ) { 63 enclosingLoops.push_back( Entry( whileStmt ) ); 64 whileStmt->set_body ( whileStmt->get_body()->acceptMutator( *this ) ); 65 74 template< typename LoopClass > 75 Statement *MLEMutator::handleLoopStmt( LoopClass *loopStmt ) { 76 // remember this as the most recent enclosing loop, then mutate 77 // the body of the loop -- this will determine whether brkLabel 78 // and contLabel are used with branch statements 79 // and will recursively do the same to nested loops 80 Label brkLabel = generator->newLabel("loopBreak"); 81 Label contLabel = generator->newLabel("loopContinue"); 82 enclosingLoops.push_back( Entry( loopStmt, brkLabel, contLabel ) ); 83 loopStmt->set_body ( loopStmt->get_body()->acceptMutator( *this ) ); 84 85 // sanity check that the enclosing loops have been popped correctly 66 86 Entry &e = enclosingLoops.back(); 67 assert ( e == whileStmt ); 68 whileStmt->set_body( mutateLoop( whileStmt->get_body(), e ) ); 87 assert ( e == loopStmt ); 88 89 // this will take the necessary steps to add definitions of the previous 90 // two labels, if they are used. 91 loopStmt->set_body( mutateLoop( loopStmt->get_body(), e ) ); 69 92 enclosingLoops.pop_back(); 70 93 71 return whileStmt; 72 } 73 74 Statement *MLEMutator::mutate( ForStmt *forStmt ) { 75 enclosingLoops.push_back( Entry( forStmt ) ); 76 maybeMutate( forStmt->get_body(), *this ); 77 78 Entry &e = enclosingLoops.back(); 79 assert ( e == forStmt ); 80 forStmt->set_body( mutateLoop( forStmt->get_body(), e ) ); 81 enclosingLoops.pop_back(); 82 83 return forStmt; 94 return loopStmt; 95 } 96 97 Statement *MLEMutator::mutate( CaseStmt *caseStmt ) { 98 caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) ); 99 fixBlock( caseStmt->get_statements() ); 100 101 return caseStmt; 102 } 103 104 template< typename SwitchClass > 105 Statement *MLEMutator::handleSwitchStmt( SwitchClass *switchStmt ) { 106 // generate a label for breaking out of a labeled switch 107 Label brkLabel = generator->newLabel("switchBreak"); 108 enclosingSwitches.push_back( Entry(switchStmt, brkLabel) ); 109 mutateAll( switchStmt->get_branches(), *this ); 110 111 Entry &e = enclosingSwitches.back(); 112 assert ( e == switchStmt ); 113 114 // only generate break label if labeled break is used 115 if (e.isBreakUsed()) { 116 // for the purposes of keeping switch statements uniform (i.e. all statements that are 117 // direct children of a switch should be CastStmts), append the exit label + break to the 118 // last case statement; create a default case if there are no cases 119 std::list< Statement * > &branches = switchStmt->get_branches(); 120 if ( branches.empty() ) { 121 branches.push_back( CaseStmt::makeDefault() ); 122 } 123 124 if ( CaseStmt * c = dynamic_cast< CaseStmt * >( branches.back() ) ) { 125 std::list<Label> temp; temp.push_back( brkLabel ); 126 c->get_statements().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) ); 127 } else assert(0); // as of this point, all branches of a switch are still CaseStmts 128 } 129 130 assert ( enclosingSwitches.back() == switchStmt ); 131 enclosingSwitches.pop_back(); 132 return switchStmt; 84 133 } 85 134 86 135 Statement *MLEMutator::mutate( BranchStmt *branchStmt ) throw ( SemanticError ) { 136 std::string originalTarget = branchStmt->get_originalTarget(); 137 87 138 if ( branchStmt->get_type() == BranchStmt::Goto ) 88 139 return branchStmt; 89 140 90 141 // test if continue target is a loop 91 if ( branchStmt->get_type() == BranchStmt::Continue && enclosingLoops.empty() ) 92 throw SemanticError( "'continue' outside a loop" ); 142 if ( branchStmt->get_type() == BranchStmt::Continue) { 143 if ( enclosingLoops.empty() ) { 144 throw SemanticError( "'continue' outside a loop" ); 145 } else if ( std::find( enclosingLoops.begin(), enclosingLoops.end(), (*targetTable)[branchStmt->get_target()] ) == enclosingLoops.end() ) { 146 throw SemanticError( "'continue' target label must be an enclosing loop: " + originalTarget ); 147 } 148 } 93 149 94 150 if ( branchStmt->get_type() == BranchStmt::Break && (enclosingLoops.empty() && enclosingSwitches.empty() && enclosingBlocks.empty() ) ) … … 98 154 99 155 if ( targetTable->find( branchStmt->get_target() ) == targetTable->end() ) 100 throw SemanticError("The label defined in the exit loop statement does not exist ."); // shouldn't happen (since that's already checked)156 throw SemanticError("The label defined in the exit loop statement does not exist: " + originalTarget ); // shouldn't happen (since that's already checked) 101 157 102 158 std::list< Entry >::iterator check; … … 106 162 // neither in loop nor in block, checking if in switch/choose 107 163 if ( (check = std::find( enclosingSwitches.begin(), enclosingSwitches.end(), (*targetTable)[branchStmt->get_target()] )) == enclosingSwitches.end() ) 108 throw SemanticError("The target specified in the exit loop statement does not correspond to an enclosing loop."); 109 164 throw SemanticError("The target specified in the exit loop statement does not correspond to an enclosing control structure: " + originalTarget ); 165 166 // what about exiting innermost block or switch??? 110 167 if ( enclosingLoops.back() == (*check) ) 111 168 return branchStmt; // exit the innermost loop (labels unnecessary) 112 169 113 Label newLabel; 170 // branch error checks, get the appropriate label name and create a goto 171 Label exitLabel; 114 172 switch ( branchStmt->get_type() ) { 115 173 case BranchStmt::Break: 116 if ( check->get_breakExit() != "" ) 117 newLabel = check->get_breakExit(); 118 else { 119 newLabel = generator->newLabel(); 120 check->set_breakExit( newLabel ); 121 } // if 122 break; 174 assert( check->useBreakExit() != ""); 175 exitLabel = check->useBreakExit(); 176 break; 123 177 case BranchStmt::Continue: 124 if ( check->get_contExit() != "" ) 125 newLabel = check->get_contExit(); 126 else { 127 newLabel = generator->newLabel(); 128 check->set_contExit( newLabel ); 129 } // if 130 break; 178 assert( check->useContExit() != ""); 179 exitLabel = check->useContExit(); 180 break; 131 181 default: 132 return 0; // shouldn't be here182 assert(0); // shouldn't be here 133 183 } // switch 134 184 135 return new BranchStmt( std::list<Label>(), newLabel, BranchStmt::Goto ); 136 } 137 138 139 Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) { 140 Label brkLabel = generator->newLabel(); 141 enclosingSwitches.push_back( Entry(switchStmt, "", brkLabel) ); 142 mutateAll( switchStmt->get_branches(), *this ); { 143 // check if this is necessary (if there is a break to this point, otherwise do not generate 144 std::list<Label> temp; temp.push_back( brkLabel ); 145 switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) ); 146 } 147 assert ( enclosingSwitches.back() == switchStmt ); 148 enclosingSwitches.pop_back(); 149 return switchStmt; 150 } 151 152 Statement *MLEMutator::mutate( ChooseStmt *switchStmt ) { 153 Label brkLabel = generator->newLabel(); 154 enclosingSwitches.push_back( Entry(switchStmt,"", brkLabel) ); 155 mutateAll( switchStmt->get_branches(), *this ); { 156 // check if this is necessary (if there is a break to this point, otherwise do not generate 157 std::list<Label> temp; temp.push_back( brkLabel ); 158 switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) ); 159 } 160 assert ( enclosingSwitches.back() == switchStmt ); 161 enclosingSwitches.pop_back(); 162 return switchStmt; 185 return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto ); 163 186 } 164 187 165 188 Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) { 189 // ensure loop body is a block 166 190 CompoundStmt *newBody; 167 191 if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) { … … 170 194 } // if 171 195 172 Label endLabel = e.get_contExit(); 173 174 if ( e.get_breakExit() != "" ) { 175 if ( endLabel == "" ) endLabel = generator->newLabel(); 176 // check for whether this label is used or not, so as to not generate extraneous gotos 177 if (e.breakExitUsed) 178 newBody->get_kids().push_back( new BranchStmt( std::list< Label >(), endLabel, BranchStmt::Goto ) ); 179 // xxx 180 //std::list< Label > ls; ls.push_back( e.get_breakExit() ); 181 set_breakLabel( e.get_breakExit() ); 182 //newBody->get_kids().push_back( new BranchStmt( ls, "", BranchStmt::Break ) ); 183 } // if 184 185 if ( e.get_breakExit() != "" || e.get_contExit() != "" ) { 186 if (dynamic_cast< NullStmt *>( newBody->get_kids().back() )) 187 newBody->get_kids().back()->get_labels().push_back( endLabel ); 188 else { 189 std::list < Label > ls; ls.push_back( endLabel ); 190 newBody->get_kids().push_back( new NullStmt( ls ) ); 191 } // if 192 } // if 196 // only generate these when needed 197 198 if ( e.isContUsed() ) { 199 // continue label goes in the body as the last statement 200 std::list< Label > labels; labels.push_back( e.useContExit() ); 201 newBody->get_kids().push_back( new NullStmt( labels ) ); 202 } 203 204 if ( e.isBreakUsed() ) { 205 // break label goes after the loop -- it'll get set by the 206 // outer mutator if we do this 207 set_breakLabel( e.useBreakExit() ); 208 } 193 209 194 210 return newBody; 195 211 } 196 212 197 //*** Entry's methods 198 void MLEMutator::Entry::set_contExit( Label l ) { 199 assert ( contExit == "" || contExit == l ); 200 contExit = l; 201 } 202 203 void MLEMutator::Entry::set_breakExit( Label l ) { 204 assert ( breakExit == "" || breakExit == l ); 205 breakExit = l; 206 } 213 Statement *MLEMutator::mutate( WhileStmt *whileStmt ) { 214 return handleLoopStmt( whileStmt ); 215 } 216 217 Statement *MLEMutator::mutate( ForStmt *forStmt ) { 218 return handleLoopStmt( forStmt ); 219 } 220 221 Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) { 222 return handleSwitchStmt( switchStmt ); 223 } 224 225 Statement *MLEMutator::mutate( ChooseStmt *switchStmt ) { 226 return handleSwitchStmt( switchStmt ); 227 } 228 207 229 } // namespace ControlStruct 208 230 -
src/ControlStruct/MLEMutator.h
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:32:39201513 // Update Count : 311 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Jun 03 15:06:36 2015 13 // Update Count : 25 14 14 // 15 15 … … 38 38 Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError ); 39 39 40 Statement *mutate( CaseStmt *caseStmt ); 40 41 Statement *mutate( SwitchStmt *switchStmt ); 41 42 Statement *mutate( ChooseStmt *switchStmt ); … … 48 49 class Entry { 49 50 public: 50 explicit Entry( Statement *_loop = 0, Label _contExit = Label(""), Label _breakExit = Label("") ) :51 loop( _loop ), contExit( _contExit ), breakExit( _breakExit ), contExitUsed( false ), breakExitUsed( false) {}51 explicit Entry( Statement *_loop, Label _breakExit, Label _contExit = Label("") ) : 52 loop( _loop ), breakExit( _breakExit ), contExit( _contExit ), breakUsed(false), contUsed(false) {} 52 53 53 54 bool operator==( const Statement *stmt ) { return ( loop == stmt ); } … … 58 59 Statement *get_loop() const { return loop; } 59 60 60 Label get_contExit() const {return contExit; }61 void set_contExit( Label );61 Label useContExit() { contUsed = true; return contExit; } 62 Label useBreakExit() { breakUsed = true; return breakExit; } 62 63 63 Label get_breakExit() const { return breakExit; }64 void set_breakExit( Label );64 bool isContUsed() const { return contUsed; } 65 bool isBreakUsed() const { return breakUsed; } 65 66 66 67 private: 67 68 Statement *loop; 68 Label contExit, breakExit; 69 public: // hack, provide proper [sg]etters 70 bool contExitUsed, breakExitUsed; 69 Label breakExit, contExit; 70 bool breakUsed, contUsed; 71 71 }; 72 72 … … 75 75 Label breakLabel; 76 76 LabelGenerator *generator; 77 78 template< typename LoopClass > 79 Statement *handleLoopStmt( LoopClass *loopStmt ); 80 81 template< typename SwitchClass > 82 Statement *handleSwitchStmt( SwitchClass *switchStmt ); 83 84 void fixBlock( std::list< Statement * > &kids ); 77 85 }; 78 86 } // namespace ControlStruct -
src/ControlStruct/Mutate.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:32:52201513 // Update Count : 211 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Jun 03 23:08:43 2015 13 // Update Count : 5 14 14 // 15 15 … … 37 37 void mutate( std::list< Declaration * > translationUnit ) { 38 38 // ForExprMutator formut; 39 40 // normalizes label definitions and generates multi-level 41 // exit labels 39 42 LabelFixer lfix; 43 44 // transform choose statements into switch statements 40 45 ChooseMutator chmut; 46 47 // expand case ranges and turn fallthru into a null statement 41 48 CaseRangeMutator ranges; // has to run after ChooseMutator 49 42 50 //ExceptMutator exc; 43 51 // LabelTypeChecker lbl; -
src/ControlStruct/module.mk
reb50842 r937e51d 1 ######################### -*- Mode: Makefile-Gmake -*- ######################## 2 ## 3 ## Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo 4 ## 5 ## The contents of this file are covered under the licence agreement in the 6 ## file "LICENCE" distributed with Cforall. 7 ## 8 ## module.mk -- 9 ## 10 ## Author : Richard C. Bilson 11 ## Created On : Mon Jun 1 17:49:17 2015 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Mon Jun 1 17:51:45 2015 14 ## Update Count : 1 15 ############################################################################### 16 1 17 SRC += ControlStruct/LabelGenerator.cc \ 2 18 ControlStruct/LabelFixer.cc \ 3 19 ControlStruct/MLEMutator.cc \ 4 20 ControlStruct/CaseRangeMutator.cc \ … … 6 22 ControlStruct/ChooseMutator.cc \ 7 23 ControlStruct/ForExprMutator.cc \ 8 ControlStruct/LabelTypeChecker.cc \ 9 $(NULL) 24 ControlStruct/LabelTypeChecker.cc 10 25
Note:
See TracChangeset
for help on using the changeset viewer.