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.g.hh>
00004 #include <lestes/backend_v2/workers/bb_finder.g.hh>
00005 #include <lestes/md/instructions/tm_instr.g.hh>
00006
00007 package(lestes);
00008 package(backend_v2);
00009 package(workers);
00010
00011 using namespace ::lestes::backend_v2::structs;
00012 using namespace ::lestes::backend_v2::intercode;
00013 using namespace ::lestes::md::instructions;
00014 using namespace ::lestes::msg;
00015
00016 typedef set< srp<ge_pi> > ge_pi_set__type;
00017 typedef map<srp<pi_mem_factory>,srp<set< srp<ge_pi> > > > m2ge_pi_set__type;
00018 typedef list< srp<ge_pi> > ge_pi_list__type;
00019 typedef vector< srp<ge_pi> > ge_pi_vector__type;
00020 typedef vector< srp<ge_operand> > ge_operand_vector__type;
00021 typedef vector< srp<basic_block> > bb_vector__type;
00022
00023 declare_logger(bblog);
00024 initialize_logger( bblog, "bb_finder", backend_v2_logger );
00025
00026
00027
00028
00029 void bb_finder::process() {
00030
00031 ptr<ge_pi_list__type> body = data_get()->ge_body_get();
00032 ptr<bb_vector__type> bbs = data_get()->bbs_get();
00033
00034 ptr<basic_block> prev_bb = NULL;
00035 ptr<basic_block> active_bb = NULL;
00036
00037 bool b_active_is_safe = true;
00038
00039 for(ge_pi_list__type::iterator it = body->begin(); it!=body->end(); ++it) {
00040 ptr<ge_pi> ge = *it;
00041
00042 if (ge->kind_get()==ge_pi::SP ) {
00043 ptr<ge_sp> sp = ge.dncast<ge_sp>();
00044
00045 if ( active_bb ) {
00046 active_bb->lsp_set(sp);
00047
00048 if ( prev_bb ) {
00049
00050 active_bb = join_blocks(prev_bb,active_bb);
00051 } else {
00052 bbs->push_back(active_bb);
00053 }
00054
00055 if ( sp->is_jmp_target_get() || !b_active_is_safe ) {
00056 prev_bb = NULL;
00057 } else {
00058 prev_bb = active_bb;
00059 }
00060
00061 active_bb = NULL;
00062 }
00063
00064 if ( !active_bb && ge!=body->back() ) {
00065 active_bb = basic_block::create();
00066 active_bb->fsp_set(sp);
00067 b_active_is_safe = true;
00068 }
00069
00070 } else {
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 prev_bb = NULL;
00081
00082 ge->bb_set(active_bb);
00083 active_bb->instructions_get()->push_back(ge);
00084
00085 if ( !is_instruction_safe(ge) ) {
00086
00087 prev_bb = NULL;
00088 b_active_is_safe = false;
00089 }
00090 }
00091 }
00092 }
00093
00094
00095
00096
00097
00098
00099
00100 bool bb_finder::is_instruction_safe(ptr<ge_pi> ge) {
00101 if ( (ge->instruction_get() && ( ge->instruction_get()->is_system() || ge->instruction_get()->is_jump()) ) ||
00102 (ge->kind_get()==ge_pi::SP && ge.dncast<ge_sp>()->is_jmp_target_get()) ) {
00103 return false;
00104 }
00105
00106 ptr<ge_operand_vector__type> operands = ge->operands_input_get();
00107
00108 for(ge_operand_vector__type::iterator it_op = operands->begin(); it_op!=operands->end(); ++it_op) {
00109 if ( (*it_op)->kind_get()!=ge_operand::MEMORY ) {
00110 continue;
00111 }
00112
00113 ptr<pi_mem_factory> mf = (*it_op).dncast<ge_operand_mem>()->factory_get();
00114
00115 if ( mf->kind_get()==pi_mem_factory::MF_PTR_DEREF ) {
00116 return false;
00117 }
00118 }
00119
00120 operands = ge->operands_output_get();
00121
00122 for(ge_operand_vector__type::iterator it_op = operands->begin(); it_op!=operands->end(); ++it_op) {
00123 if ( (*it_op)->kind_get()!=ge_operand::MEMORY ) {
00124 continue;
00125 }
00126
00127 ptr<pi_mem_factory> mf = (*it_op).dncast<ge_operand_mem>()->factory_get();
00128
00129 if ( mf->kind_get()==pi_mem_factory::MF_PTR_DEREF ) {
00130 return false;
00131 }
00132 }
00133
00134 return true;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144 ptr<basic_block> bb_finder::join_blocks(ptr<basic_block> bb1, ptr<basic_block> bb2) {
00145 ptr<ge_pi_vector__type> active_instrs = bb2->instructions_get();
00146 ptr<ge_pi_vector__type> prev_instrs = bb1->instructions_get();
00147
00148 ptr<ge_sp> prev_fsp = bb1->fsp_get();
00149 ptr<ge_sp> active_lsp = bb2->lsp_get();
00150
00151 bb1->lsp_set(active_lsp);
00152
00153 ptr<ge_sp> active_fsp = bb2->fsp_get();
00154
00155
00156
00157
00158
00159
00160 ptr<ge_sp> new_sp = ge_sp::create(NULL,NULL);
00161 new_sp->operands_input_set(active_fsp->operands_input_get());
00162 new_sp->dependencies_set(active_fsp->dependencies_get());
00163 new_sp->bb_set(bb1);
00164 prev_instrs->push_back(new_sp);
00165
00166 prev_instrs->push_back(active_fsp);
00167 active_fsp->dependencies_set(ge_pi_set__type::create());
00168 active_fsp->operands_input_set(ge_operand_vector__type::create());
00169 active_fsp->bb_set(bb1);
00170
00171
00172
00173
00174 ptr<m2ge_pi_set__type> mfdeps = m2ge_pi_set__type::create();
00175
00176 for(ge_pi_vector__type::iterator it = prev_instrs->begin(); it!=prev_instrs->end(); ++it) {
00177 ptr<ge_pi> ge = *it;
00178
00179 active_lsp->dependencies_get()->insert(ge);
00180
00181 ptr<ge_operand_vector__type> operands = ge->operands_input_get();
00182
00183 for(ge_operand_vector__type::iterator it_op = operands->begin(); it_op!=operands->end(); ++it_op) {
00184 if ( (*it_op)->kind_get()!=ge_operand::MEMORY ) {
00185 continue;
00186 }
00187
00188 ptr<pi_mem_factory> mf = (*it_op).dncast<ge_operand_mem>()->factory_get();
00189
00190 m2ge_pi_set__type::iterator it_search = mfdeps->find(mf);
00191
00192 if ( it_search!=mfdeps->end() ) {
00193 it_search->second->insert(ge);
00194 } else {
00195 ptr<ge_pi_set__type> deps = ge_pi_set__type::create();
00196 deps->insert(ge);
00197 (*mfdeps)[mf] = deps;
00198 }
00199 }
00200
00201 operands = ge->operands_output_get();
00202
00203 for(ge_operand_vector__type::iterator it_op = operands->begin(); it_op!=operands->end(); ++it_op) {
00204 if ( (*it_op)->kind_get()!=ge_operand::MEMORY ) {
00205 continue;
00206 }
00207
00208 ptr<pi_mem_factory> mf = (*it_op).dncast<ge_operand_mem>()->factory_get();
00209
00210 m2ge_pi_set__type::iterator it_search = mfdeps->find(mf);
00211
00212 if ( it_search!=mfdeps->end() ) {
00213 it_search->second->insert(ge);
00214 } else {
00215 ptr<ge_pi_set__type> deps = ge_pi_set__type::create();
00216 deps->insert(ge);
00217 (*mfdeps)[mf] = deps;
00218 }
00219 }
00220
00221 }
00222
00223
00224
00225
00226
00227 for(ge_pi_vector__type::iterator it = active_instrs->begin(); it!=active_instrs->end(); ++it) {
00228 ptr<ge_pi> ge = *it;
00229
00230 ptr<ge_operand_vector__type> operands = ge->operands_input_get();
00231
00232 for(ge_operand_vector__type::iterator it_op = operands->begin(); it_op!=operands->end(); ++it_op) {
00233 if ( (*it_op)->kind_get()!=ge_operand::MEMORY ) {
00234 continue;
00235 }
00236
00237 ptr<pi_mem_factory> mf = (*it_op).dncast<ge_operand_mem>()->factory_get();
00238
00239 m2ge_pi_set__type::iterator it_search = mfdeps->find(mf);
00240
00241 if ( it_search!=mfdeps->end() ) {
00242 ge->dependencies_get()->insert(it_search->second->begin(),it_search->second->end());
00243 }
00244 }
00245
00246 operands = ge->operands_output_get();
00247
00248 for(ge_operand_vector__type::iterator it_op = operands->begin(); it_op!=operands->end(); ++it_op) {
00249 if ( (*it_op)->kind_get()!=ge_operand::MEMORY ) {
00250 continue;
00251 }
00252
00253 ptr<pi_mem_factory> mf = (*it_op).dncast<ge_operand_mem>()->factory_get();
00254
00255 m2ge_pi_set__type::iterator it_search = mfdeps->find(mf);
00256
00257 if ( it_search!=mfdeps->end() ) {
00258 ge->dependencies_get()->insert(it_search->second->begin(),it_search->second->end());
00259 }
00260 }
00261
00262
00263 prev_instrs->push_back(ge);
00264 ge->bb_set(bb1);
00265 ge->dependencies_get()->insert(prev_fsp);
00266 active_lsp->dependencies_get()->insert(ge);
00267
00268 }
00269
00270 bblog << "Blocks joined (" << bb1->uid_get() << "<-" << bb2->uid_get() << ").\n" << eolog;
00271
00272 return bb1;
00273 }
00274
00275 ptr<func_data> bb_finder::get_result() {
00276 return data_get();
00277 }
00278
00279 end_package(workers);
00280 end_package(backend_v2);
00281 end_package(lestes);
00282