Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    r1869adf r843054c2  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jun 24 16:24:34 2015
    13 // Update Count     : 141
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 15:25:59 2015
     13// Update Count     : 1
    1414//
    1515
     
    1919#include "LabelFixer.h"
    2020#include "MLEMutator.h"
    21 #include "SynTree/Expression.h"
    2221#include "SynTree/Statement.h"
    2322#include "SynTree/Declaration.h"
    2423#include "utility.h"
    2524
    26 #include <iostream>
    27 
    2825namespace ControlStruct {
    2926        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 );
    3429        }
    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 
    4330
    4431        bool LabelFixer::Entry::insideLoop() {
    4532                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 )  );
    5534        }
    5635
     
    6140
    6241        void LabelFixer::visit( FunctionDecl *functionDecl ) {
    63                 maybeAccept( functionDecl->get_statements(), *this );
     42                if ( functionDecl->get_statements() != 0 )
     43                        functionDecl->get_statements()->accept( *this );
    6444
    6545                MLEMutator mlemut( resolveJumps(), generator );
     
    6747        }
    6848
    69         // prune to at most one label definition for each statement
    7049        void LabelFixer::visit( Statement *stmt ) {
    71                 currentStatement = stmt;
    7250                std::list< Label > &labels = stmt->get_labels();
    7351
    7452                if ( ! labels.empty() ) {
    75                         // only remember one label for each statement
    7653                        Label current = setLabelsDef( labels, stmt );
    7754                        labels.clear();
     
    8158
    8259        void LabelFixer::visit( BranchStmt *branchStmt ) {
    83                 visit ( ( Statement * )branchStmt );
     60                visit ( ( Statement * )branchStmt );  // the labels this statement might have
    8461
    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()) != "" ) {
    8864                        setLabelsUsg( target, branchStmt );
    89                 }
     65                } //else       /* computed goto or normal exit-loop statements */
    9066        }
    9167
    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
    10385        }
    10486
     87        Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
     88                assert( use != 0 );
    10589
    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 );
    11194
    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();
    13396        }
    13497
    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 before
    142                         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,
    19298        std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
    19399                std::map< Statement *, Entry * > def_us;
    194100
    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++ ) {
    197102                        Entry *e = i->second;
    198103
    199                         if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
     104                        if ( def_us.find ( e->get_definition() ) == def_us.end() )
    200105                                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() );
    204109                }
    205110
    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++ ) {
    208113                        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 );
    211117
    212                         // no label definition found
    213118                        if ( to == 0 ) {
    214                                 Label undef;
    215                                 LabelGetter 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();
    218123                                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                        }
    224125
    225126                        to->get_labels().clear();
    226127                        to->get_labels().push_back( finalLabel );
    227128
    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 );
    237133                        } // for
    238134                } // for
    239135
    240                 // create a table where each label maps to its defining statement
     136                // reverse table
    241137                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++ )
    243139                        (*ret)[ (*i).second->get_label() ] = (*i).first;
    244                 }
    245140
    246141                return ret;
Note: See TracChangeset for help on using the changeset viewer.