Changeset 46cbfe1


Ignore:
Timestamp:
May 29, 2015, 4:02:20 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, string, with_gc
Children:
76934fb
Parents:
be5aa1b
Message:

reorganization and refactoring of most of LabelFixer?

Location:
src/ControlStruct
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    rbe5aa1b r46cbfe1  
    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 : Fri May 29 15:57:12 2015
     13// Update Count     : 82
    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                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
    8090
    81                 if ( ! used ) delete entry;
    82 
    83                 return labelTable[ llabel.front() ]->get_label();  // this *must* exist
     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();
    8494        }
    8595
    86         Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
     96        // Remember all uses of a label.
     97        void LabelFixer::setLabelsUsg( Label orgValue, BranchStmt *use ) {
    8798                assert( use != 0 );
    8899
    89                 if ( labelTable.find( orgValue ) != labelTable.end() )
    90                         labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
    91                 else
     100                if ( labelTable.find( orgValue ) != labelTable.end() ) {
     101                        // the label has been defined or used before
     102                        labelTable[ orgValue ]->add_use( use );
     103                } else {
    92104                        labelTable[ orgValue ] = new Entry( 0, use );
    93 
    94                 return labelTable[ orgValue ]->get_label();
     105                }
    95106        }
    96107
     108        // Ultimately builds a table that maps a label to its defining statement.
     109        // In the process,
    97110        std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
    98111                std::map< Statement *, Entry * > def_us;
    99112
    100                 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
     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 ) {
    101115                        Entry *e = i->second;
    102116
    103117                        if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
    104118                                def_us[ e->get_definition() ] = e;                             
    105                         } else {
    106                                 if ( e->used() )
    107                                         def_us[ e->get_definition() ]->add_uses( e->get_uses() );
     119                        } else if ( e->used() ) {
     120                                def_us[ e->get_definition() ]->add_uses( e->get_uses() );
    108121                        }
    109122                }
    110123
    111                 // get rid of labelTable
    112                 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
     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 ) {
    113126                        Statement *to = (*i).first;
    114                         std::list< Statement *> &from = (*i).second->get_uses();
    115                         Label finalLabel = generator->newLabel();
    116                         (*i).second->set_label( finalLabel );
     127                        Entry * entry = (*i).second;
     128                        std::list< BranchStmt *> &from = entry->get_uses();
    117129
     130                        // no label definition found
    118131                        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();
     132                                Label undef = from.back()->get_target();
    123133                                throw SemanticError ( "'" + undef + "' label not defined");
    124134                        }
     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 );
    125140
    126141                        to->get_labels().clear();
    127142                        to->get_labels().push_back( finalLabel );
    128143
    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 );
     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 );
    133149                        } // for
    134150                } // for
    135151
    136                 // reverse table
     152                // create a table where each label maps to its defining statement
    137153                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++ )
     154                for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
    139155                        (*ret)[ (*i).second->get_label() ] = (*i).first;
     156                }
    140157
    141158                return ret;
  • src/ControlStruct/LabelFixer.h

    rbe5aa1b r46cbfe1  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue May 26 12:55:10 2015
    13 // Update Count     : 4
     12// Last Modified On : Fri May 29 15:25:55 2015
     13// Update Count     : 11
    1414//
    1515
     
    5555
    5656                Label setLabelsDef( std::list< Label > &, Statement *definition );
    57                 Label setLabelsUsg( Label, Statement *usage = 0 );
     57                void setLabelsUsg( Label, BranchStmt *usage = 0 );
    5858
    5959          private:
    6060                class Entry {
    6161                  public:
    62                         Entry( Statement *to = 0, Statement *from = 0 );
     62                        Entry( Statement *to = 0, BranchStmt *from = 0 );
    6363                        bool used() { return ( usage.empty() ); }
    6464                        bool defined() { return ( definition != 0 ); }
     
    7171                        void set_definition( Statement *def ) { definition = def; }
    7272
    73                         std::list< Statement *> &get_uses() { return usage; }
    74                         void add_use ( Statement *use ) { usage.push_back( use ); }
    75                         void add_uses ( std::list<Statement *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
     73                        std::list< BranchStmt *> &get_uses() { return usage; }
     74                        void add_use ( BranchStmt *use ) { usage.push_back( use ); }
     75                        void add_uses ( std::list<BranchStmt *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
    7676                  private:
    7777                        Label label; 
    7878                        Statement *definition;
    79                         std::list<Statement *> usage;
     79                        std::list<BranchStmt *> usage;
    8080                };
    8181                 
Note: See TracChangeset for help on using the changeset viewer.