useless_code_eliminator.cc

Go to the documentation of this file.
00001 #include <lestes/backend_v2/structs/func_data.g.hh>
00002 #include <lestes/backend_v2/workers/useless_code_eliminator.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/intercode/visitor_pi_pi2id.g.hh>
00006 #include <lestes/md/instructions/tm_instr.g.hh>
00007 #include <lestes/md/registers/tm_register.g.hh>
00008 #include <lestes/lang/cplus/sem/ss_declaration.g.hh>
00009 
00010 #include <lestes/backend_v2/debug/debug.hh>
00011 
00012 package(lestes);
00013 package(backend_v2);
00014 package(workers);
00015 
00016 using namespace ::lestes::backend_v2::intercode;
00017 using namespace ::lestes::backend_v2::structs;
00018 using namespace ::lestes::md::instructions;
00019 using namespace ::lestes::md::registers;
00020 
00021 typedef list<srp<ge_pi> > ge_pi_list__type;
00022 typedef vector<srp<ge_operand> > ge_operand_vector__type;
00023 typedef map<ulint, srp<pi_mem_factory> > id2mf__type;
00024 typedef set<ulint> id_set__type;
00025 
00026 /*!
00027         \brief Eliminates a uselesss code.
00028 */
00029 void useless_code_eliminator::process() {
00030         
00031         ptr<ge_pi_list__type> body = data_get()->ge_body_get();
00032 
00033         ptr<id2mf__type> reg2mem = id2mf__type::create();
00034                 
00035         for(ge_pi_list__type::iterator it = body->begin(); it!=body->end(); ++it) {
00036                 
00037                 ptr<ge_pi> ge = *it;
00038                 
00039                 ptr<tm_instr_base> tm = ge->instruction_get();
00040                 
00041                 if ( ge->kind_get()==ge_pi::SP && ge.dncast<ge_sp>()->is_jmp_target_get() ) {
00042                         //Instruction invalidates reg2mem mapping.
00043                         reg2mem->clear();
00044                         continue;
00045                 }
00046                 
00047                 if ( !tm ) {
00048                         continue;
00049                 }
00050                 
00051                 if ( tm->is_system() ) {
00052                         //Instruction invalidates reg2mem mapping.
00053                         reg2mem->clear();
00054                 } else if ( tm->is_copy() ) {
00055                         ptr<ge_operand_reg> in = ge->operands_input_get()->front().dncast<ge_operand_reg>();
00056                         ptr<ge_operand_reg> out = ge->operands_output_get()->front().dncast<ge_operand_reg>();
00057                         ulint assigned_reg1 = (*in->assigned_registers_get())[ge];
00058                         ulint assigned_reg2 = (*out->assigned_registers_get())[ge];
00059                         
00060                         if ( assigned_reg1==assigned_reg2 ) {
00061                                  //Move eax,eax
00062                                  //Erase output.         
00063                                  ge->instruction_set(NULL);
00064                         }
00065                         
00066                         set_register_user(assigned_reg2,(*reg2mem)[assigned_reg1],reg2mem);
00067                 } else if ( tm->is_load() && ge->operands_input_get()->size()==1 ) {
00068                         //Instruction is load but it's not indirect load.
00069                         ptr<ge_operand> in = ge->operands_input_get()->front();
00070                         ptr<ge_operand> out = ge->operands_output_get()->front();
00071                         
00072                         if ( out->kind_get()==ge_operand::REGISTER ) {
00073                                 ptr<ge_operand_reg> reg = out.dncast<ge_operand_reg>();
00074                                 ulint assigned_reg = (*reg->assigned_registers_get())[ge];
00075                         
00076                                 if ( in->kind_get()==ge_operand::MEMORY ) {
00077                                         ptr<pi_mem_factory> mf = in.dncast<ge_operand_mem>()->factory_get();
00078                                 
00079                                         if ( mf && (*reg2mem)[assigned_reg]==mf ) {
00080                                                 //The register already contains the mem's value. No load needed.
00081                                                 ge->instruction_set(NULL);      
00082                                         } else {
00083                                                 //Set flag that the mem's value has been loaded to the reg.
00084                                                 set_register_user(assigned_reg,mf,reg2mem);
00085                                         }
00086                                 } else if ( in->kind_get()==ge_operand::IMMEDIATE ) {
00087                                         set_register_user(assigned_reg,NULL,reg2mem);
00088                                 } else lassert(false);
00089                         }
00090                         
00091                 } else if ( tm->is_store() && ge->operands_input_get()->size()==1 ) {
00092                         //Instruction is store but it's not indirect store.
00093                         ptr<ge_operand> in = ge->operands_input_get()->front();
00094                         ptr<ge_operand> out = ge->operands_output_get()->front();
00095                         
00096                         if ( out->kind_get()==ge_operand::MEMORY && in->kind_get()==ge_operand::REGISTER) {                     
00097                                 //Set flag that the the reg's value has been stored to the mem.
00098                                 set_register_user((*in.dncast<ge_operand_reg>()->assigned_registers_get())[ge],out.dncast<ge_operand_mem>()->factory_get(),reg2mem);
00099                         } else lassert(false);
00100                 } else {
00101                         ptr<ge_operand_vector__type> operands = ge->operands_output_get();
00102                         
00103                         for(ge_operand_vector__type::iterator it_operand = operands->begin(); it_operand!=operands->end(); ++it_operand) {
00104                                 if ( (*it_operand)->kind_get()!=ge_operand::REGISTER ) {
00105                                         continue;
00106                                 }
00107                                 
00108                                 ptr<ge_operand_reg> op = (*it_operand).dncast<ge_operand_reg>();
00109                                 ulint assigned_reg = (*op->assigned_registers_get())[ge];
00110                                 
00111                                 set_register_user(assigned_reg,NULL,reg2mem);
00112                         }
00113                 }
00114         }
00115 }
00116 
00117 /*!
00118         \brief Sets a memory place to a register from where a value has been loaded to the register.
00119         
00120         \param reg_id The register.
00121         \param user The memory.
00122         \param reg2mem A map that holds couples.
00123 */
00124 void useless_code_eliminator::set_register_user(ulint reg_id,ptr<pi_mem_factory> user,ptr<id2mf__type> reg2mem) {
00125         ptr<tm_register> reg = tm_register::instance(reg_id);
00126         ptr<id_set__type> aliases = reg->aliases_get();
00127         
00128         for(id_set__type::iterator it = aliases->begin(); it!=aliases->end(); ++it) {
00129                 (*reg2mem)[*it] = user;
00130         }
00131 }
00132 
00133 /*!
00134         \brief Returns data of a currently processed function without a useless code.
00135 */
00136 ptr<func_data> useless_code_eliminator::get_result() {
00137         return data_get();
00138 }
00139 
00140 
00141 
00142 end_package(workers);
00143 end_package(backend_v2);
00144 end_package(lestes);
00145 

Generated on Mon Feb 12 18:23:44 2007 for lestes by doxygen 1.5.1-20070107