00001 #include <lestes/backend_v2/structs/func_data.g.hh>
00002 #include <lestes/backend_v2/intercode/visitor_pi_pi2id.g.hh>
00003 #include <lestes/backend_v2/intercode/ge.g.hh>
00004 #include <lestes/backend_v2/intercode/pi_mem_factory.g.hh>
00005 #include <lestes/backend_v2/workers/liveness_analysis.g.hh>
00006 #include <lestes/backend_v2/debug/debug.hh>
00007
00008 package(lestes);
00009 package(backend_v2);
00010 package(workers);
00011
00012 using namespace ::lestes::backend_v2::intercode;
00013
00014 typedef map< srp< ::lestes::backend_v2::intercode::ge_pi >, srp< ::lestes::std::pair< srp<set< srp< ::lestes::backend_v2::intercode::ge_operand_reg > > >, srp<set< srp< ::lestes::backend_v2::intercode::ge_operand_reg > > > > > > ge_pi2inout__type;
00015 typedef list< srp<ge_pi> > ge_pi_list__type;
00016 typedef set< srp< ::lestes::backend_v2::intercode::ge_operand_reg > > ge_op_set__type;
00017 typedef ::lestes::std::pair< srp<ge_op_set__type>,srp<ge_op_set__type> > ge_op_set_pair__type;
00018 typedef vector< srp<ge_operand> > ge_op_vector__type;
00019 typedef vector< srp < ge_sp > > ge_sp_vector__type;
00020 typedef map<srp<ge_operand>,srp<liveness_range> > ge_op2liveness__type;
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 void liveness_analysis::process() {
00044
00045 ptr<visitor_pi_pi2id> pi2id = visitor_pi_pi2id::create();
00046
00047 ptr<ge_pi_list__type> body = data_get()->ge_body_get();
00048
00049
00050 for(ge_pi_list__type::iterator it = body->begin(); it!=body->end(); ++it) {
00051 ptr<ge_pi> ge = *it;
00052 (*inout)[ge] = ge_op_set_pair__type::create(ge_op_set__type::create(),ge_op_set__type::create());
00053 }
00054
00055 bool changed = true;
00056
00057 while(changed) {
00058
00059 changed = false;
00060
00061 ptr<ge_pi> succ;
00062
00063 for(ge_pi_list__type::reverse_iterator it = body->rbegin(); it!=body->rend(); ++it) {
00064 ptr<ge_pi> ge = *it;
00065
00066 if ( ge->kind_get()==ge_pi::SP ) {
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 continue;
00078 }
00079
00080 ptr<ge_op_vector__type> in_ops = ge->operands_input_get();
00081 ptr<ge_op_vector__type> out_ops = ge->operands_output_get();
00082
00083
00084 ptr<ge_op_set_pair__type> ge_io = (*inout)[ge];
00085 ptr<ge_op_set__type> old_in = ge_io->first;
00086 ptr<ge_op_set__type> old_out = ge_io->second;
00087
00088
00089 ptr<ge_op_set__type> in = ge_op_set__type::create();
00090 ptr<ge_op_set__type> out = ge_op_set__type::create();
00091
00092 ge_io->first = in;
00093 ge_io->second = out;
00094
00095
00096
00097
00098 for(ulint i=0; i<out_ops->size(); ++i) {
00099 ptr<ge_operand> op = (*out_ops)[i];
00100
00101 ptr<ge_operand_reg> reg = extract_reg_operand(op);
00102
00103 if ( !reg ) {
00104 continue;
00105 }
00106
00107 if ( old_out->find(reg)==old_out->end() ) {
00108 in->insert(reg);
00109 }
00110 }
00111
00112 for(ulint i=0; i<in_ops->size(); ++i) {
00113 ptr<ge_operand> op = (*in_ops)[i];
00114
00115 ptr<ge_operand_reg> reg = extract_reg_operand(op);
00116
00117 if ( !reg ) {
00118 continue;
00119 }
00120
00121 in->insert(reg);
00122 }
00123
00124
00125
00126
00127
00128
00129 visitor_pi_pi2id::kind_type pi_id = visitor_pi_pi2id::PI_ADD;
00130
00131 if ( ge->pi_source_get() ) {
00132 pi_id = (visitor_pi_pi2id::kind_type)ge->pi_source_get()->accept_visitor_pi_pi2ulint_gen_base(pi2id);
00133 }
00134
00135 switch ( pi_id ) {
00136 case visitor_pi_pi2id::PI_BA:
00137 case visitor_pi_pi2id::PI_LEAVE: {
00138
00139
00140
00141
00142 ptr<ge_sp_vector__type> targets = ge->jmp_targets_get();
00143
00144 if ( targets && targets->size()!=0 ) {
00145
00146 for(ulint i=0; i<targets->size(); ++i) {
00147 ptr<ge_op_set_pair__type> succ_io = (*inout)[(*targets)[i]];
00148 ptr<ge_op_set__type> succ_in = succ_io->first;
00149
00150 set_union(
00151 out->begin(),
00152 out->end(),
00153 succ_in->begin(),
00154 succ_in->end(),
00155 ::std::insert_iterator<ge_op_set__type>(*out,out->begin()));
00156 }
00157 }
00158
00159 } break;
00160
00161 case visitor_pi_pi2id::PI_BN: {
00162
00163
00164
00165
00166 if ( succ ) {
00167 ptr<ge_op_set_pair__type> succ_io = (*inout)[succ];
00168 ptr<ge_op_set__type> succ_in = succ_io->first;
00169
00170 set_union(
00171 out->begin(),
00172 out->end(),
00173 succ_in->begin(),
00174 succ_in->end(),
00175 ::std::insert_iterator<ge_op_set__type>(*out,out->begin()));
00176 }
00177
00178 } break;
00179
00180 default: {
00181
00182
00183
00184
00185 if ( succ ) {
00186 ptr<ge_op_set_pair__type> succ_io = (*inout)[succ];
00187 ptr<ge_op_set__type> succ_in = succ_io->first;
00188
00189 set_union(
00190 out->begin(),
00191 out->end(),
00192 succ_in->begin(),
00193 succ_in->end(),
00194 ::std::insert_iterator<ge_op_set__type>(*out,out->begin()));
00195 }
00196
00197
00198
00199
00200 ptr<ge_sp_vector__type> targets = ge->jmp_targets_get();
00201 if ( targets && targets->size()!=0 ) {
00202
00203 for(ulint i=0; i<targets->size(); ++i) {
00204 ptr<ge_op_set_pair__type> succ_io = (*inout)[(*targets)[i]];
00205 ptr<ge_op_set__type> succ_in = succ_io->first;
00206
00207 set_union(
00208 out->begin(),
00209 out->end(),
00210 succ_in->begin(),
00211 succ_in->end(),
00212 ::std::insert_iterator<ge_op_set__type>(*out,out->begin()));
00213 }
00214 }
00215
00216 } break;
00217
00218 }
00219
00220
00221 if ( in->size()!=old_in->size() || out->size()!=old_out->size() ) {
00222 changed = true;
00223 }
00224
00225 succ = ge;
00226
00227 }
00228 }
00229
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 ptr<ge_operand_reg> liveness_analysis::extract_reg_operand(ptr<ge_operand> op) {
00239 ptr<ge_operand_reg> reg = NULL;
00240
00241 if ( op->kind_get()==ge_operand::REGISTER ) {
00242 reg = op.dncast<ge_operand_reg>();
00243 }
00244
00245 return reg;
00246 }
00247
00248
00249
00250
00251 ptr<vector<srp<liveness_range> > > liveness_analysis::get_result() {
00252 ptr<vector<srp<liveness_range> > > output = vector<srp<liveness_range> >::create();
00253
00254
00255 ptr<ge_op2liveness__type> op2live = ge_op2liveness__type::create();
00256
00257 ptr<ge_pi_list__type> body = data_get()->ge_body_get();
00258
00259 for(ge_pi_list__type::iterator it = body->begin(); it!=body->end(); ++it) {
00260 ptr<ge_pi> ge = *it;
00261
00262 ptr<ge_op_set__type> ge_io = (*inout)[ge]->first;
00263
00264 for(ge_op_set__type::iterator it_op = ge_io->begin(); it_op!=ge_io->end(); ++it_op) {
00265 ptr<ge_operand_reg> reg = *it_op;
00266
00267 ptr<liveness_range> rng;
00268
00269 ge_op2liveness__type::iterator live_it = op2live->find(reg);
00270
00271 if ( live_it==op2live->end() ) {
00272 rng = liveness_range::create(reg,ge->schedule_pos_get(),ge->schedule_pos_get());
00273 output->push_back(rng);
00274 (*op2live)[reg] = rng;
00275 } else {
00276 rng = live_it->second;
00277 rng->end_set(ge->schedule_pos_get());
00278 }
00279
00280 rng->instructions_get()->push_back(ge);
00281 }
00282 }
00283
00284 return output;
00285 }
00286
00287
00288 end_package(workers);
00289 end_package(backend_v2);
00290 end_package(lestes);
00291