source: translator/ControlStruct/LabelFixer.cc @ 01aeade

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 01aeade was 51587aa, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

licencing: fourth groups of files

  • Property mode set to 100644
File size: 4.5 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// XXX.cc --
8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
11// Last Modified By :
12// Last Modified On :
13// Update Count     : 0
14//
15#include <list>
16#include <cassert>
17
18#include "LabelFixer.h"
19#include "MLEMutator.h"
20#include "SynTree/Statement.h"
21#include "SynTree/Declaration.h"
22#include "utility.h"
23
24namespace ControlStruct {
25    LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {
26        if ( from != 0 )
27            usage.push_back( from );
28    }
29
30    bool LabelFixer::Entry::insideLoop() {
31        return ( dynamic_cast< ForStmt * > ( definition ) ||
32                 dynamic_cast< WhileStmt * > ( definition )  );
33    }
34
35    LabelFixer::LabelFixer( LabelGenerator *gen ) : generator ( gen ) {
36        if ( generator == 0 )
37            generator = LabelGenerator::getGenerator();
38    }
39
40    void LabelFixer::visit( FunctionDecl *functionDecl ) {
41        if ( functionDecl->get_statements() != 0 )
42            functionDecl->get_statements()->accept( *this );
43
44        MLEMutator mlemut( resolveJumps(), generator );
45        functionDecl->acceptMutator( mlemut );
46    }
47
48    void LabelFixer::visit( Statement *stmt ) {
49        std::list< Label > &labels = stmt->get_labels();
50
51        if ( ! labels.empty() ) {
52            Label current = setLabelsDef( labels, stmt );
53            labels.clear();
54            labels.push_front( current );
55        } // if
56    }
57
58    void LabelFixer::visit( BranchStmt *branchStmt ) {
59        visit ( ( Statement * )branchStmt );  // the labels this statement might have
60
61        Label target;
62        if ( (target = branchStmt->get_target()) != "" ) {
63            setLabelsUsg( target, branchStmt );
64        } //else       /* computed goto or normal exit-loop statements */
65    }
66
67    Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
68        assert( definition != 0 );
69        Entry *entry = new Entry( definition );
70        bool used = false;
71
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 );
80
81        if (! used ) delete entry;
82
83        return labelTable[ llabel.front() ]->get_label();  // this *must* exist
84    }
85
86    Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
87        assert( use != 0 );
88
89        if ( labelTable.find( orgValue ) != labelTable.end() )
90            labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
91        else
92            labelTable[ orgValue ] = new Entry( 0, use );
93
94        return labelTable[ orgValue ]->get_label();
95    }
96
97    std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
98        std::map< Statement *, Entry * > def_us;
99
100        for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
101            Entry *e = i->second;
102
103            if ( def_us.find ( e->get_definition() ) == def_us.end() )
104                def_us[ e->get_definition() ] = e;
105            else
106                if ( e->used() )
107                    def_us[ e->get_definition() ]->add_uses( e->get_uses() );
108        }
109
110        // get rid of labelTable
111        for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
112            Statement *to = (*i).first;
113            std::list< Statement *> &from = (*i).second->get_uses();
114            Label finalLabel = generator->newLabel();
115            (*i).second->set_label( finalLabel );
116
117            if ( to == 0 ) {
118                BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());
119                Label undef("");
120                if ( first_use != 0 )
121                    undef = first_use->get_target();
122                throw SemanticError ( "'" + undef + "' label not defined");
123            }
124
125            to->get_labels().clear();
126            to->get_labels().push_back( finalLabel );
127
128            for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) {
129                BranchStmt *jumpTo = dynamic_cast< BranchStmt * > ( *j );
130                assert( jumpTo != 0 );
131                jumpTo->set_target( finalLabel );
132            } // for
133        } // for
134
135        // reverse table
136        std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
137        for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) 
138            (*ret)[ (*i).second->get_label() ] = (*i).first;
139
140        return ret;
141    }
142}  // namespace ControlStruct
143// Local Variables: //
144// tab-width: 4 //
145// mode: c++ //
146// compile-command: "make install" //
147// End: //
Note: See TracBrowser for help on using the repository browser.