00001 #include <lestes/backend_v2/intercode/ge.g.hh>
00002 #include <lestes/backend_v2/structs/func_data.g.hh>
00003 #include <lestes/backend_v2/workers/memory_inliner.g.hh>
00004 #include <lestes/md/literals/literal_info_base.g.hh>
00005 #include <lestes/md/instructions/tm_instr.g.hh>
00006 #include <lestes/std/list.hh>
00007 #include <lestes/std/map.hh>
00008 #include <lestes/std/vector.hh>
00009
00010 package(lestes);
00011 package(backend_v2);
00012 package(workers);
00013
00014 using namespace ::lestes::backend_v2::structs;
00015 using namespace ::lestes::backend_v2::intercode;
00016 using namespace ::lestes::md::instructions;
00017 using namespace ::lestes::md::literals;
00018
00019 typedef list< srp<ge_pi> > ge_pi_list__type;
00020 typedef vector< srp<ge_operand> > ge_op_vector__type;
00021 typedef map< srp<ge_operand_reg>, srp<ge_operand_mem> > reg2mem__type;
00022 typedef set<ulint> id_set__type;
00023
00024
00025
00026
00027 void memory_inliner::process() {
00028
00029 ptr<reg2mem__type> reg2mem = reg2mem__type::create();
00030
00031 ptr<ge_pi_list__type> body = data_get()->ge_body_get();
00032
00033 for(ge_pi_list__type::iterator it = body->begin(); it!=body->end(); ++it) {
00034 ptr<ge_pi> ge = *it;
00035 ptr<tm_instr_base> tm = ge->instruction_get();
00036
00037 if ( !tm ) {
00038 continue;
00039 }
00040
00041 if ( tm->is_load()
00042 && ge->operands_input_get()->front()->kind_get()==ge_operand::MEMORY
00043 && ge->operands_output_get()->front()->kind_get()==ge_operand::REGISTER ) {
00044
00045 ptr<ge_operand_mem> mem = ge->operands_input_get()->front().dncast<ge_operand_mem>();
00046
00047
00048 if ( mem->factory_get() && mem->factory_get()->kind_get()!=pi_mem_factory::MF_PTR_DEREF ) {
00049 (*reg2mem)[ge->operands_output_get()->front().dncast<ge_operand_reg>()] = mem;
00050 }
00051 } else if ( tm->versions_get() ) {
00052
00053
00054 ptr<ge_op_vector__type> operands = ge->operands_input_get();
00055 for(ge_op_vector__type::iterator it_op = operands->begin(); it_op!=operands->end();) {
00056 if ( (*it_op)->kind_get()!=ge_operand::REGISTER ) {
00057 ++it_op;
00058 continue;
00059 }
00060
00061 ptr<ge_operand_reg> reg = (*it_op).dncast<ge_operand_reg>();
00062
00063 reg2mem__type::iterator it_mem = reg2mem->find(reg);
00064
00065 if ( it_mem==reg2mem->end() ) {
00066 ++it_op;
00067 continue;
00068 }
00069
00070
00071 ptr<ge_operand_mem> mem = it_mem->second;
00072
00073
00074 *it_op = mem;
00075
00076
00077 if ( find_compatible_version(ge) ) {
00078
00079
00080 ge->dependencies_get()->erase(reg->origin_get());
00081
00082
00083 it_op = operands->begin();
00084 } else {
00085
00086 *it_op = reg;
00087 ++it_op;
00088 }
00089 }
00090 }
00091 }
00092 }
00093
00094
00095
00096
00097
00098
00099 bool memory_inliner::find_compatible_version(ptr<ge_pi> ge) {
00100 ptr<tm_instr_base> backup = ge->instruction_get();
00101 ptr<id_set__type> versions = backup->versions_get();
00102
00103 for(id_set__type::iterator it = versions->begin(); it!=versions->end();++it) {
00104 ge->instruction_set(tm_instr::instance(*it));
00105
00106 if ( ge->validate() ) {
00107
00108 return true;
00109 }
00110 }
00111
00112 ge->instruction_set(backup);
00113 return false;
00114 }
00115
00116
00117
00118
00119 ptr<func_data> memory_inliner::get_result() {
00120 return data_get();
00121 }
00122
00123
00124
00125 end_package(workers);
00126 end_package(backend_v2);
00127 end_package(lestes);
00128