source: src/Tuples/TupleExpansion.cc @ 1132b62

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 1132b62 was 1132b62, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

copy construct tuple function arguments, and destruct tuple function results

  • Property mode set to 100644
File size: 6.8 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// TupleAssignment.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 May 18 15:02:53 2015
13// Update Count     : 2
14//
15
16#include <iterator>
17#include <iostream>
18#include <cassert>
19#include "Tuples.h"
20#include "GenPoly/DeclMutator.h"
21#include "SynTree/Mutator.h"
22#include "SynTree/Statement.h"
23#include "SynTree/Declaration.h"
24#include "SynTree/Type.h"
25#include "SynTree/Expression.h"
26#include "SynTree/Initializer.h"
27#include "SymTab/Mangler.h"
28#include "Common/ScopedMap.h"
29#include "ResolvExpr/typeops.h"
30
31namespace Tuples {
32        namespace {
33                class UniqueExprExpander : public GenPoly::DeclMutator {
34                public:
35                        typedef GenPoly::DeclMutator Parent;
36                        virtual Expression * mutate( UniqueExpr * unqExpr );
37                        std::map< Expression *, ObjectDecl * > decls;
38                };
39
40                class TupleAssignExpander : public Mutator {
41                public:
42                        typedef Mutator Parent;
43                        virtual Expression * mutate( TupleAssignExpr * tupleExpr );
44                };
45
46                class TupleTypeReplacer : public GenPoly::DeclMutator {
47                  public:
48                        typedef GenPoly::DeclMutator Parent;
49
50                        virtual Type * mutate( TupleType * tupleType );
51                        virtual Type * mutate( FunctionType * ftype );
52
53                        virtual CompoundStmt * mutate( CompoundStmt * stmt ) {
54                                typeMap.beginScope();
55                                stmt = Parent::mutate( stmt );
56                                typeMap.endScope();
57                                return stmt;
58                        }
59                  private:
60                        ScopedMap< std::string, StructDecl * > typeMap;
61                };
62
63                class TupleIndexExpander : public Mutator {
64                public:
65                        typedef Mutator Parent;
66                        virtual Expression * mutate( TupleIndexExpr * tupleExpr );
67                };
68
69                class TupleExprExpander : public Mutator {
70                public:
71                        typedef Mutator Parent;
72                        virtual Expression * mutate( TupleExpr * tupleExpr );
73                };
74        }
75
76        void expandUniqueExpr( std::list< Declaration * > & translationUnit ) {
77                UniqueExprExpander unqExpander;
78                unqExpander.mutateDeclarationList( translationUnit );
79        }
80
81        void expandTuples( std::list< Declaration * > & translationUnit ) {
82                TupleAssignExpander assnExpander;
83                mutateAll( translationUnit, assnExpander );
84
85                TupleTypeReplacer replacer;
86                replacer.mutateDeclarationList( translationUnit );
87
88                TupleIndexExpander idxExpander;
89                mutateAll( translationUnit, idxExpander );
90
91                TupleExprExpander exprExpander;
92                mutateAll( translationUnit, exprExpander );
93        }
94
95        Expression * UniqueExprExpander::mutate( UniqueExpr * unqExpr ) {
96                static UniqueName tempNamer( "_unq_expr_" );
97                unqExpr = safe_dynamic_cast< UniqueExpr * > ( Parent::mutate( unqExpr ) );
98                if ( ! decls.count( unqExpr->get_expr() ) ) {
99                        // xxx - it's possible (likely?) that expressions can appear in the wrong order because of this. Need to ensure they're placed in the correct location.
100                        ObjectDecl * decl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, unqExpr->get_result()->clone(), new SingleInit( unqExpr->get_expr()->clone() ) );
101                        decls[unqExpr->get_expr()] = decl;
102                        addDeclaration( decl );
103                }
104                return new VariableExpr( decls[unqExpr->get_expr()] );
105        }
106
107        Expression * TupleAssignExpander::mutate( TupleAssignExpr * assnExpr ) {
108                // xxx - Parent::mutate?
109                CompoundStmt * compoundStmt = new CompoundStmt( noLabels );
110                std::list< Statement * > & stmts = compoundStmt->get_kids();
111                for ( ObjectDecl * obj : assnExpr->get_tempDecls() ) {
112                        stmts.push_back( new DeclStmt( noLabels, obj ) );
113                }
114                TupleExpr * tupleExpr = new TupleExpr( assnExpr->get_assigns() );
115                assert( tupleExpr->get_result() );
116                stmts.push_back( new ExprStmt( noLabels, tupleExpr ) );
117                assnExpr->get_tempDecls().clear();
118                assnExpr->get_assigns().clear();
119                delete assnExpr;
120                return new StmtExpr( compoundStmt );
121        }
122
123        Type * TupleTypeReplacer::mutate( FunctionType * ftype ) {
124                // replace multiple-returning functions with functions which return a tuple
125                if ( ftype->get_returnVals().size() > 1 ) {
126                        TupleType * tupleType = safe_dynamic_cast<TupleType *>( ResolvExpr::extractResultType( ftype ) );
127                        ObjectDecl * retVal = new ObjectDecl( "__tuple_ret", DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, tupleType, nullptr );
128                        // xxx - replace all uses of return vals with appropriate tuple index expr
129                        deleteAll( ftype->get_returnVals() );
130                        ftype->get_returnVals().clear();
131                        ftype->get_returnVals().push_back( retVal );
132                }
133                return Parent::mutate( ftype );
134        }
135
136        Type * TupleTypeReplacer::mutate( TupleType * tupleType ) {
137                std::string mangleName = SymTab::Mangler::mangleType( tupleType );
138                TupleType * newType = safe_dynamic_cast< TupleType * > ( Parent::mutate( tupleType ) );
139                if ( ! typeMap.count( mangleName ) ) {
140                        // generate struct type to replace tuple type
141                        StructDecl * decl = new StructDecl( "_tuple_type_" + mangleName );
142                        decl->set_body( true );
143                        int cnt = 0;
144                        for ( Type * t : *newType ) {
145                                decl->get_members().push_back( new ObjectDecl( "field_"+std::to_string(++cnt), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, t->clone(), nullptr ) );
146                        }
147                        typeMap[mangleName] = decl;
148                        addDeclaration( decl );
149                }
150                Type::Qualifiers qualifiers = newType->get_qualifiers();
151                delete newType;
152                return new StructInstType( qualifiers, typeMap[mangleName] );
153        }
154
155        Expression * TupleIndexExpander::mutate( TupleIndexExpr * tupleExpr ) {
156                Expression * tuple = maybeMutate( tupleExpr->get_tuple(), *this );
157                assert( tuple );
158                tupleExpr->set_tuple( nullptr );
159                unsigned int idx = tupleExpr->get_index();
160                delete tupleExpr;
161
162                StructInstType * type = safe_dynamic_cast< StructInstType * >( tuple->get_result() );
163                StructDecl * structDecl = type->get_baseStruct();
164                assert( structDecl->get_members().size() > idx );
165                Declaration * member = *std::next(structDecl->get_members().begin(), idx);
166                return new MemberExpr( safe_dynamic_cast< DeclarationWithType * >( member ), tuple );
167        }
168
169        Expression * TupleExprExpander::mutate( TupleExpr * tupleExpr ) {
170                assert( tupleExpr->get_result() );
171                std::list< Initializer * > inits;
172                for ( Expression * expr : tupleExpr->get_exprs() ) {
173                        inits.push_back( new SingleInit( expr ) );
174                }
175                return new CompoundLiteralExpr( tupleExpr->get_result(), new ListInit( inits ) );
176        }
177
178        TupleType * makeTupleType( const std::list< Expression * > & exprs ) {
179                TupleType *tupleType = new TupleType( Type::Qualifiers(true, true, true, true, true, false) );
180                Type::Qualifiers &qualifiers = tupleType->get_qualifiers();
181                for ( Expression * expr : exprs ) {
182                        assert( expr->get_result() );
183                        Type * type = expr->get_result()->clone();
184                        tupleType->get_types().push_back( type );
185                        qualifiers &= type->get_qualifiers();
186                } // for
187                return tupleType;
188        }
189} // namespace Tuples
190
191// Local Variables: //
192// tab-width: 4 //
193// mode: c++ //
194// compile-command: "make install" //
195// End: //
196
Note: See TracBrowser for help on using the repository browser.