lestes::backend_v2::workers::bb_finder Class Reference

Identifies basic block in a function body. More...

#include <bb_finder.g.hh>

Inheritance diagram for lestes::backend_v2::workers::bb_finder:

lestes::backend_v2::workers::worker_base lestes::std::object lestes::std::mem::keystone List of all members.

Public Member Functions

void process ()
 Groups pseudoinstructions of a function body to basic blocks.
ptr< ::lestes::backend_v2::structs::func_dataget_result ()
bool is_instruction_safe (ptr< ::lestes::backend_v2::intercode::ge_pi > ge)
ptr< basic_blockjoin_blocks (ptr< basic_block > bb1, ptr< basic_block > bb2)
 Merges two basic blocks into one.
virtual ptr< reflection_listreflection_get () const
 for purposes of dumping
virtual ptr< field_list_listfield_values_get () const
 for purposes of dumping

Static Public Member Functions

static ptr< bb_findercreate (ptr< ::lestes::backend_v2::structs::func_data > a__worker_base__data)
 First generated factory method for class bb_finder.

Protected Member Functions

 bb_finder (ptr< ::lestes::backend_v2::structs::func_data > a__worker_base__data)
 Generated constructor for class bb_finder.
virtual void gc_mark ()
 Marking routine for class bb_finder.

Static Private Attributes

static ptr< reflection_listreflection = reflection

Detailed Description

Identifies basic block in a function body.

Definition at line 50 of file bb_finder.g.hh.


Constructor & Destructor Documentation

lestes::backend_v2::workers::bb_finder::bb_finder ( ptr< ::lestes::backend_v2::structs::func_data a__worker_base__data  )  [protected]

Generated constructor for class bb_finder.

Generated constructor for class bb_finder.

Author:
lsg

Definition at line 37 of file bb_finder.g.cc.

Referenced by create().

00038         : worker_base(a__worker_base__data)
00039 {}


Member Function Documentation

void lestes::backend_v2::workers::bb_finder::process (  )  [virtual]

Groups pseudoinstructions of a function body to basic blocks.

Implements lestes::backend_v2::workers::worker_base.

Definition at line 29 of file bb_finder.cc.

References lestes::backend_v2::workers::basic_block::create(), lestes::backend_v2::workers::worker_base::data_get(), is_instruction_safe(), and join_blocks().

00029                         {
00030         
00031         ptr<ge_pi_list__type> body = data_get()->ge_body_get();
00032         ptr<bb_vector__type> bbs = data_get()->bbs_get();
00033         
00034         ptr<basic_block> prev_bb = NULL;
00035         ptr<basic_block> active_bb = NULL;
00036         
00037         bool b_active_is_safe = true;
00038         
00039         for(ge_pi_list__type::iterator it = body->begin(); it!=body->end(); ++it) {
00040                 ptr<ge_pi> ge = *it;
00041 
00042                 if (ge->kind_get()==ge_pi::SP ) {
00043                         ptr<ge_sp> sp = ge.dncast<ge_sp>();
00044 
00045                         if ( active_bb ) {
00046                                 active_bb->lsp_set(sp);
00047                                 
00048                                 if ( prev_bb ) {
00049                                         //Join blocks.
00050                                         active_bb = join_blocks(prev_bb,active_bb);
00051                                 } else {                                        
00052                                         bbs->push_back(active_bb);
00053                                 }
00054                                 
00055                                 if ( sp->is_jmp_target_get() || !b_active_is_safe ) {
00056                                         prev_bb = NULL;
00057                                 } else {
00058                                         prev_bb = active_bb;
00059                                 }
00060                                 
00061                                 active_bb = NULL;
00062                         }
00063                         
00064                         if ( !active_bb && ge!=body->back() ) {
00065                                 active_bb = basic_block::create();
00066                                 active_bb->fsp_set(sp);
00067                                 b_active_is_safe = true;
00068                         }
00069                         
00070                 } else {                
00071                         /*
00072                                 The following code line turns off block joining.
00073                                 
00074                                 Extended basic blocks bring a lots of problems especially 
00075                                 in context with memory operands and memory alliasing.
00076                                 
00077                                 Extended blocks don't produce better results of code scheduling
00078                                 so it is better to switch off block joining to extended blocks.
00079                         */
00080                         prev_bb = NULL; 
00081                         
00082                         ge->bb_set(active_bb);
00083                         active_bb->instructions_get()->push_back(ge);
00084                         
00085                         if ( !is_instruction_safe(ge) ) {
00086                                  //The block contains instruction that doesn't allow the block to be merged with a previous one.
00087                                  prev_bb = NULL;
00088                                  b_active_is_safe = false;
00089                         }
00090                 }
00091         }
00092 }

