00001 #include <lestes/backend_v2/intercode/ge.g.hh> 00002 #include <lestes/backend_v2/intercode/pi.g.hh> 00003 #include <lestes/backend_v2/intercode/pi_mem_factory.g.hh> 00004 #include <lestes/backend_v2/structs/func_data.g.hh> 00005 #include <lestes/backend_v2/workers/dead_code_eliminator.g.hh> 00006 #include <lestes/md/literals/literal_info_base.g.hh> 00007 #include <lestes/md/instructions/tm_instr.g.hh> 00008 #include <lestes/md/functions/function_parameter_accessor.g.hh> 00009 #include <lestes/lang/cplus/sem/ss_declaration.g.hh> 00010 #include <lestes/std/list.hh> 00011 #include <lestes/std/map.hh> 00012 #include <lestes/std/vector.hh> 00013 00014 package(lestes); 00015 package(backend_v2); 00016 package(workers); 00017 00018 using namespace ::lestes::backend_v2::structs; 00019 using namespace ::lestes::backend_v2::intercode; 00020 using namespace ::lestes::md::instructions; 00021 using namespace ::lestes::md::literals; 00022 using namespace ::lestes::md::functions; 00023 00024 typedef list< srp<ge_pi> > ge_pi_list__type; 00025 typedef vector< srp<ge_operand> > ge_op_vector__type; 00026 typedef set< srp<ge_operand> > ge_op_set__type; 00027 typedef set<ulint> id_set__type; 00028 00029 /*! 00030 \brief Eliminates a dead code. 00031 00032 It removes any pseudoinstruction whose output operands are not used by another pseudoinstruction. 00033 */ 00034 void dead_code_eliminator::process() { 00035 00036 ptr<ge_op_set__type> used_operands = ge_op_set__type::create(); 00037 00038 //Sweep used operands. 00039 ptr<ge_pi_list__type> body = data_get()->ge_body_get(); 00040 00041 for(ge_pi_list__type::iterator it = body->begin(); it!=body->end(); ++it) { 00042 ptr<ge_pi> ge = *it; 00043 00044 ptr<ge_op_vector__type> operands = ge->operands_input_get(); 00045 for(ge_op_vector__type::iterator it_op = operands->begin(); it_op!=operands->end(); ++it_op) { 00046 used_operands->insert(*it_op); 00047 } 00048 } 00049 00050 //Operand that represents return value from the function. 00051 ptr<pi_mem_factory> ret_val = function_parameter_accessor::instance(data_get()->function_decl_get())->get_ret_val(); 00052 00053 //Delete instructions that product unused operands. 00054 for(ge_pi_list__type::iterator it = body->begin(); it!=body->end();) { 00055 ptr<ge_pi> ge = *it; 00056 00057 if ( ge->kind_get()!=ge_pi::PI ) { 00058 ++it; 00059 continue; 00060 } 00061 00062 ptr<tm_instr_base> tm = ge->instruction_get(); 00063 00064 if ( !tm || tm->is_store() || tm->is_jump() || tm->is_system() ) { 00065 ++it; 00066 continue; 00067 } 00068 00069 bool b_delete = true; 00070 00071 ptr<ge_op_vector__type> operands = ge->operands_output_get(); 00072 for(ge_op_vector__type::iterator it_op = operands->begin(); it_op!=operands->end();++it_op) { 00073 ptr<ge_operand> op = *it_op; 00074 00075 if ( used_operands->find(op)!=used_operands->end() || 00076 (op->pi_source_get() 00077 && op->pi_source_get()->kind_get()!=pi_operand::PREG 00078 && op->pi_source_get()->kind_get()!=pi_operand::LIT 00079 && op->pi_source_get().dncast<pi_mem>()->factory_get()==ret_val) 00080 ) { 00081 /* 00082 This instruction isn't to be deleted because of an output operand is used by another instruction 00083 or an output operand is return value from the function. 00084 */ 00085 b_delete = false; 00086 break; 00087 } 00088 } 00089 00090 if ( b_delete ) { 00091 it = body->erase(it); 00092 } else { 00093 ++it; 00094 } 00095 00096 } 00097 } 00098 00099 /*! 00100 \brief Returns function body without any dead code. 00101 */ 00102 ptr<func_data> dead_code_eliminator::get_result() { 00103 return data_get(); 00104 } 00105 00106 00107 00108 end_package(workers); 00109 end_package(backend_v2); 00110 end_package(lestes); 00111
1.5.1-20070107