Changes in src/Concurrency/Keywords.cc [9243cc91:68ac32e]
- File:
-
- 1 edited
-
src/Concurrency/Keywords.cc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Keywords.cc
r9243cc91 r68ac32e 1 // -*- Mode: CPP -*-2 //3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo4 //5 // The contents of this file are covered under the licence agreement in the6 // file "LICENCE" distributed with Cforall.7 //8 // Keywords.cc --9 //10 // Author : Thierry Delisle11 // Created On : Mon Mar 13 12:41:22 201712 // Last Modified By :13 // Last Modified On :14 // Update Count : 015 //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 27 namespace Concurrency {28 29 namespace {30 const std::list<Label> noLabels;31 DeclarationNode::StorageClasses noStorage;32 Type::Qualifiers noQualifiers;33 }34 35 //=============================================================================================36 // Visitors declaration37 //=============================================================================================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[] = { get_monitor(a), get_monitor(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 virtual void visit( StructDecl *functionDecl ) override final;101 102 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );103 void validate( DeclarationWithType * );104 void addStatments( CompoundStmt *, const std::list<DeclarationWithType * > &);105 106 static void implement( std::list< Declaration * > & translationUnit ) {107 MutexKeyword impl;108 acceptAll( translationUnit, impl );109 }110 111 private:112 StructDecl* monitor_decl = nullptr;113 };114 115 //=============================================================================================116 // General entry routine117 //=============================================================================================118 void applyKeywords( std::list< Declaration * > & translationUnit ) {119 ThreadKeyword ::implement( translationUnit );120 CoroutineKeyword ::implement( translationUnit );121 MonitorKeyword ::implement( translationUnit );122 MutexKeyword ::implement( translationUnit );123 }124 125 //=============================================================================================126 // Mutex keyword implementation127 //=============================================================================================128 void MutexKeyword::visit(FunctionDecl* decl) {129 std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );130 if( mutexArgs.empty() ) return;131 132 for(auto arg : mutexArgs) {133 validate( arg );134 }135 136 CompoundStmt* body = decl->get_statements();137 if( ! body ) return;138 139 assert(monitor_decl);140 addStatments( body, mutexArgs );141 }142 143 void MutexKeyword::visit(StructDecl* decl) {144 if( decl->get_name() == "monitor_desc" ) {145 assert( !monitor_decl );146 monitor_decl = decl;147 }148 }149 150 std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl ) {151 std::list<DeclarationWithType*> mutexArgs;152 153 for( auto arg : decl->get_functionType()->get_parameters()) {154 //Find mutex arguments155 Type* ty = arg->get_type();156 if( ! ty->get_qualifiers().isMutex ) continue;157 158 //Append it to the list159 mutexArgs.push_back( arg );160 }161 162 return mutexArgs;163 }164 165 void MutexKeyword::validate( DeclarationWithType * arg ) {166 Type* ty = arg->get_type();167 168 //Makes sure it's not a copy169 PointerType* pty = dynamic_cast< PointerType * >( ty );170 if( ! pty ) throw SemanticError( "Mutex argument must be of pointer/reference type ", arg );171 172 //Make sure the we are pointing directly to a type173 Type* base = pty->get_base();174 if( dynamic_cast< PointerType * >( base ) ) throw SemanticError( "Mutex argument have exactly one level of indirection ", arg );175 176 //Make sure that typed isn't mutex177 if( ! base->get_qualifiers().isMutex ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );178 }179 180 void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {181 182 ObjectDecl * monitors = new ObjectDecl(183 "__monitors",184 noStorage,185 LinkageSpec::Cforall,186 nullptr,187 new ArrayType(188 noQualifiers,189 new PointerType(190 noQualifiers,191 new StructInstType(192 noQualifiers,193 monitor_decl194 )195 ),196 new ConstantExpr( Constant::from_ulong( args.size() ) ),197 false,198 false199 ),200 new ListInit(201 map_range < std::list<Initializer*> > ( args, [](DeclarationWithType * var ){202 return new SingleInit( new UntypedExpr(203 new NameExpr( "get_monitor" ),204 { new VariableExpr( var ) }205 ) );206 })207 )208 );209 210 //in reverse order :211 // monitor_guard_t __guard = { __monitors, # };212 body->push_front(213 new DeclStmt( noLabels, new ObjectDecl(214 "__guard",215 noStorage,216 LinkageSpec::Cforall,217 nullptr,218 new StructInstType(219 noQualifiers,220 "monitor_guard_t"221 ),222 new ListInit(223 {224 new SingleInit( new VariableExpr( monitors ) ),225 new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) )226 }227 )228 ))229 );230 231 //monitor_desc * __monitors[] = { a, b };232 body->push_front( new DeclStmt( noLabels, monitors) );233 }234 };
Note:
See TracChangeset
for help on using the changeset viewer.