source: src/Concurrency/Keywords.cc @ 4a3334cf

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 4a3334cf was 64adb03, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Added first implementation of mutex keyword

  • Property mode set to 100644
File size: 7.6 KB
Line 
1//                              -*- Mode: CPP -*-
2//
3// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
4//
5// The contents of this file are covered under the licence agreement in the
6// file "LICENCE" distributed with Cforall.
7//
8// Keywords.cc --
9//
10// Author           : Thierry Delisle
11// Created On       : Mon Mar 13 12:41:22 2017
12// Last Modified By :
13// Last Modified On :
14// Update Count     : 0
15//
16
17#include "Concurrency/Keywords.h"
18
19#include "SynTree/Declaration.h"
20#include "SynTree/Expression.h"
21#include "SynTree/Initializer.h"
22#include "SynTree/Mutator.h"
23#include "SynTree/Statement.h"
24#include "SynTree/Type.h"
25#include "SynTree/Visitor.h"
26
27namespace Concurrency {
28
29        namespace {
30                const std::list<Label> noLabels;
31                DeclarationNode::StorageClasses noStorage;
32                Type::Qualifiers noQualifiers;
33        }
34
35        //=============================================================================================
36        // Visitors declaration
37        //=============================================================================================
38
39        //-----------------------------------------------------------------------------
40        //Handles thread type declarations :
41        // thread Mythread {                         struct MyThread {
42        //      int data;                                  int data;
43        //      a_struct_t more_data;                      a_struct_t more_data;
44        //                                =>             thread_desc __thrd_d;
45        // };                                        };
46        //                                           static inline thread_desc * get_thread( MyThread * this ) { return &this->__thrd_d; }
47        //                                           void main( MyThread * this );
48        //
49        class ThreadKeyword final : public Mutator {
50          public:
51
52                static void implement( std::list< Declaration * > & translationUnit ) {}
53        };
54
55        //-----------------------------------------------------------------------------
56        //Handles coroutine type declarations :
57        // coroutine MyCoroutine {                   struct MyCoroutine {
58        //      int data;                                  int data;
59        //      a_struct_t more_data;                      a_struct_t more_data;
60        //                                =>             coroutine_desc __cor_d;
61        // };                                        };
62        //                                           static inline coroutine_desc * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; }
63        //                                           void main( MyCoroutine * this );
64        //
65        class CoroutineKeyword final : public Mutator {
66          public:
67
68                static void implement( std::list< Declaration * > & translationUnit ) {}
69        };
70
71        //-----------------------------------------------------------------------------
72        //Handles monitor type declarations :
73        // monitor MyMonitor {                       struct MyMonitor {
74        //      int data;                                  int data;
75        //      a_struct_t more_data;                      a_struct_t more_data;
76        //                                =>             monitor_desc __mon_d;
77        // };                                        };
78        //                                           static inline monitor_desc * get_coroutine( MyMonitor * this ) { return &this->__cor_d; }
79        //                                           void main( MyMonitor * this );
80        //
81        class MonitorKeyword final : public Mutator {
82          public:
83
84                static void implement( std::list< Declaration * > & translationUnit ) {}
85        };
86
87        //-----------------------------------------------------------------------------
88        //Handles mutex routines definitions :
89        // void foo( A * mutex a, B * mutex b,  int i ) {                  void foo( A * a, B * b,  int i ) {
90        //                                                                       monitor_desc * __monitors[] = { a, b };
91        //                                                                       monitor_guard_t __guard = { __monitors, 2 };
92        //    /*Some code*/                                       =>           /*Some code*/
93        // }                                                               }
94        //
95        class MutexKeyword final : public Visitor {
96          public:
97
98                using Visitor::visit;
99                virtual void visit( FunctionDecl *functionDecl ) override final;
100
101                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
102                void validate( DeclarationWithType * );
103                void addStatments( CompoundStmt *, const std::list<DeclarationWithType * > &);
104
105                static void implement( std::list< Declaration * > & translationUnit ) {
106                        MutexKeyword impl;
107                        acceptAll( translationUnit, impl );
108                }
109        };
110
111        //=============================================================================================
112        // General entry routine
113        //=============================================================================================
114        void applyKeywords( std::list< Declaration * > & translationUnit ) {
115                ThreadKeyword   ::implement( translationUnit );
116                CoroutineKeyword        ::implement( translationUnit );
117                MonitorKeyword  ::implement( translationUnit );
118                MutexKeyword    ::implement( translationUnit );
119        }
120
121        //=============================================================================================
122        // Mutex keyword implementation
123        //=============================================================================================
124        void MutexKeyword::visit(FunctionDecl* decl) {
125                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
126                if( mutexArgs.empty() ) return;
127
128                for(auto arg : mutexArgs) {
129                        validate( arg );
130                }
131
132                CompoundStmt* body = decl->get_statements();
133                if( ! body ) return;
134
135                addStatments( body, mutexArgs );
136        }
137
138        std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl ) {
139                std::list<DeclarationWithType*> mutexArgs;
140
141                for( auto arg : decl->get_functionType()->get_parameters()) {
142                        //Find mutex arguments
143                        Type* ty = arg->get_type();
144                        if( ! ty->get_qualifiers().isMutex ) continue;
145
146                        //Append it to the list
147                        mutexArgs.push_back( arg );
148                }
149
150                return mutexArgs;
151        }
152
153        void MutexKeyword::validate( DeclarationWithType * arg ) {
154                Type* ty = arg->get_type();
155
156                //Makes sure it's not a copy
157                PointerType* pty = dynamic_cast< PointerType * >( ty );
158                if( ! pty ) throw SemanticError( "Mutex argument must be of pointer/reference type ", arg );
159
160                //Make sure the we are pointing directly to a type
161                Type* base = pty->get_base();
162                if(  dynamic_cast< PointerType * >( base ) ) throw SemanticError( "Mutex argument have exactly one level of indirection ", arg );
163
164                //Make sure that typed isn't mutex
165                if( ! base->get_qualifiers().isMutex ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
166        }
167
168        void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
169                //in reverse order :
170                // monitor_guard_t __guard = { __monitors, # };
171                body->push_front(
172                        new DeclStmt( noLabels, new ObjectDecl(
173                                "__guard",
174                                noStorage,
175                                LinkageSpec::Cforall,
176                                nullptr,
177                                new StructInstType(
178                                        noQualifiers,
179                                        "monitor_guard_t"
180                                ),
181                                new ListInit(
182                                        {
183                                                new SingleInit( new NameExpr( "__monitors" ) ),
184                                                new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) )
185                                        }
186                                )
187                        ))
188                );
189
190                //monitor_desc * __monitors[] = { a, b };
191                body->push_front(
192                        new DeclStmt( noLabels, new ObjectDecl(
193                                "__monitors",
194                                noStorage,
195                                LinkageSpec::Cforall,
196                                nullptr,
197                                new ArrayType(
198                                        noQualifiers,
199                                        new PointerType(
200                                                noQualifiers,
201                                                new StructInstType(
202                                                        noQualifiers,
203                                                        "monitor_desc"
204                                                )
205                                        ),
206                                        new ConstantExpr( Constant::from_ulong( args.size() ) ),
207                                        false,
208                                        false
209                                ),
210                                new ListInit(
211                                        map_range < std::list<Initializer*> > ( args, [](DeclarationWithType * var ){
212                                                return new SingleInit( new VariableExpr( var ) );
213                                        })
214                                )
215                        ))
216                );
217        }
218};
Note: See TracBrowser for help on using the repository browser.