Changeset 3d9d017 for src/Concurrency
- Timestamp:
- Nov 6, 2023, 2:19:37 PM (23 months ago)
- Branches:
- master
- Children:
- ba0e1bc
- Parents:
- 49ae2bc
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Corun.cpp
r49ae2bc r3d9d017 27 27 struct CorunKeyword : public WithDeclsToAdd<>, public WithStmtsToAdd<> { 28 28 UniqueName CorunFnNamer = "__CFA_corun_lambda_"s; 29 UniqueName CoforFnNamer = "__CFA_cofor_lambda_"s; 30 // UniqueName CoforFnVarNamer = "__CFA_cofor_lambda_var"s; 29 31 UniqueName RunnerBlockNamer = "__CFA_corun_block_"s; 32 33 string coforArgName = "__CFA_cofor_lambda_arg"; 34 string numProcsName = "__CFA_cofor_num_procs"; 35 string currProcsName = "__CFA_cofor_curr_procs"; 36 string thdArrName = "__CFA_cofor_thread_array"; 37 string loopTempName = "__CFA_cofor_loop_temp"; 38 30 39 31 40 const StructDecl * runnerBlockDecl = nullptr; 32 33 // Finds select_node decl 41 const StructDecl * coforRunnerDecl = nullptr; 42 43 // Finds runner_block (corun task) and cofor_runner (cofor task) decls 34 44 void previsit( const StructDecl * decl ) { 35 45 if ( !decl->body ) { … … 38 48 assert( !runnerBlockDecl ); 39 49 runnerBlockDecl = decl; 50 } else if ( "cofor_runner" == decl->name ) { 51 assert( !coforRunnerDecl ); 52 coforRunnerDecl = decl; 40 53 } 41 54 } 42 55 56 // codegen for cofor statements 57 Stmt * postvisit( const CoforStmt * stmt ) { 58 if ( !runnerBlockDecl || !coforRunnerDecl ) 59 SemanticError( stmt->location, "To use cofor statements add #include <cofor.hfa>\n" ); 60 61 if ( stmt->inits.size() != 1 ) 62 SemanticError( stmt->location, "Cofor statements must have a single initializer in the loop control\n" ); 63 64 if ( !stmt->body ) 65 return nullptr; 66 67 const CodeLocation & loc = stmt->location; 68 const string fnName = CoforFnNamer.newName(); 69 70 CompoundStmt * body = new CompoundStmt( loc ); 71 72 // push back cofor initializer to generated body 73 body->push_back( deepCopy( stmt->inits.at(0) ) ); 74 75 CompoundStmt * fnBody = new CompoundStmt( loc ); 76 77 const DeclStmt * declStmtPtr = dynamic_cast<const DeclStmt *>(stmt->inits.at(0).get()); 78 if ( ! declStmtPtr ) 79 SemanticError( stmt->location, "Cofor statement initializer is somehow not a decl statement?\n" ); 80 81 const Decl * declPtr = dynamic_cast<const Decl *>(declStmtPtr->decl.get()); 82 if ( ! declPtr ) 83 SemanticError( stmt->location, "Cofor statement initializer is somehow not a decl?\n" ); 84 85 Type * initType = new TypeofType( new NameExpr( loc, declPtr->name ) ); 86 87 // Generates: 88 // typeof(init) __CFA_cofor_lambda_var = *((typeof(init) *)val); 89 fnBody->push_back( new DeclStmt( loc, 90 new ObjectDecl( loc, 91 declPtr->name, 92 initType, 93 new SingleInit( loc, 94 UntypedExpr::createDeref( loc, 95 new CastExpr( loc, 96 new NameExpr( loc, coforArgName ), 97 new PointerType( initType ), ExplicitCast 98 ) 99 ) 100 ) 101 ) 102 )); 103 104 // push rest of cofor body into loop lambda 105 fnBody->push_back( deepCopy( stmt->body ) ); 106 107 // Generates: 108 // void __CFA_cofor_lambda_() { 109 // typeof(init) __CFA_cofor_lambda_var = *((typeof(init) *)val); 110 // stmt->body; 111 // } 112 Stmt * coforLambda = new DeclStmt( loc, 113 new FunctionDecl( loc, 114 fnName, // name 115 {}, // forall 116 { 117 new ObjectDecl( loc, 118 coforArgName, 119 new ast::PointerType( new ast::VoidType() ) 120 ) 121 }, // params 122 {}, // return 123 fnBody // body 124 ) 125 ); 126 body->push_back( coforLambda ); 127 128 // Generates: 129 // unsigned __CFA_cofor_num_procs = get_proc_count(); 130 body->push_back( new DeclStmt( loc, 131 new ObjectDecl( loc, 132 numProcsName, 133 new BasicType( BasicType::Kind::UnsignedInt ), 134 new SingleInit( loc, 135 new UntypedExpr( loc, 136 new NameExpr( loc, "get_proc_count" ), 137 {} 138 ) 139 ) 140 ) 141 ) 142 ); 143 144 // Generates: 145 // unsigned __CFA_cofor_curr_procs = 0; 146 body->push_back( new DeclStmt( loc, 147 new ObjectDecl( loc, 148 currProcsName, 149 new BasicType( BasicType::Kind::UnsignedInt ), 150 new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) ) 151 ) 152 ) 153 ); 154 155 // Generates: 156 // unsigned cofor_runner __CFA_cofor_thread_array[nprocs]; 157 body->push_back( new DeclStmt( loc, 158 new ObjectDecl( loc, 159 thdArrName, 160 new ast::ArrayType( 161 new StructInstType( coforRunnerDecl ), 162 new NameExpr( loc, numProcsName ), 163 ast::FixedLen, 164 ast::DynamicDim 165 ) 166 ) 167 ) 168 ); 169 170 // Generates: 171 // start_runners( __CFA_cofor_thread_array, __CFA_cofor_num_procs, __CFA_cofor_lambda_ ); 172 body->push_back( new ExprStmt( loc, 173 new UntypedExpr( loc, 174 new NameExpr( loc, "start_runners" ), 175 { 176 new NameExpr( loc, thdArrName ), 177 new NameExpr( loc, numProcsName ), 178 new NameExpr( loc, fnName ) 179 } 180 ) 181 )); 182 183 // Generates: 184 // typeof(initializer) * __CFA_cofor_loop_temp = malloc(); 185 CompoundStmt * forLoopBody = new CompoundStmt( loc ); 186 forLoopBody->push_back( new DeclStmt( loc, 187 new ObjectDecl( loc, 188 loopTempName, 189 new PointerType( initType ), 190 new SingleInit( loc, 191 new UntypedExpr( loc, 192 new NameExpr( loc, "malloc" ), 193 {} 194 ) 195 ) 196 ) 197 ) 198 ); 199 200 // Generates: 201 // *__CFA_cofor_loop_temp = initializer; 202 forLoopBody->push_back( new ExprStmt( loc, 203 UntypedExpr::createAssign( loc, 204 UntypedExpr::createDeref( loc, new NameExpr( loc, loopTempName ) ), 205 new NameExpr( loc, declPtr->name ) 206 ) 207 )); 208 209 // Generates: 210 // send_work( __CFA_cofor_thread_array, __CFA_cofor_num_procs, 211 // __CFA_cofor_curr_procs, __CFA_cofor_loop_temp ); 212 forLoopBody->push_back( new ExprStmt( loc, 213 new UntypedExpr( loc, 214 new NameExpr( loc, "send_work" ), 215 { 216 new NameExpr( loc, thdArrName ), 217 new NameExpr( loc, numProcsName ), 218 new NameExpr( loc, currProcsName ), 219 new NameExpr( loc, loopTempName ) 220 } 221 ) 222 )); 223 224 body->push_back( new ForStmt( loc, 225 {}, 226 deepCopy( stmt->cond ), 227 deepCopy( stmt->inc ), 228 forLoopBody 229 )); 230 231 // Generates: 232 // end_runners( __CFA_cofor_thread_array, __CFA_cofor_num_procs ); 233 body->push_back( new ExprStmt( loc, 234 new UntypedExpr( loc, 235 new NameExpr( loc, "end_runners" ), 236 { 237 new NameExpr( loc, thdArrName ), 238 new NameExpr( loc, numProcsName ) 239 } 240 ) 241 )); 242 243 return body; 244 } 245 246 // codegen for corun statements 43 247 Stmt * postvisit( const CorunStmt * stmt ) { 44 if ( !runnerBlockDecl )248 if ( !runnerBlockDecl || !coforRunnerDecl ) 45 249 SemanticError( stmt->location, "To use corun statements add #include <cofor.hfa>\n" ); 46 250
Note:
See TracChangeset
for help on using the changeset viewer.