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/literal_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_imm> > reg2imm__type;
00022 typedef set<ulint> id_set__type;
00023
00024
00025
00026
00027 void literal_inliner::process() {
00028
00029 ptr<reg2imm__type> reg2imm = reg2imm__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::IMMEDIATE
00043 && ge->operands_output_get()->front()->kind_get()==ge_operand::REGISTER ) {
00044
00045 (*reg2imm)[ge->operands_output_get()->front().dncast<ge_operand_reg>()] = ge->operands_input_get()->front().dncast<ge_operand_imm>();
00046 } else if ( tm->versions_get() ) {
00047
00048
00049 ptr<ge_op_vector__type> operands = ge->operands_input_get();
00050 for(ge_op_vector__type::iterator it_op = operands->begin(); it_op!=operands->end();) {
00051 if ( (*it_op)->kind_get()!=ge_operand::REGISTER ) {
00052 ++it_op;
00053 continue;
00054 }
00055
00056 ptr<ge_operand_reg> reg = (*it_op).dncast<ge_operand_reg>();
00057
00058 reg2imm__type::iterator it_imm = reg2imm->find(reg);
00059
00060 if ( it_imm==reg2imm->end() ) {
00061 ++it_op;
00062 continue;
00063 }
00064
00065
00066 ptr<ge_operand_imm> imm = it_imm->second;
00067
00068
00069 *it_op = imm;
00070
00071
00072 if ( find_compatible_version(ge) ) {
00073
00074
00075 ge->dependencies_get()->erase(reg->origin_get());
00076
00077
00078 it_op = operands->begin();
00079 } else {
00080
00081 *it_op = reg;
00082 ++it_op;
00083 }
00084 }
00085 }
00086 }
00087 }
00088
00089
00090
00091
00092
00093
00094 bool literal_inliner::find_compatible_version(ptr<ge_pi> ge) {
00095 ptr<tm_instr_base> backup = ge->instruction_get();
00096 ptr<id_set__type> versions = backup->versions_get();
00097
00098 for(id_set__type::iterator it = versions->begin(); it!=versions->end();++it) {
00099 ge->instruction_set(tm_instr::instance(*it));
00100
00101 if ( ge->validate() ) {
00102
00103 return true;
00104 }
00105 }
00106
00107 ge->instruction_set(backup);
00108 return false;
00109 }
00110
00111
00112
00113
00114 ptr<func_data> literal_inliner::get_result() {
00115 return data_get();
00116 }
00117
00118
00119
00120 end_package(workers);
00121 end_package(backend_v2);
00122 end_package(lestes);
00123