00001 #include <lestes/backend_v2/structs/func_data.g.hh>
00002 #include <lestes/backend_v2/intercode/ge.g.hh>
00003 #include <lestes/backend_v2/intercode/pi_mem_factory.g.hh>
00004 #include <lestes/backend_v2/workers/liveness_analysis.g.hh>
00005 #include <lestes/md/registers/tm_register.g.hh>
00006 #include <lestes/md/registers/move_generator.g.hh>
00007 #include <lestes/backend_v2/workers/alloc_int_finder.g.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::md::instructions;
00016 using namespace ::lestes::md::registers;
00017 using namespace ::lestes::md::mem;
00018
00019 typedef set<ulint> id_set__type;
00020 typedef vector<srp<ge_pi> > ge_pi_vector__type;
00021 typedef vector<srp<liveness_range> > liveness_rng_vector__type;
00022 typedef vector<srp<alloc_interval> > alloc_int_vector__type;
00023
00024
00025
00026
00027
00028
00029
00030 void alloc_int_finder::process() {
00031
00032
00033 ptr<liveness_analysis> liveness = liveness_analysis::create(data_get());
00034 liveness->process();
00035 ptr<liveness_rng_vector__type> liveness_rngs = liveness->get_result();
00036
00037
00038 ptr<alloc_int_vector__type> ints = data_get()->alloc_ints_get();
00039
00040
00041
00042
00043
00044 for(liveness_rng_vector__type::iterator it1 = liveness_rngs->begin(); it1!=liveness_rngs->end(); ++it1) {
00045 ptr<liveness_range> rng = *it1;
00046 ptr<ge_operand_reg> operand = rng->operand_get();
00047
00048 ptr<alloc_interval> prev_inter = NULL;
00049
00050 ptr<alloc_interval> inter = NULL;
00051 ptr<id_set__type> int_allowed_regs = NULL;
00052 ptr<ge_pi_vector__type> int_instrs = NULL;
00053
00054 ptr<ge_pi_vector__type> rng_instrs = rng->instructions_get();
00055
00056
00057
00058
00059
00060 for(ge_pi_vector__type::iterator it2 = rng_instrs->begin(); it2!=rng_instrs->end();) {
00061 ptr<ge_pi> ge = *it2;
00062
00063 if ( !inter ) {
00064 inter = alloc_interval::create(operand,rng);
00065 ints->push_back(inter);
00066
00067 int_allowed_regs = NULL;
00068 int_instrs = inter->instructions_get();
00069
00070
00071 if ( !prev_inter ) {
00072
00073
00074
00075
00076
00077
00078
00079
00080 if ( operand->origin_get() ) {
00081 if ( operand->origin_get()->kind_get()!=ge_pi::SP ) {
00082 int_allowed_regs = ge_pi__get_allowed_regs_for_op(operand->origin_get(),operand);
00083 }
00084
00085 int_instrs->push_back(operand->origin_get());
00086 }
00087 }
00088 }
00089
00090 if ( ge==operand->origin_get() ) {
00091
00092 ++it2;
00093 continue;
00094 }
00095
00096 if ( ge->kind_get()==ge_pi::SP ) {
00097 ++it2;
00098 int_instrs->push_back(ge);
00099 continue;
00100 }
00101
00102 ptr<id_set__type> int_allowed_regs_tmp = id_set__type::create();
00103
00104 ptr<id_set__type> op_allowed_regs = ge_pi__get_allowed_regs_for_op(ge,operand);
00105
00106 if ( !int_allowed_regs ) {
00107
00108 int_allowed_regs_tmp->insert(op_allowed_regs->begin(),op_allowed_regs->end());
00109 int_allowed_regs = int_allowed_regs_tmp;
00110 } else {
00111
00112
00113
00114
00115 set_intersection(
00116 int_allowed_regs->begin(),
00117 int_allowed_regs->end(),
00118 op_allowed_regs->begin(),
00119 op_allowed_regs->end(),
00120 ::std::insert_iterator<id_set__type>(*int_allowed_regs_tmp,int_allowed_regs_tmp->begin()));
00121 }
00122
00123 if ( int_allowed_regs_tmp->size()==0 ) {
00124
00125 lassert(int_instrs->size()!=0);
00126
00127 inter->allowed_registers_set(int_allowed_regs);
00128
00129 if ( prev_inter ) {
00130 inter->start_set(prev_inter->instructions_get()->back()->schedule_pos_get());
00131 prev_inter->end_set(int_instrs->front()->schedule_pos_get());
00132 } else {
00133 inter->start_set(int_instrs->front()->schedule_pos_get());
00134 }
00135
00136 inter->end_set(int_instrs->back()->schedule_pos_get());
00137
00138 if ( prev_inter ) {
00139 inter->prev_set(prev_inter);
00140 prev_inter->next_set(inter);
00141 }
00142
00143 prev_inter = inter;
00144
00145 inter = NULL;
00146 } else {
00147
00148 int_allowed_regs = int_allowed_regs_tmp;
00149 int_instrs->push_back(ge);
00150 ++it2;
00151 }
00152
00153
00154 }
00155
00156 if ( inter ) {
00157
00158 lassert(int_instrs->size()!=0);
00159
00160 inter->allowed_registers_set(int_allowed_regs);
00161
00162 if ( prev_inter ) {
00163 inter->start_set(prev_inter->instructions_get()->back()->schedule_pos_get());
00164 prev_inter->end_set(int_instrs->front()->schedule_pos_get());
00165 } else {
00166 inter->start_set(int_instrs->front()->schedule_pos_get());
00167 }
00168
00169 inter->end_set(int_instrs->back()->schedule_pos_get());
00170
00171 if ( prev_inter ) {
00172 inter->prev_set(prev_inter);
00173 prev_inter->next_set(inter);
00174 }
00175 }
00176
00177 }
00178
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188 ptr<id_set__type> alloc_int_finder::ge_pi__get_allowed_regs_for_op(ptr<ge_pi> ge,ptr<ge_operand_reg> op) {
00189
00190
00191 ptr<tm_instr_op_reg_base> tm_op = ge_pi__find_tm_op_by_ge_op(ge,op);
00192 lassert(tm_op);
00193
00194
00195 ptr<id_set__type> regs = id_set__type::create(tm_op->allowed_registers_get());
00196
00197 ulint type_id = op->type_get()->id_get();
00198
00199
00200
00201
00202 for(id_set__type::iterator it = regs->begin(); it!=regs->end();) {
00203 ptr<tm_register_base> reg = tm_register::instance(*it);
00204 if ( reg->compatible_types_get()->find(type_id)==reg->compatible_types_get()->end() ) {
00205 id_set__type::iterator del_it = it++;
00206 regs->erase(del_it);
00207 } else {
00208 ++it;
00209 }
00210 }
00211
00212 lassert(regs->size()!=0);
00213
00214 return regs;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224 ptr<tm_instr_op_reg_base> alloc_int_finder::ge_pi__find_tm_op_by_ge_op(ptr<ge_pi> ge,ptr<ge_operand_reg> op) {
00225 ptr<tm_instr_base> tm = ge->instruction_get();
00226
00227 lassert(tm);
00228
00229 for(ulint i=0; i<ge->operands_input_get()->size(); ++i) {
00230 if ( op==(*ge->operands_input_get())[i] ) {
00231 return (*tm->operands_input_get())[i].dncast<tm_instr_op_reg_base>();
00232 }
00233 }
00234
00235 for(ulint i=0; i<ge->operands_output_get()->size(); ++i) {
00236 if ( op==(*ge->operands_output_get())[i] ) {
00237 return (*tm->operands_output_get())[i].dncast<tm_instr_op_reg_base>();
00238 }
00239 }
00240
00241 return NULL;
00242
00243 }
00244
00245
00246
00247
00248
00249
00250
00251 ptr<func_data> alloc_int_finder::get_result() {
00252 return data_get();
00253 }
00254
00255 end_package(workers);
00256 end_package(backend_v2);
00257 end_package(lestes);
00258