Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    r46cbfe1 rbe5aa1b  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 29 15:57:12 2015
    13 // Update Count     : 82
     12// Last Modified On : Wed May 27 16:16:14 2015
     13// Update Count     : 4
    1414//
    1515
     
    2323#include "utility.h"
    2424
    25 #include <iostream>
    26 
    2725namespace ControlStruct {
    28         LabelFixer::Entry::Entry( Statement *to, BranchStmt *from ) : definition ( to ) {
     26        LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {
    2927                if ( from != 0 )
    3028                        usage.push_back( from );
     
    3331        bool LabelFixer::Entry::insideLoop() {
    3432                return ( dynamic_cast< ForStmt * > ( definition ) ||
    35                         dynamic_cast< WhileStmt * > ( definition )  );
     33                                 dynamic_cast< WhileStmt * > ( definition )  );
    3634        }
    3735
     
    4846        }
    4947
    50         // prune to at most one label definition for each statement
    5148        void LabelFixer::visit( Statement *stmt ) {
    5249                std::list< Label > &labels = stmt->get_labels();
    5350
    5451                if ( ! labels.empty() ) {
    55                         // only remember one label for each statement
    5652                        Label current = setLabelsDef( labels, stmt );
    5753                        labels.clear();
     
    6157
    6258        void LabelFixer::visit( BranchStmt *branchStmt ) {
    63                 visit ( ( Statement * )branchStmt );
     59                visit ( ( Statement * )branchStmt );  // the labels this statement might have
    6460
    65                 // for labeled branches, add an entry to the label table
    66                 Label target = branchStmt->get_target();
    67                 if ( target != "" ) {
     61                Label target;
     62                if ( (target = branchStmt->get_target()) != "" ) {
    6863                        setLabelsUsg( target, branchStmt );
    69                 }
     64                } //else       /* computed goto or normal exit-loop statements */
    7065        }
    7166
    72         // sets the definition of the labelTable entry to be the provided
    73         // statement for every label in the list parameter. Happens for every kind of statement
    7467        Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
    7568                assert( definition != 0 );
    76                 assert( llabel.size() > 0 );
     69                Entry *entry = new Entry( definition );
     70                bool used = false;
    7771
    78                 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) {
    79                         if ( labelTable.find( *i ) == labelTable.end() ) {
    80                                 // undefined and unused until now, add an entry
    81                                 labelTable[ *i ] =  new Entry( definition );
    82                         } else if ( labelTable[ *i ]->defined() ) {\
    83                                 // defined twice, error
    84                                 throw SemanticError( "Duplicate definition of label: " + *i );
    85                         }       else {
    86                                 // used previously, but undefined until now -> set its definition to this location
    87                                 labelTable[ *i ]->set_definition( definition );
    88                         } // if
    89                 } // for
     72                for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ )
     73                        if ( labelTable.find( *i ) == labelTable.end() )
     74                                { used = true; labelTable[ *i ] = entry; } // undefined and unused
     75                        else
     76                                if ( labelTable[ *i ]->defined() )
     77                                        throw SemanticError( "Duplicate definition of label: " + *i );
     78                                else
     79                                        labelTable[ *i ]->set_definition( definition );
    9080
    91                 // produce one of the labels attached to this statement to be
    92                 // temporarily used as the canonical label
    93                 return labelTable[ llabel.front() ]->get_label();
     81                if ( ! used ) delete entry;
     82
     83                return labelTable[ llabel.front() ]->get_label();  // this *must* exist
    9484        }
    9585
    96         // Remember all uses of a label.
    97         void LabelFixer::setLabelsUsg( Label orgValue, BranchStmt *use ) {
     86        Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
    9887                assert( use != 0 );
    9988
    100                 if ( labelTable.find( orgValue ) != labelTable.end() ) {
    101                         // the label has been defined or used before
    102                         labelTable[ orgValue ]->add_use( use );
    103                 } else {
     89                if ( labelTable.find( orgValue ) != labelTable.end() )
     90                        labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
     91                else
    10492                        labelTable[ orgValue ] = new Entry( 0, use );
    105                 }
     93
     94                return labelTable[ orgValue ]->get_label();
    10695        }
    10796
    108         // Ultimately builds a table that maps a label to its defining statement.
    109         // In the process,
    11097        std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
    11198                std::map< Statement *, Entry * > def_us;
    11299
    113                 // combine the entries for all labels that target the same location
    114                 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
     100                for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
    115101                        Entry *e = i->second;
    116102
    117103                        if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
    118104                                def_us[ e->get_definition() ] = e;                             
    119                         } else if ( e->used() ) {
    120                                 def_us[ e->get_definition() ]->add_uses( e->get_uses() );
     105                        } else {
     106                                if ( e->used() )
     107                                        def_us[ e->get_definition() ]->add_uses( e->get_uses() );
    121108                        }
    122109                }
    123110
    124                 // create a unique label for each target location.
    125                 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++ ) {
    126113                        Statement *to = (*i).first;
    127                         Entry * entry = (*i).second;
    128                         std::list< BranchStmt *> &from = entry->get_uses();
     114                        std::list< Statement *> &from = (*i).second->get_uses();
     115                        Label finalLabel = generator->newLabel();
     116                        (*i).second->set_label( finalLabel );
    129117
    130                         // no label definition found
    131118                        if ( to == 0 ) {
    132                                 Label undef = 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();
    133123                                throw SemanticError ( "'" + undef + "' label not defined");
    134124                        }
    135 
    136                         // generate a new label, and attach it to its defining statement
    137                         // as the only label on that statement
    138                         Label finalLabel = generator->newLabel();
    139                         entry->set_label( finalLabel );
    140125
    141126                        to->get_labels().clear();
    142127                        to->get_labels().push_back( finalLabel );
    143128
    144                         // redirect each of the source branch statements to the new target label
    145                         for ( std::list< BranchStmt *>::iterator j = from.begin(); j != from.end(); ++j ) {
    146                                 BranchStmt *jump = *j;
    147                                 assert( jump != 0 );
    148                                 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 );
    149133                        } // for
    150134                } // for
    151135
    152                 // create a table where each label maps to its defining statement
     136                // reverse table
    153137                std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
    154                 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++ )
    155139                        (*ret)[ (*i).second->get_label() ] = (*i).first;
    156                 }
    157140
    158141                return ret;
Note: See TracChangeset for help on using the changeset viewer.