Ignore:
Timestamp:
Jun 4, 2015, 2:07:40 PM (9 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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:
0423f25, eb3261f
Parents:
a61fea9a (diff), 1136d96 (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.
Message:

enable AM_MAINTAINER_MODE, add operator ?{}, formatting

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    ra61fea9a r9a8930f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed May 27 16:16:14 2015
    13 // Update Count     : 4
     12// Last Modified On : Tue Jun 02 15:30:32 2015
     13// Update Count     : 93
    1414//
    1515
     
    2323#include "utility.h"
    2424
     25#include <iostream>
     26
    2527namespace ControlStruct {
    26         LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {
     28        LabelFixer::Entry::Entry( Statement *to, BranchStmt *from ) : definition ( to ) {
    2729                if ( from != 0 )
    2830                        usage.push_back( from );
     
    3133        bool LabelFixer::Entry::insideLoop() {
    3234                return ( dynamic_cast< ForStmt * > ( definition ) ||
    33                                  dynamic_cast< WhileStmt * > ( definition )  );
     35                        dynamic_cast< WhileStmt * > ( definition )  );
    3436        }
    3537
     
    4648        }
    4749
     50        // prune to at most one label definition for each statement
    4851        void LabelFixer::visit( Statement *stmt ) {
    4952                std::list< Label > &labels = stmt->get_labels();
    5053
    5154                if ( ! labels.empty() ) {
     55                        // only remember one label for each statement
    5256                        Label current = setLabelsDef( labels, stmt );
    5357                        labels.clear();
     
    5761
    5862        void LabelFixer::visit( BranchStmt *branchStmt ) {
    59                 visit ( ( Statement * )branchStmt );  // the labels this statement might have
     63                visit ( ( Statement * )branchStmt );
    6064
    61                 Label target;
    62                 if ( (target = branchStmt->get_target()) != "" ) {
     65                // for labeled branches, add an entry to the label table
     66                Label target = branchStmt->get_target();
     67                if ( target != "" ) {
    6368                        setLabelsUsg( target, branchStmt );
    64                 } //else       /* computed goto or normal exit-loop statements */
     69                }
    6570        }
    6671
     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
    6774        Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
    6875                assert( definition != 0 );
    69                 Entry *entry = new Entry( definition );
    70                 bool used = false;
     76                assert( llabel.size() > 0 );
    7177
    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 );
     78                Entry * e = new Entry( definition );
    8079
    81                 if ( ! used ) delete entry;
     80                for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) {
     81                        if ( labelTable.find( *i ) == labelTable.end() ) {
     82                                // all labels on this statement need to use the same entry, so this should only be created once
     83                                // undefined and unused until now, add an entry
     84                                labelTable[ *i ] =  e;
     85                        } else if ( labelTable[ *i ]->defined() ) {
     86                                // defined twice, error
     87                                throw SemanticError( "Duplicate definition of label: " + *i );
     88                        }       else {
     89                                // used previously, but undefined until now -> link with this entry
     90                                Entry * oldEntry = labelTable[ *i ];
     91                                e->add_uses( oldEntry->get_uses() );
     92                                labelTable[ *i ] = e;
     93                        } // if
     94                } // for
    8295
    83                 return labelTable[ llabel.front() ]->get_label();  // this *must* exist
     96                // produce one of the labels attached to this statement to be
     97                // temporarily used as the canonical label
     98                return labelTable[ llabel.front() ]->get_label();
    8499        }
    85100
    86         Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
     101        // Remember all uses of a label.
     102        void LabelFixer::setLabelsUsg( Label orgValue, BranchStmt *use ) {
    87103                assert( use != 0 );
    88104
    89                 if ( labelTable.find( orgValue ) != labelTable.end() )
    90                         labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
    91                 else
     105                if ( labelTable.find( orgValue ) != labelTable.end() ) {
     106                        // the label has been defined or used before
     107                        labelTable[ orgValue ]->add_use( use );
     108                } else {
    92109                        labelTable[ orgValue ] = new Entry( 0, use );
    93 
    94                 return labelTable[ orgValue ]->get_label();
     110                }
    95111        }
    96112
     113        // Ultimately builds a table that maps a label to its defining statement.
     114        // In the process,
    97115        std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
    98116                std::map< Statement *, Entry * > def_us;
    99117
    100                 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
     118                // combine the entries for all labels that target the same location
     119                for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
    101120                        Entry *e = i->second;
    102121
    103122                        if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
    104123                                def_us[ e->get_definition() ] = e;                             
    105                         } else {
    106                                 if ( e->used() )
    107                                         def_us[ e->get_definition() ]->add_uses( e->get_uses() );
     124                        } else if ( e->used() ) {
     125                                def_us[ e->get_definition() ]->add_uses( e->get_uses() );
    108126                        }
    109127                }
    110128
    111                 // get rid of labelTable
    112                 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
     129                // create a unique label for each target location.
     130                for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
    113131                        Statement *to = (*i).first;
    114                         std::list< Statement *> &from = (*i).second->get_uses();
    115                         Label finalLabel = generator->newLabel();
    116                         (*i).second->set_label( finalLabel );
     132                        Entry * entry = (*i).second;
     133                        std::list< BranchStmt *> &from = entry->get_uses();
    117134
     135                        // no label definition found
    118136                        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();
     137                                Label undef = from.back()->get_target();
    123138                                throw SemanticError ( "'" + undef + "' label not defined");
    124139                        }
     140
     141                        // generate a new label, and attach it to its defining statement
     142                        // as the only label on that statement
     143                        Label finalLabel = generator->newLabel();
     144                        entry->set_label( finalLabel );
    125145
    126146                        to->get_labels().clear();
    127147                        to->get_labels().push_back( finalLabel );
    128148
    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 );
     149                        // redirect each of the source branch statements to the new target label
     150                        for ( std::list< BranchStmt *>::iterator j = from.begin(); j != from.end(); ++j ) {
     151                                BranchStmt *jump = *j;
     152                                assert( jump != 0 );
     153                                jump->set_target( finalLabel );
    133154                        } // for
    134155                } // for
    135156
    136                 // reverse table
     157                // create a table where each label maps to its defining statement
    137158                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++ )
     159                for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
    139160                        (*ret)[ (*i).second->get_label() ] = (*i).first;
     161                }
    140162
    141163                return ret;
Note: See TracChangeset for help on using the changeset viewer.