00001 #include <lestes/backend_v2/workers/order_governor.g.hh>
00002 #include <lestes/backend_v2/intercode/pi.g.hh>
00003 #include <lestes/backend_v2/structs/func_data.g.hh>
00004 #include <lestes/backend_v2/intercode/visitor_pi_pi2pi_operands.g.hh>
00005 #include <lestes/backend_v2/intercode/visitor_pi_pi2id.g.hh>
00006 #include <lestes/backend_v2/structs/pi_operands.g.hh>
00007 #include <lestes/backend_v2/debug/debug.hh>
00008
00009 package(lestes);
00010 package(backend_v2);
00011 package(workers);
00012
00013 using namespace ::lestes::backend_v2::intercode;
00014 using namespace ::lestes::backend_v2::structs;
00015 using namespace ::lestes::msg;
00016
00017 typedef list< srp< pi_pi > > pi_list_type;
00018 typedef list< srp< pi_sp > > sp_list_type;
00019 typedef vector< srp< pi_operand > > operand_vector_type;
00020 typedef map< srp<pi_pi>, bool > pi_bool_map_type;
00021
00022
00023 declare_logger(og_log);
00024 initialize_logger( og_log, "order_governor", backend_v2_logger );
00025
00026
00027
00028
00029
00030 void order_governor::process()
00031 {
00032 og_log << "Process begin\n" << eolog;
00033
00034 pis_unordered = data_get()->pi_body_get();
00035
00036
00037 identify_level_0();
00038
00039
00040 while( !pis_unordered_get()->empty() ) {
00041 og_log << "Main loop begin.\n" << eolog;
00042
00043
00044 merge_ordered_with_unordered_level_X(1);
00045
00046 torder_ordered();
00047
00048 linearize_ordered_sps();
00049
00050 shift_unordered_nsp_psp();
00051
00052 renumber_levels(pis_unordered_get());
00053
00054 renumber_levels(pis_ordered_get());
00055
00056 og_log << "Main loop end.\n" << eolog;
00057 }
00058
00059 og_log << "Process end.\n" << eolog;
00060 }
00061
00062
00063
00064
00065
00066 void order_governor::identify_level_0()
00067 {
00068
00069 merge_ordered_with_unordered_level_X(0);
00070
00071
00072 pi_list_type::iterator it;
00073 for(it=pis_ordered->begin(); it != pis_ordered->end(); it++) {
00074 (*is_ordered)[*it] = true;
00075 }
00076
00077
00078 for(it=pis_unordered->begin(); it != pis_unordered->end(); it++) {
00079 (*is_ordered)[*it] = false;
00080 }
00081 }
00082
00083
00084
00085
00086
00087 void order_governor::merge_ordered_with_unordered_level_X(level_t level_to_merge)
00088 {
00089
00090 for(pi_list_type::iterator it = pis_unordered_get()->begin(); it != pis_unordered_get()->end();) {
00091 if ( (*it)->level_get() == level_to_merge ) {
00092 og_log << "Merging L0 with L" << level_to_merge << ": " << (*it)->reflection_get()->back()->name_get() << "(" << (*it)->uid_get() << ")[level=" << (*it)->level_get() << "] added\n" << eolog;;
00093
00094
00095 pis_ordered->push_back(*it);
00096
00097 it = pis_unordered->erase(it);
00098 } else {
00099 ++it;
00100 }
00101 }
00102
00103 }
00104
00105
00106
00107
00108 void order_governor::linearize_ordered_sps() {
00109 ptr<visitor_pi_pi2id> identificator = visitor_pi_pi2id::create();
00110
00111
00112
00113
00114 ptr<pi_pi> previous = NULL;
00115 ptr<pi_pi> current = NULL;
00116 pi_list_type::iterator it;
00117 for(it=pis_ordered->begin(); it != pis_ordered->end(); it++) {
00118
00119
00120
00121 current = (*it);
00122
00123 if ( previous ) {
00124 previous->nsp_set(current);
00125 }
00126 current->psp_set(previous);
00127 previous = current;
00128
00129 }
00130 current->nsp_set(NULL);
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140 void order_governor::torder_ordered()
00141 {
00142
00143 og_log << "Tordering begin\n" << eolog;
00144
00145
00146 ptr<visitor_pi_pi2pi_operands> operands_getter = visitor_pi_pi2pi_operands::create();
00147
00148
00149 ptr<visitor_pi_pi2id> identificator = visitor_pi_pi2id::create();
00150
00151
00152 ptr<pi_list_type> tordered_list = pi_list_type::create();
00153
00154 ptr<pi_list_type> tunordered_list = pis_ordered_get();
00155
00156
00157 pi_list_type::iterator it;
00158 for(it=tunordered_list->begin(); it != tunordered_list->end(); it++) {
00159 (*is_ordered)[*it] = false;
00160 }
00161
00162 #ifdef BACKEND_V2_DEBUG
00163
00164 ulint dbg = 0;
00165 #endif
00166
00167
00168 while( !tunordered_list->empty()) {
00169
00170 #ifdef BACKEND_V2_DEBUG
00171 lassert2(dbg<=tunordered_list->size(),"An inifinite loop detected.");
00172 dbg++;
00173 #endif
00174
00175
00176 ptr<pi_pi> pi = tunordered_list->front();
00177
00178
00179 tunordered_list->pop_front();
00180
00181 og_log << "Tordering: trying order " << pi->reflection_get()->back()->name_get() << "(" << pi->uid_get() << ")\n" << eolog;
00182
00183 if ( pi->psp_get() && (*is_ordered_get())[pi->psp_get()] == false ) {
00184
00185 tunordered_list->push_back(pi);
00186
00187 og_log << "\tTordering: current pi can't be ordered (psp is not ordered yet)\n" << eolog;
00188
00189 continue;
00190 }
00191
00192
00193 ptr<pi_operands> operands = pi->accept_visitor_pi_pi2pi_operands_gen_base(operands_getter);
00194
00195
00196
00197
00198 if ( !pi_operands_origins_ordered(operands->operands_input_get()) ) {
00199
00200 tunordered_list->push_back(pi);
00201
00202 og_log << "\tTordering: current pi can't be ordered (origins of operands are not ordered yet)\n" << eolog;
00203
00204 continue;
00205 }
00206
00207 if ( nsp_for_any(pi, tunordered_list) ) {
00208
00209 tunordered_list->push_back(pi);
00210
00211 og_log << "\tTordering: current pi can't be ordered (sp is nsp for unorderd pi)\n" << eolog;
00212
00213 continue;
00214 }
00215
00216 (*is_ordered_get())[pi] = true;
00217 tordered_list->push_back(pi);
00218
00219 og_log << "\tTordering: " << pi->reflection_get()->back()->name_get() << "(" << pi->uid_get() << ") is set as ordered\n" << eolog;
00220
00221 #ifdef BACKEND_V2_DEBUG
00222 dbg = 0;
00223 #endif
00224
00225 }
00226
00227
00228 pis_ordered_set(tordered_list);
00229
00230 og_log << "Tordering end\n" << eolog;
00231 }
00232
00233
00234
00235
00236
00237
00238 bool order_governor::nsp_for_any(ptr<pi_pi> sp, ptr<pi_list_type> list) {
00239
00240 pi_list_type::iterator it;
00241 for(it = list->begin(); it != list->end();it++) {
00242 if ( (*it)->nsp_get()==sp ) {
00243 return true;
00244 }
00245 }
00246 return false;
00247 }
00248
00249
00250
00251
00252
00253 bool order_governor::pi_operands_origins_ordered(ptr<operand_vector_type> operand_list) {
00254 lassert(operand_list);
00255
00256
00257 operand_vector_type::iterator it;
00258 for(it=operand_list->begin(); it!=operand_list->end(); it++) {
00259 ptr<pi_pi> origin = (*it)->origin_get();
00260
00261 if ( !origin ) {
00262
00263 continue;
00264 }
00265
00266
00267 pi_bool_map_type::iterator it1 = is_ordered->find(origin);
00268
00269
00270 lassert(it1!=is_ordered->end());
00271
00272 if ( !it1->second ) {
00273
00274 return false;
00275 }
00276 }
00277 return true;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286 int order_governor::get_pi_level(ptr < pi_pi > pi)
00287 {
00288 return pi ? (int)pi->level_get() : -1;
00289 }
00290
00291
00292
00293
00294
00295
00296
00297 ptr<pi_pi> order_governor::conjugated_chain_end_find(ptr<pi_pi> pi)
00298 {
00299 while(pi->nsp_get() && pi->nsp_get()->psp_get()==pi) {
00300 pi = pi->nsp_get();
00301 }
00302 return pi;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 ptr<pi_pi> order_governor::conjugated_chain_start_find(ptr<pi_pi> pi)
00312 {
00313 while(pi->psp_get() && pi->psp_get()->nsp_get()==pi) {
00314 pi = pi->psp_get();
00315 }
00316 return pi;
00317 }
00318
00319
00320
00321
00322
00323 void order_governor::shift_unordered_nsp_psp()
00324 {
00325
00326 pi_list_type::iterator it;
00327 for(it = pis_unordered->begin(); it!=pis_unordered->end(); it++) {
00328 ptr<pi_pi> pi = (*it);
00329
00330 og_log << "shift_unordered_nsp_psp: pi(" << pi->uid_get() << ").level= " << get_pi_level(pi) << "\n" << msg::eolog;
00331
00332 lassert(get_pi_level(pi)>1);
00333
00334 if ( get_pi_level(pi->psp_get())==0 ) {
00335 ptr<pi_pi> pi_hlp = conjugated_chain_end_find(pi);
00336
00337 og_log << "shift_psp: chain_end(" << pi_hlp->uid_get() << ").nsp.level=" << get_pi_level(pi_hlp->nsp_get()) << "\n" << msg::eolog;
00338
00339 lassert(get_pi_level(pi_hlp)==get_pi_level(pi));
00340
00341 if (get_pi_level(pi_hlp->nsp_get())>0){
00342 pi->psp_set(pi_hlp->nsp_get()->psp_get());
00343 }
00344
00345 } else if ( get_pi_level(pi->nsp_get())==0 ) {
00346 ptr<pi_pi> pi_hlp = conjugated_chain_start_find(pi);
00347
00348 og_log << "shift_nsp: chain_begin(" << pi_hlp->uid_get() << ").psp.level=" << get_pi_level(pi_hlp->psp_get()) << "\n" << msg::eolog;
00349
00350 lassert(get_pi_level(pi_hlp)==get_pi_level(pi));
00351
00352 if (get_pi_level(pi_hlp->psp_get())>0) {
00353 pi->nsp_set(pi_hlp->psp_get()->nsp_get());
00354 }
00355 }
00356 }
00357 }
00358
00359
00360
00361
00362
00363 void order_governor::renumber_levels(ptr<pi_list_type> pi_list)
00364 {
00365 lassert(pi_list);
00366
00367
00368 pi_list_type::iterator it;
00369 for(it = pi_list->begin(); it!=pi_list->end(); it++) {
00370 ptr<pi_pi> pi = (*it);
00371
00372 if ( pi->level_get() > 0 ) {
00373 pi->level_set(pi->level_get()-1);
00374 }
00375 }
00376 }
00377
00378
00379
00380
00381 ptr<func_data> order_governor::get_result()
00382 {
00383 lassert(pis_ordered);
00384
00385 ptr<visitor_pi_pi2id> pi_id_getter = visitor_pi_pi2id::create();
00386
00387
00388
00389
00390 ptr<pi_sp> tmp_sp = NULL;
00391 for(pi_list_type::iterator it_pi_list = pis_ordered->begin(); it_pi_list!=pis_ordered->end(); ++it_pi_list) {
00392 ptr<pi_pi> pi = *it_pi_list;
00393
00394 visitor_pi_pi2id::kind_type pi_id = (visitor_pi_pi2id::kind_type)pi->accept_visitor_pi_pi2ulint_gen_base(pi_id_getter);
00395
00396
00397 pi->psp_set(tmp_sp);
00398
00399
00400 if ( pi_id==visitor_pi_pi2id::PI_SP ) {
00401 tmp_sp = pi.dncast<pi_sp>();
00402 }
00403
00404 }
00405
00406
00407
00408
00409 tmp_sp = NULL;
00410 for(pi_list_type::reverse_iterator it_pi_list = pis_ordered->rbegin(); it_pi_list!=pis_ordered->rend(); ++it_pi_list) {
00411 ptr<pi_pi> pi = *it_pi_list;
00412
00413 visitor_pi_pi2id::kind_type pi_id = (visitor_pi_pi2id::kind_type)pi->accept_visitor_pi_pi2ulint_gen_base(pi_id_getter);
00414
00415 pi->nsp_set(tmp_sp);
00416
00417 if ( pi_id==visitor_pi_pi2id::PI_SP ) {
00418 tmp_sp = pi.dncast<pi_sp>();
00419 }
00420 }
00421
00422 data_get()->pi_body_set(pis_ordered);
00423
00424 return data_get();
00425 }
00426
00427 end_package(workers);
00428 end_package(backend_v2);
00429 end_package(lestes);
00430