dead_code_eliminator.cc

Go to the documentation of this file.
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 

Generated on Mon Feb 12 18:22:33 2007 for lestes by doxygen 1.5.1-20070107