source: src/Tuples/MultRet.cc @ 038726d

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 038726d was 5f2f2d7, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

fix constant types, remove unnecessary string copying, work on regression testing, fix several memory leaks

  • Property mode set to 100644
File size: 4.9 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// MultRet.cc --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Mon Jun  8 14:54:44 2015
13// Update Count     : 2
14//
15
16#include <list>
17#include <vector>
18#include <cassert>
19#include <algorithm>
20
21#include "MultRet.h"
22#include "SynTree/Statement.h"
23#include "SynTree/Expression.h"
24#include "SynTree/Declaration.h"
25#include "SynTree/Type.h"
26
27namespace Tuples {
28        MVRMutator::MVRMutator() : newVars( 0 ), newCode( 0 ) {
29        }
30
31        MVRMutator::~MVRMutator() {
32        }
33
34        int MVRMutator::curVal = 0;
35
36        Statement *MVRMutator::mutate( ExprStmt *exprStmt ) {
37                MVRMutator toplevel;
38                exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), toplevel ) );
39
40                if ( toplevel.hasCode() ) {
41                        assert ( toplevel.getVars() != 0 );
42
43                        typedef std::list<Statement *> Statements;
44
45                        CompoundStmt *code = new CompoundStmt( std::list< Label >() );
46
47                        // copy variables
48                        Statements &vars = toplevel.getVars()->get_kids();
49                        for ( Statements::iterator i = vars.begin(); i != vars.end(); i++ )
50                                code->get_kids().push_back( *i );
51
52                        // copy statements
53                        Statements &block = toplevel.getCode()->get_kids();
54                        for ( Statements::iterator i = block.begin(); i != block.end(); i++ )
55                                code->get_kids().push_back( *i );
56
57                        return code;
58                } else
59                        return exprStmt;
60        }
61
62        Expression *MVRMutator::mutate( ApplicationExpr *appExpr ) {
63                // appExpr->set_function(  maybeMutate( appExpr->get_function(), *this ) );
64                bool mulretp = false;
65                VariableExpr *funname;
66                if ( (funname = dynamic_cast<VariableExpr *>(appExpr->get_function())) == 0 ) goto DoArgs;
67
68                FunctionDecl *fundecl;
69                if ((fundecl = dynamic_cast<FunctionDecl *>(funname->get_var())) == 0) goto DoArgs;
70                {
71                        typedef std::list<DeclarationWithType*> RetType;
72
73                        RetType &rets = fundecl->get_functionType()->get_returnVals();
74                        if ( rets.size() <= 1 ) goto DoArgs;
75                        mulretp = true;
76
77                        if ( newVars == 0 )
78                                newVars = new CompoundStmt( std::list<Label>(0) );
79
80                        for (RetType::iterator i = rets.begin() ; i != rets.end(); i++) {
81                                DeclStmt *arg = newVar( *i );
82                                newVars->get_kids().push_back( arg );
83                                add_pending( arg->get_decl() );
84                        } // for
85                }
86
87          DoArgs:
88                // mutate the argument list
89                typedef std::list< Expression *> Exprs;
90                Exprs &args = appExpr->get_args();
91                std::list< Expression * > newArgs;
92                for ( Exprs::iterator i = args.begin(); i != args.end(); i++ ) {
93                        MVRMutator next;
94                        Expression *mutated = (*i)->acceptMutator( next );
95
96                        if ( next.hasCode() ) {
97                                // merge new vars and bodies
98                                typedef std::list< Statement * > Stmts;
99                                Stmts &vars = next.getVars()->get_kids();
100                                Stmts &block = next.getCode()->get_kids();
101
102                                if (newVars == 0)
103                                        newVars = new CompoundStmt( std::list< Label >() );
104                                for ( Stmts::iterator i = vars.begin(); i != vars.end(); i++ )  // std::splice? -- need to append lists
105                                        newVars->get_kids().push_back( *i );
106
107                                if (newCode == 0)
108                                        newCode = new CompoundStmt( std::list< Label >() );
109                                for ( Stmts::iterator i = block.begin(); i != block.end(); i++ )
110                                        newCode->get_kids().push_back( *i );
111                        } // if
112
113                        if ( next.hasResults() ) {
114                                Exprs &res = next.get_results();
115                                for ( Exprs::iterator i = res.begin(); i != res.end(); i++ )
116                                        newArgs.push_back( *i );
117                        } else
118                                newArgs.push_back( mutated );
119                }
120
121                appExpr->get_args() = newArgs;  // new argument list
122
123                if ( mulretp ) {
124                        // add 'out' parameters
125                        if ( ! argsToAdd.empty() )
126                                for (std::list< Expression *>::iterator i = argsToAdd.begin(); i != argsToAdd.end(); i++)
127                                        (appExpr->get_args()).push_back( *i );
128                        // clear 'out' parameters ( so that the list can be reused -- substitute by auto_ptr later? )
129
130                        if (newCode == 0)
131                                newCode = new CompoundStmt( std::list<Label>(0) );
132                } // if
133
134                // add to block of code
135                if ( newCode != 0 )
136                        newCode->get_kids().push_back( new ExprStmt( std::list<Label>(), appExpr ) );
137
138                return appExpr;
139        }
140
141        // Auxiliary function to generate new names for the `output' parameters
142        DeclStmt *MVRMutator::newVar( DeclarationWithType *reqDecl ) {
143                // std::ostringstream os;
144                // os << "__" << curVal++ << "__";// << std::ends;
145
146                ObjectDecl *decl;
147                if ((decl = dynamic_cast<ObjectDecl *>( reqDecl )) != 0)
148                        // return new DeclStmt( new ObjectDecl( std::string (os.str(), os.pcount()), );
149                        return new DeclStmt( std::list<Label>(), decl );
150                else
151                        return 0;
152        }
153
154        void MVRMutator::add_pending( Declaration *decl ) {
155                ObjectDecl *obj;
156                if ( (obj = dynamic_cast< ObjectDecl * >( decl )) == 0 ) return;
157
158                VariableExpr *var = new VariableExpr(obj, 0 );
159                results.push_back( var ); // probably change this name to newResults or something
160                argsToAdd.push_back( new AddressExpr( var ) );
161                return;
162        }
163}
164
165// Local Variables: //
166// tab-width: 4 //
167// mode: c++ //
168// compile-command: "make install" //
169// End: //
Note: See TracBrowser for help on using the repository browser.