ptr< func_data > lestes::backend_v2::workers::bb_finder::get_result (  )  [virtual]

Implements lestes::backend_v2::workers::worker_base.

Definition at line 275 of file bb_finder.cc.

References lestes::backend_v2::workers::worker_base::data_get().

00275                                      {
00276         return data_get();
00277 }

bool lestes::backend_v2::workers::bb_finder::is_instruction_safe ( ptr< ::lestes::backend_v2::intercode::ge_pi ge  ) 

Referenced by process().

ptr< basic_block > lestes::backend_v2::workers::bb_finder::join_blocks ( ptr< basic_block bb1,
ptr< basic_block bb2 
)

Merges two basic blocks into one.

Parameters:
bb1 A first basic block.
bb2 A second basic block.
Returns:
A merged result.

Definition at line 144 of file bb_finder.cc.

References lestes::msg::eolog.

Referenced by process().

00144                                                                                   {
00145         ptr<ge_pi_vector__type> active_instrs = bb2->instructions_get();
00146         ptr<ge_pi_vector__type> prev_instrs = bb1->instructions_get();
00147                                         
00148         ptr<ge_sp> prev_fsp = bb1->fsp_get();
00149         ptr<ge_sp> active_lsp = bb2->lsp_get();//
00150         
00151         bb1->lsp_set(active_lsp);
00152         
00153         ptr<ge_sp> active_fsp = bb2->fsp_get();
00154                                         
00155         /*  
00156                 Split the bording sp into two sps. The first one will inherit input operands and dependencies
00157                 and the second one will inherits output ones.
00158         */
00159         
00160         ptr<ge_sp> new_sp = ge_sp::create(NULL,NULL);
00161         new_sp->operands_input_set(active_fsp->operands_input_get());
00162         new_sp->dependencies_set(active_fsp->dependencies_get());
00163         new_sp->bb_set(bb1);
00164         prev_instrs->push_back(new_sp);
00165                                         
00166         prev_instrs->push_back(active_fsp);
00167         active_fsp->dependencies_set(ge_pi_set__type::create());
00168         active_fsp->operands_input_set(ge_operand_vector__type::create());
00169         active_fsp->bb_set(bb1);
00170                                         
00171         /*
00172                 In the first block, find instructions that stores into memory.
00173         */
00174         ptr<m2ge_pi_set__type> mfdeps = m2ge_pi_set__type::create();
00175         
00176         for(ge_pi_vector__type::iterator it = prev_instrs->begin(); it!=prev_instrs->end(); ++it) {
00177                 ptr<ge_pi> ge = *it;
00178                 
00179                 active_lsp->dependencies_get()->insert(ge);
00180                 
00181                 ptr<ge_operand_vector__type> operands = ge->operands_input_get();
00182                 
00183                 for(ge_operand_vector__type::iterator it_op = operands->begin(); it_op!=operands->end(); ++it_op) {
00184                         if ( (*it_op)->kind_get()!=ge_operand::MEMORY ) {
00185                                 continue;
00186                         }
00187 
00188                         ptr<pi_mem_factory> mf = (*it_op).dncast<ge_operand_mem>()->factory_get();
00189                                 
00190                         m2ge_pi_set__type::iterator it_search = mfdeps->find(mf);
00191                                 
00192                         if ( it_search!=mfdeps->end() ) {
00193                                 it_search->second->insert(ge);
00194                         } else {
00195                                 ptr<ge_pi_set__type> deps = ge_pi_set__type::create();
00196                                 deps->insert(ge);
00197                                 (*mfdeps)[mf] = deps;
00198                         }       
00199                 }
00200                 
00201                 operands = ge->operands_output_get();
00202                 
00203                 for(ge_operand_vector__type::iterator it_op = operands->begin(); it_op!=operands->end(); ++it_op) {
00204                         if ( (*it_op)->kind_get()!=ge_operand::MEMORY ) {
00205                                 continue;
00206                         }
00207 
00208                         ptr<pi_mem_factory> mf = (*it_op).dncast<ge_operand_mem>()->factory_get();
00209                                 
00210                         m2ge_pi_set__type::iterator it_search = mfdeps->find(mf);
00211                                 
00212                         if ( it_search!=mfdeps->end() ) {
00213                                 it_search->second->insert(ge);
00214                         } else {
00215                                 ptr<ge_pi_set__type> deps = ge_pi_set__type::create();
00216                                 deps->insert(ge);
00217                                 (*mfdeps)[mf] = deps;
00218                         }       
00219                 }
00220                 
00221         }
00222         
00223         /*
00224                 In the second block, find instructions that uses memory operands and set dependecies on instructions from the
00225                 first block that produces these operands.
00226         */
00227         for(ge_pi_vector__type::iterator it = active_instrs->begin(); it!=active_instrs->end(); ++it) {
00228                 ptr<ge_pi> ge = *it;
00229                 
00230                 ptr<ge_operand_vector__type> operands = ge->operands_input_get();
00231                 
00232                 for(ge_operand_vector__type::iterator it_op = operands->begin(); it_op!=operands->end(); ++it_op) {
00233                         if ( (*it_op)->kind_get()!=ge_operand::MEMORY ) {
00234                                 continue;
00235                         }
00236 
00237                         ptr<pi_mem_factory> mf = (*it_op).dncast<ge_operand_mem>()->factory_get();
00238                                 
00239                         m2ge_pi_set__type::iterator it_search = mfdeps->find(mf);
00240                                 
00241                         if ( it_search!=mfdeps->end() ) {
00242                                 ge->dependencies_get()->insert(it_search->second->begin(),it_search->second->end());
00243                         }       
00244                 }
00245                 
00246                 operands = ge->operands_output_get();
00247                 
00248                 for(ge_operand_vector__type::iterator it_op = operands->begin(); it_op!=operands->end(); ++it_op) {
00249                         if ( (*it_op)->kind_get()!=ge_operand::MEMORY ) {
00250                                 continue;
00251                         }
00252 
00253                         ptr<pi_mem_factory> mf = (*it_op).dncast<ge_operand_mem>()->factory_get();
00254                                 
00255                         m2ge_pi_set__type::iterator it_search = mfdeps->find(mf);
00256                                 
00257                         if ( it_search!=mfdeps->end() ) {
00258                                 ge->dependencies_get()->insert(it_search->second->begin(),it_search->second->end());
00259                         }       
00260                 }
00261                 
00262                 //Finaly, insert instruction from the second block to the first one.
00263                 prev_instrs->push_back(ge);
00264                 ge->bb_set(bb1);
00265                 ge->dependencies_get()->insert(prev_fsp);
00266                 active_lsp->dependencies_get()->insert(ge);
00267                 
00268         }
00269         
00270         bblog << "Blocks joined (" << bb1->uid_get() << "<-" << bb2->uid_get() << ").\n" << eolog;
00271         
00272         return bb1;
00273 }

