00001 #include <lestes/backend_v2/structs/func_data.g.hh>
00002 #include <lestes/backend_v2/intercode/pi.g.hh>
00003 #include <lestes/backend_v2/intercode/ge.g.hh>
00004 #include <lestes/backend_v2/workers/scheduler.g.hh>
00005 #include <lestes/backend_v2/workers/bb_finder.g.hh>
00006 #include <lestes/md/instructions/tm_instr_base.g.hh>
00007 #include <lestes/md/instructions/execution_info.g.hh>
00008
00009 #include <lestes/backend_v2/debug/debug.hh>
00010
00011 package(lestes);
00012 package(backend_v2);
00013 package(workers);
00014
00015 using namespace ::lestes::backend_v2::debug;
00016 using namespace ::lestes::backend_v2::structs;
00017 using namespace ::lestes::backend_v2::intercode;
00018 using namespace ::lestes::md::instructions;
00019 using namespace ::lestes::msg;
00020
00021 typedef set< srp<ge_pi> > ge_pi_set__type;
00022 typedef vector< srp<ge_pi> > ge_pi_vector__type;
00023 typedef list< srp<ge_pi> > ge_pi_list__type;
00024 typedef vector< srp<basic_block> > bb_vector__type;
00025 typedef map< srp<ge_pi>, srp<schedule_item> > ge2si__type;
00026 typedef set< srp<schedule_item> > si_set__type;
00027 typedef vector< srp<schedule_item> > si_vector__type;
00028
00029 declare_logger(schedlog);
00030 initialize_logger( schedlog, "scheduler", backend_v2_logger );
00031
00032
00033
00034
00035 void scheduler::process() {
00036 schedlog << "process start\n" << eolog;
00037
00038 ptr<ge_pi_list__type> body = ge_pi_list__type::create();
00039
00040 current_schedule_pos = 0;
00041
00042 ptr<bb_vector__type> bbs = data_get()->bbs_get();
00043
00044 for(bb_vector__type::iterator it = bbs->begin(); it!=bbs->end(); ++it) {
00045 ptr<basic_block> bb = *it;
00046
00047
00048 body->push_back(bb->fsp_get());
00049 bb->fsp_get()->schedule_pos_set(current_schedule_pos++);
00050
00051
00052 ptr<ge_pi_vector__type> output = process_bb(bb);
00053 body->insert(body->end(), output->begin(), output->end());
00054 }
00055
00056
00057 ptr<ge_pi> lsp = bbs->back()->lsp_get();
00058 lsp->schedule_pos_set(current_schedule_pos);
00059 body->push_back(lsp);
00060
00061 data_get()->ge_body_set(body);
00062
00063 schedlog << "process end\n" << eolog;
00064 }
00065
00066
00067
00068
00069
00070
00071
00072 ptr<ge_pi_vector__type> scheduler::process_bb(ptr<basic_block> bb) {
00073 schedlog << "process_bb start\n" << eolog;
00074 ptr<si_set__type> sch_items = find_schedule_items(bb);
00075
00076 if ( !dumb_scheduling_get() ) {
00077
00078 find_critical_paths(sch_items);
00079 }
00080 ptr<ge_pi_vector__type> output = schedule_items(sch_items);
00081 schedlog << "process_bb end\n" << eolog;
00082 return output;
00083 }
00084
00085
00086
00087
00088 bool schedule_items_cmp1(srp<schedule_item> a, srp<schedule_item> b) {
00089 return a->latest_start_time_get() < b->latest_start_time_get();
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099 ptr<ge_pi_vector__type> scheduler::schedule_items(ptr<si_set__type> items) {
00100 schedlog << "schedule_items start\n" << eolog;
00101
00102 ptr<ge_pi_vector__type> schedule = ge_pi_vector__type::create();
00103
00104 ptr<si_set__type> waiting = items;
00105 ptr<si_vector__type> ready = si_vector__type::create();
00106
00107
00108 for(si_set__type::iterator it=waiting->begin(); it!=waiting->end();) {
00109 ptr<schedule_item> si = *it;
00110
00111 si->out_deps_set(si->out_deps_copy_get());
00112
00113 if ( si->in_deps_get()->size()==0 ) {
00114 si_set__type::iterator del_it = it++;
00115 waiting->erase(del_it);
00116 ready->push_back(si);
00117 } else {
00118 ++it;
00119 }
00120 }
00121
00122
00123 ::std::sort(ready->begin(),ready->end(),schedule_items_cmp1);
00124
00125 while( ready->size()!=0 ) {
00126 ptr<schedule_item> si = *ready->begin();
00127
00128 schedule->push_back(si->instruction_get());
00129 si->instruction_get()->schedule_pos_set(current_schedule_pos++);
00130 ready->erase(ready->begin());
00131
00132 bool b_ready_set_changed = false;
00133
00134
00135 ptr<si_set__type> deps = si->out_deps_get();
00136 for(si_set__type::iterator it1 = deps->begin(); it1!=deps->end(); ++it1) {
00137 ptr<schedule_item> dep = *it1;
00138 dep->in_deps_get()->erase(si);
00139
00140 if ( dep->in_deps_get()->size()==0 ) {
00141
00142 waiting->erase(dep);
00143 ready->push_back(dep);
00144 b_ready_set_changed = true;
00145 }
00146 }
00147
00148 if ( b_ready_set_changed ) {
00149
00150 ::std::sort(ready->begin(),ready->end(),schedule_items_cmp1);
00151 }
00152 }
00153
00154 if ( waiting->size()!=0 ) {
00155 b_dump(waiting,"waiting");
00156 }
00157 lassert(waiting->size()==0);
00158
00159 schedlog << "schedule_items end\n" << eolog;
00160 return schedule;
00161 }
00162
00163
00164
00165
00166
00167
00168 void scheduler::check_waiting_set(ptr<si_set__type> waiting) {
00169 for(si_set__type::iterator it = waiting->begin(); it!=waiting->end(); ++it) {
00170 ptr<schedule_item> si = *it;
00171
00172 if ( find_dependence_loop(si,si,0) ) {
00173 return;
00174 }
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183 bool scheduler::find_dependence_loop(ptr<schedule_item> start,ptr<schedule_item> curr,ulint depth) {
00184 if ( depth > 4 ) {
00185 return false;
00186 }
00187
00188 ptr<si_set__type> deps = curr->in_deps_get();
00189
00190 for(si_set__type::iterator it = deps->begin(); it!=deps->end(); ++it) {
00191 ptr<schedule_item> dep = *it;
00192
00193 if ( dep==start || find_dependence_loop(start,dep,depth+1)) {
00194 schedlog << "find_dependence_loop found:item=" << curr->uid_get() << "\n" << eolog;
00195 return true;
00196 }
00197 }
00198
00199 return false;
00200 }
00201
00202
00203
00204
00205 void scheduler::find_critical_paths(ptr<si_set__type> items) {
00206 schedlog << "find_critical_paths start\n" << eolog;
00207
00208
00209 ulint cp_length = 0;
00210
00211 ptr<si_set__type> waiting = si_set__type::create(items);
00212
00213 ulint u_tmp = 0;
00214
00215 si_set__type::iterator it = waiting->begin();
00216 while( waiting->size()!=0 ) {
00217 ptr<schedule_item> si = *it;
00218
00219 if ( ++u_tmp > 10000 ) {
00220 lassert2(false,"An infinite loop detected.");
00221 }
00222
00223 if ( si->in_deps_get()->size()==0 ) {
00224
00225 si->end_time_set(si->start_time_get() + si->etime_get());
00226
00227
00228 ulint succ_start_time = si->end_time_get() + si->ctime_get();
00229
00230 if ( succ_start_time > cp_length ) {
00231 cp_length = succ_start_time;
00232 }
00233
00234
00235 ptr<si_set__type> deps = si->out_deps_get();
00236 for(si_set__type::iterator it1 = deps->begin(); it1!=deps->end(); ++it1) {
00237 ptr<schedule_item> dep = *it1;
00238
00239 dep->in_deps_get()->erase(si);
00240
00241
00242 if ( dep->start_time_get()<succ_start_time ) {
00243 dep->start_time_set(succ_start_time);
00244 }
00245 }
00246 si_set__type::iterator del_it = it++;
00247 waiting->erase(del_it);
00248 } else {
00249 ++it;
00250 }
00251
00252 if ( it==waiting->end() ) {
00253 it = waiting->begin();
00254 }
00255 }
00256
00257
00258 waiting = si_set__type::create(items);
00259 for(it = waiting->begin(); it!=waiting->end(); ++it) {
00260 ptr<schedule_item> si = *it;
00261
00262 if ( si->end_time_get() + si->ctime_get() == cp_length ) {
00263
00264 si->latest_start_time_set(si->end_time_get() - si->etime_get());
00265 }
00266
00267 si->in_deps_set(si->in_deps_copy_get());
00268 }
00269
00270
00271 it = waiting->begin();
00272 while( waiting->size()!=0 ) {
00273 ptr<schedule_item> si = *it;
00274
00275 if ( si->out_deps_get()->size()==0 ) {
00276 ulint lst = si->latest_start_time_get();
00277
00278
00279 ptr<si_set__type> deps = si->in_deps_get();
00280 for(si_set__type::iterator it1 = deps->begin(); it1!=deps->end(); ++it1) {
00281 ptr<schedule_item> dep = *it1;
00282 dep->out_deps_get()->erase(si);
00283
00284 ulint tmp_lst = lst - dep->ctime_get() - dep->etime_get();
00285
00286 if ( tmp_lst < dep->latest_start_time_get() ) {
00287 dep->latest_start_time_set(tmp_lst);
00288 }
00289 }
00290
00291 si_set__type::iterator del_it = it++;
00292 waiting->erase(del_it);
00293 } else {
00294 ++it;
00295 }
00296
00297 if ( it==waiting->end() ) {
00298 it = waiting->begin();
00299 }
00300 }
00301
00302 schedlog << "find_critical_paths end\n" << eolog;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 ptr<si_set__type> scheduler::find_schedule_items(ptr<basic_block> bb) {
00312 schedlog << "find_schedule_items start\n" << eolog;
00313
00314 ge2si->clear();
00315
00316 ptr<si_set__type> schedule_items = si_set__type::create();
00317
00318 ptr<ge_pi_vector__type> instrs = bb->instructions_get();
00319
00320
00321 for(ge_pi_vector__type::iterator it = instrs->begin(); it!=instrs->end(); ++it) {
00322 ptr<ge_pi> ge = *it;
00323
00324 ptr<schedule_item> si;
00325
00326 ge2si__type::iterator si_search = ge2si->find(ge);
00327 if ( si_search!=ge2si->end() ) {
00328 si = si_search->second;
00329 } else {
00330 si = create_schedule_item(ge);
00331 (*ge2si)[ge] = si;
00332 }
00333
00334 schedule_items->insert(si);
00335
00336 ptr<ge_pi_set__type> in_deps = ge->dependencies_get();
00337 for(ge_pi_set__type::iterator it1 = in_deps->begin(); it1!=in_deps->end(); ++it1 ) {
00338 ptr<ge_pi> dep_ge = *it1;
00339
00340 if ( dep_ge->bb_get()!=bb || dep_ge==ge) {
00341 continue;
00342 }
00343
00344 ptr<schedule_item> dep;
00345
00346 si_search = ge2si->find(dep_ge);
00347 if ( si_search!=ge2si->end() ) {
00348 dep = si_search->second;
00349 } else {
00350 dep = create_schedule_item(*it1);
00351 (*ge2si)[dep_ge] = dep;
00352 }
00353
00354 si->in_deps_get()->insert(dep);
00355 dep->out_deps_get()->insert(si);
00356 }
00357
00358 }
00359
00360 for(si_set__type::iterator it=schedule_items->begin(); it!=schedule_items->end(); ++it) {
00361 ptr<schedule_item> si = *it;
00362 si->in_deps_copy_set(si_set__type::create(si->in_deps_get()));
00363 si->out_deps_copy_set(si_set__type::create(si->out_deps_get()));
00364 }
00365
00366 schedlog << "find_schedule_items end\n" << eolog;
00367 return schedule_items;
00368 }
00369
00370
00371
00372
00373
00374
00375
00376 ptr<schedule_item> scheduler::create_schedule_item(ptr<ge_pi> ge) {
00377
00378 ptr<tm_instr_base> tm = ge->instruction_get();
00379
00380 ulint et, ct;
00381
00382 if ( tm && tm->exec_info_get() ) {
00383 et = tm->exec_info_get()->etime_get();
00384 ct = 0;
00385 } else {
00386 et = 0;
00387 ct = 0;
00388 }
00389
00390 ptr<schedule_item> si = schedule_item::create(ge,et,ct);
00391
00392 return si;
00393 }
00394
00395
00396
00397
00398 ptr<func_data> scheduler::get_result() {
00399 return data_get();
00400 }
00401
00402
00403 end_package(workers);
00404 end_package(backend_v2);
00405 end_package(lestes);
00406