ptr< bb_finder > lestes::backend_v2::workers::bb_finder::create ( ptr< ::lestes::backend_v2::structs::func_data a__worker_base__data  )  [static]

First generated factory method for class bb_finder.

This factory method for class bb_finder takes values of all fields as arguments.

Author:
lsg

Definition at line 28 of file bb_finder.g.cc.

References bb_finder().

00029 {
00030         return ptr< bb_finder > ( new bb_finder(a__worker_base__data) );
00031 }

ptr< object::reflection_list > lestes::backend_v2::workers::bb_finder::reflection_get (  )  const [virtual]

for purposes of dumping

Reimplemented from lestes::backend_v2::workers::worker_base.

Definition at line 41 of file bb_finder.g.cc.

References lestes::std::list< T >::create(), reflection, and lestes::backend_v2::workers::worker_base::reflection_get().

00042 {
00043         if (!reflection) {
00044                 typedef class_reflection::field_metadata md;
00045                 typedef class_reflection::field_metadata_list mdlist;
00046                 ptr<mdlist> mdl = mdlist::create();
00047                 reflection = reflection_list::create( worker_base::reflection_get() );
00048                 reflection->push_back( class_reflection::create( "bb_finder", mdl ) );
00049         }
00050         return reflection;
00051 }

ptr< object::field_list_list > lestes::backend_v2::workers::bb_finder::field_values_get (  )  const [virtual]

for purposes of dumping

Reimplemented from lestes::backend_v2::workers::worker_base.

Definition at line 53 of file bb_finder.g.cc.

References lestes::backend_v2::workers::worker_base::field_values_get().

00054 {
00055         ptr < field_list_list > result = worker_base::field_values_get();
00056         return result;
00057 }

void lestes::backend_v2::workers::bb_finder::gc_mark ( void   )  [protected, virtual]

Marking routine for class bb_finder.

Marking routine is used for garbage collection.

Author:
lsg

Reimplemented from lestes::backend_v2::workers::worker_base.

Definition at line 64 of file bb_finder.g.cc.

References lestes::backend_v2::workers::worker_base::gc_mark().

00065 {
00066         worker_base::gc_mark();
00067 }


Member Data Documentation

ptr< object::reflection_list > lestes::backend_v2::workers::bb_finder::reflection = reflection [static, private]

Reimplemented from lestes::backend_v2::workers::worker_base.

Definition at line 81 of file bb_finder.g.hh.

Referenced by reflection_get().


The documentation for this class was generated from the following files:
Generated on Mon Feb 12 18:24:10 2007 for lestes by doxygen 1.5.1-20070107