statement.h File Reference

Contains functions to create, manipulate and deallocate statements. More...

#include "defines.h"

Go to the source code of this file.

Functions

statementstatement_create (expression *exp, func_unit *funit, unsigned int ppline)
 Creates new statement structure.
void statement_size_elements (statement *stmt, func_unit *funit)
 Sizes all expressions for the given statement block.
void statement_db_write (statement *stmt, FILE *ofile, bool ids_issued)
 Writes specified statement to the specified output file.
void statement_db_write_tree (statement *stmt, FILE *ofile)
 Writes specified statement tree to the specified output file.
void statement_db_write_expr_tree (statement *stmt, FILE *ofile)
 Writes specified expression trees for given statement block to specified output file.
void statement_db_read (char **line, func_unit *curr_funit, int read_mode)
 Reads in statement line from specified string and stores statement in specified functional unit.
void statement_assign_expr_ids (statement *stmt, func_unit *funit)
 Assigns unique expression IDs to each expression in the given statement block.
bool statement_connect (statement *curr_stmt, statement *next_stmt, int conn_id)
 Connects statement sequence to next statement and sets stop bit.
int statement_get_last_line (statement *stmt)
 Calculates the last line of the specified statement tree.
void statement_find_rhs_sigs (statement *stmt, str_link **head, str_link **tail)
 Creates a list of all signals on the RHS of expressions in the given statement block.
statementstatement_find_statement (statement *curr, int id)
 Searches for statement with ID in the given statement block.
bool statement_contains_expr_calling_stmt (statement *curr, statement *stmt)
 Searches the specified statement block for expression that calls the given stmt.
void statement_dealloc_recursive (statement *stmt, bool rm_stmt_blks)
 Recursively deallocates specified statement tree.
void statement_dealloc (statement *stmt)
 Deallocates statement memory and associated expression tree from the heap.

Detailed Description

Contains functions to create, manipulate and deallocate statements.

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
5/1/2002

Function Documentation

void statement_assign_expr_ids ( statement stmt,
func_unit funit 
)

Assigns unique expression IDs to each expression in the given statement block.

Parameters:
stmt Pointer to statement block to traverse
funit Pointer to functional unit containing this statement block
Exceptions:
anonymous statement_assign_expr_ids statement_assign_expr_ids statement_assign_expr_ids expression_assign_expr_ids

Recursively traverses the entire statement block and assigns unique expression IDs for each expression tree that it finds.

References statement_s::exp, expression_assign_expr_ids(), statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_assign_expr_ids(), and statement_s::suppl.

Referenced by gen_item_assign_ids(), and statement_assign_expr_ids().

00561   { PROFILE(STATEMENT_ASSIGN_EXPR_IDS);
00562 
00563   if( stmt != NULL ) {
00564 
00565     /* Assign unique expression IDs */
00566     expression_assign_expr_ids( stmt->exp, funit );
00567 
00568     /* Traverse down the rest of the statement block */
00569     if( (stmt->next_true == stmt->next_false) && (stmt->suppl.part.stop_true == 0) ) {
00570       statement_assign_expr_ids( stmt->next_true, funit );
00571     } else {
00572       if( stmt->suppl.part.stop_false == 0 ) {
00573         statement_assign_expr_ids( stmt->next_false, funit );
00574       }
00575       if( stmt->suppl.part.stop_true == 0 ) {
00576         statement_assign_expr_ids( stmt->next_true, funit );
00577       }
00578     }
00579 
00580   }
00581 
00582   PROFILE_END;
00583 
00584 }

bool statement_connect ( statement curr_stmt,
statement next_stmt,
int  conn_id 
)

Connects statement sequence to next statement and sets stop bit.

Parameters:
curr_stmt Pointer to statement sequence to traverse.
next_stmt Pointer to statement to connect ends to.
conn_id Current connection identifier (used to eliminate infinite looping and connection overwrite)
Returns:
Returns TRUE if statement was connected to the given statement list; otherwise, returns FALSE.

Recursively traverses the specified stmt sequence. When it reaches a statement that has either next_true or next_false set to NULL, sets next_true and/or next_false of that statement to point to the next_stmt statement.

References statement_s::conn_id, statement_s::exp, EXPR_IS_CONTEXT_SWITCH, FALSE, statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_connect(), statement_s::suppl, and TRUE.

Referenced by db_statement_connect(), and statement_connect().

00612   { PROFILE(STATEMENT_CONNECT);
00613 
00614   bool retval = FALSE;  /* Return value for this function */
00615 
00616   assert( curr_stmt != NULL );
00617   assert( next_stmt != NULL );
00618 
00619   /* Specify that this statement has been traversed */
00620   curr_stmt->conn_id = conn_id;
00621 
00622   //display( "In statement_connect", curr_stmt, next_stmt, conn_id );
00623 
00624   /* If both paths go to the same destination, only parse one path */
00625   if( curr_stmt->next_true == curr_stmt->next_false ) {
00626     
00627     /* If the TRUE path is NULL, connect it to the new statement */
00628     if( curr_stmt->next_true == NULL ) {
00629       //display( "Setting next_true to next_stmt", curr_stmt, next_stmt, conn_id );
00630       curr_stmt->next_true  = next_stmt;
00631       /* If the current statement is a wait statement, don't connect next_false path */
00632       if( !EXPR_IS_CONTEXT_SWITCH( curr_stmt->exp ) ) {
00633         //display( "Setting next_false to next_stmt", curr_stmt, next_stmt, conn_id );
00634         curr_stmt->next_false = next_stmt;
00635       }
00636       if( curr_stmt->next_true->conn_id == conn_id ) {
00637         //display( "Setting stop_true and stop_false", curr_stmt, next_stmt, conn_id );
00638         curr_stmt->suppl.part.stop_true  = 1;
00639         curr_stmt->suppl.part.stop_false = 1;
00640       } else {
00641         curr_stmt->next_true->conn_id = conn_id;
00642       }
00643       retval = TRUE;
00644     /* If the TRUE path leads to a loop/merge, set the stop bit and stop traversing */
00645     } else if( curr_stmt->next_true->conn_id == conn_id ) {
00646       //display( "Setting stop_true and stop_false", curr_stmt, next_stmt, conn_id );
00647       curr_stmt->suppl.part.stop_true  = 1;
00648       curr_stmt->suppl.part.stop_false = 1;
00649     /* Continue to traverse the TRUE path if the next_stmt does not match this statement */
00650     } else if( curr_stmt->next_true != next_stmt ) {
00651       //display( "Traversing next_true path", curr_stmt, next_stmt, conn_id );
00652       retval |= statement_connect( curr_stmt->next_true, next_stmt, conn_id );
00653     }
00654 
00655   } else {
00656 
00657     /* Traverse FALSE path */
00658     if( curr_stmt->next_false == NULL ) {
00659       if( !EXPR_IS_CONTEXT_SWITCH( curr_stmt->exp ) ) {
00660         //display( "Setting next_false to next_stmt", curr_stmt, next_stmt, conn_id );
00661         curr_stmt->next_false = next_stmt;
00662         if( curr_stmt->next_false->conn_id == conn_id ) {
00663           //display( "Setting stop_false", curr_stmt, next_stmt, conn_id );
00664           curr_stmt->suppl.part.stop_false = 1;
00665         } else {
00666           curr_stmt->next_false->conn_id = conn_id; 
00667         }
00668         retval = TRUE;
00669       }
00670     /* If the FALSE path leads to a loop/merge, set the stop bit and stop traversing */
00671     } else if( curr_stmt->next_false->conn_id == conn_id ) {
00672       //display( "Setting stop_false", curr_stmt, next_stmt, conn_id );
00673       curr_stmt->suppl.part.stop_false = 1;
00674     /* Continue to traverse the FALSE path if the next statement does not match this statement */
00675     } else if( (curr_stmt->next_false != next_stmt) ) {
00676       //display( "Traversing next_false path", curr_stmt, next_stmt, conn_id );
00677       retval |= statement_connect( curr_stmt->next_false, next_stmt, conn_id );
00678     }
00679 
00680     /* Traverse TRUE path */
00681     if( curr_stmt->next_true == NULL ) {
00682       //display( "Setting next_true to next_stmt", curr_stmt, next_stmt, conn_id );
00683       curr_stmt->next_true = next_stmt;
00684       if( curr_stmt->next_true->conn_id == conn_id ) {
00685         //display( "Setting stop_true", curr_stmt, next_stmt, conn_id );
00686         curr_stmt->suppl.part.stop_true = 1;
00687       } else {
00688         curr_stmt->next_true->conn_id = conn_id;
00689       }
00690       retval = TRUE;
00691     /* If the TRUE path leads to a loop/merge, set the stop bit and stop traversing */
00692     } else if( curr_stmt->next_true->conn_id == conn_id ) {
00693       //display( "Setting stop_true", curr_stmt, next_stmt, conn_id );
00694       curr_stmt->suppl.part.stop_true = 1;
00695     /* Continue to traverse the TRUE path if the next statement does not match this statement */
00696     } else if( curr_stmt->next_true != next_stmt ) {
00697       //display( "Traversing next_true path", curr_stmt, next_stmt, conn_id );
00698       retval |= statement_connect( curr_stmt->next_true, next_stmt, conn_id );
00699     }
00700 
00701   }
00702 
00703   PROFILE_END;
00704 
00705   return( retval );
00706 
00707 }

bool statement_contains_expr_calling_stmt ( statement curr,
statement stmt 
)

Searches the specified statement block for expression that calls the given stmt.

Returns:
Returns TRUE if the given statement contains the given expression; otherwise, returns FALSE.
Parameters:
curr Pointer to current statement to traverse
stmt Pointer to statement to find in the associated expression tree

References statement_s::exp, expression_contains_expr_calling_stmt(), statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_contains_expr_calling_stmt(), and statement_s::suppl.

Referenced by funit_remove_stmt_blks_calling_stmt(), gen_item_remove_if_contains_expr_calling_stmt(), and statement_contains_expr_calling_stmt().

00876   { PROFILE(STATEMENT_CONTAINS_EXPR_CALLING_STMT);
00877 
00878   bool contains = (curr != NULL) &&
00879                   (expression_contains_expr_calling_stmt( curr->exp, stmt ) ||
00880                   ((curr->suppl.part.stop_true == 0) &&
00881                     statement_contains_expr_calling_stmt( curr->next_true, stmt )) ||
00882                   ((curr->next_false != curr->next_false) &&
00883                    (curr->suppl.part.stop_false == 0) &&
00884                     statement_contains_expr_calling_stmt( curr->next_false, stmt )));
00885 
00886   PROFILE_END;
00887 
00888   return( contains );
00889 
00890 }

statement* statement_create ( expression exp,
func_unit funit,
unsigned int  ppline 
)

Creates new statement structure.

Returns:
Returns pointer to the newly created statement.

Creates a new statement structure from heap memory and initializes it with the specified parameter information.

Parameters:
exp Pointer to root expression of expression tree for this statement
funit Pointer to functional unit that this statement exists in
ppline File line from the preprocessed file

References statement_s::all, statement_s::conn_id, statement_s::exp, statement_s::funit, statement_s::head, malloc_safe, statement_s::next_false, statement_s::next_true, expression_s::parent, statement_s::ppline, PROFILE, PROFILE_END, expr_stmt_u::stmt, and statement_s::suppl.

Referenced by db_create_statement(), fsm_arg_parse_state(), and statement_db_read().

00138   { PROFILE(STATEMENT_CREATE);
00139 
00140   statement* stmt;  /* Pointer to newly created statement */
00141 
00142   stmt                    = (statement*)malloc_safe( sizeof( statement ) );
00143   stmt->exp               = exp;
00144   stmt->exp->parent->stmt = stmt;
00145   stmt->next_true         = NULL;
00146   stmt->next_false        = NULL;
00147   stmt->head              = NULL;
00148   stmt->conn_id           = 0;
00149   stmt->suppl.all         = 0;
00150   stmt->funit             = funit;
00151   stmt->ppline            = ppline;
00152 
00153   PROFILE_END;
00154 
00155   return( stmt );
00156 
00157 }

void statement_db_read ( char **  line,
func_unit curr_funit,
int  read_mode 
)

Reads in statement line from specified string and stores statement in specified functional unit.

Parameters:
line Pointer to current line of file being read.
curr_funit Pointer to current module.
read_mode If set to REPORT, adds statement to head of list; otherwise, adds statement to tail.
Exceptions:
anonymous Throw Throw

Reads in the contents of the statement from the specified line, creates a statement structure to hold the contents.

References statement_s::all, exp_link_s::exp, func_unit_s::exp_head, exp_link_find(), FALSE, FATAL, func_unit_s::first_stmt, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, FUNIT_FUNCTION, FUNIT_NAMED_BLOCK, FUNIT_TASK, statement_s::head, statement_s::next_false, statement_s::next_true, statement_s::part, print_output(), PROFILE, PROFILE_END, READ_MODE_NO_MERGE, sim_add_thread(), statement_create(), statement_queue_add(), statement_queue_compare(), stmt_link_s::stmt, func_unit_s::stmt_head, stmt_link_add(), stmt_link_find(), func_unit_s::stmt_tail, statement_s::suppl, Throw, TRUE, and func_unit_s::type.

Referenced by db_read(), and funit_db_mod_merge().

00436   { PROFILE(STATEMENT_DB_READ);
00437 
00438   int          id;             /* ID of root expression that is associated with this statement */
00439   int          true_id;        /* ID of root expression that is associated with the next_true statement */
00440   int          false_id;       /* ID of root expression that is associated with the next_false statement */
00441   int          head_id;
00442   statement*   stmt;           /* Pointer to newly created statement */
00443   exp_link*    expl;           /* Pointer to found expression link */
00444   stmt_link*   stmtl;          /* Pointer to found statement link */
00445   int          chars_read;     /* Number of characters read from line */
00446   uint32       suppl;          /* Supplemental field value */
00447   unsigned int ppline;         /* Preprocessor file line */
00448   uint32       first_col;     /* First column */
00449 
00450   if( sscanf( *line, "%d %u %u %x %d %d %d%n", &id, &ppline, &first_col, &suppl, &true_id, &false_id, &head_id, &chars_read ) == 7 ) {
00451 
00452     *line = *line + chars_read;
00453 
00454     if( curr_funit == NULL ) {
00455 
00456       print_output( "Internal error:  statement in database written before its functional unit", FATAL, __FILE__, __LINE__ );
00457       Throw 0;
00458 
00459     } else {
00460 
00461       /* Find associated root expression */
00462       expl = exp_link_find( id, curr_funit->exp_head );
00463       assert( expl != NULL );
00464 
00465       stmt = statement_create( expl->exp, curr_funit, ppline );
00466       stmt->suppl.all = suppl;
00467 
00468       /*
00469        If this statement is a head statement and the current functional unit is a task, function or named block,
00470        set the curr_funit->first_stmt pointer to this statement.
00471       */
00472       if( (stmt->suppl.part.head == 1) &&
00473           ((curr_funit->type == FUNIT_TASK)        ||
00474            (curr_funit->type == FUNIT_ATASK)       ||
00475            (curr_funit->type == FUNIT_FUNCTION)    ||
00476            (curr_funit->type == FUNIT_AFUNCTION)   ||
00477            (curr_funit->type == FUNIT_NAMED_BLOCK) ||
00478            (curr_funit->type == FUNIT_ANAMED_BLOCK)) ) {
00479         curr_funit->first_stmt = stmt;
00480       }
00481 
00482       /* Find and link next_true */
00483       if( true_id == id ) {
00484         stmt->next_true = stmt;
00485       } else if( true_id != 0 ) {
00486         stmtl = stmt_link_find( true_id, curr_funit->stmt_head );
00487         if( stmtl == NULL ) {
00488           /* Add to statement loop queue */
00489           statement_queue_add( stmt, true_id, 0 );
00490         } else {
00491           stmt->next_true = stmtl->stmt;
00492         }
00493         /* Check against statement queue */
00494         statement_queue_compare( stmt );
00495       }
00496 
00497       /* Find and link next_false */
00498       if( false_id == id ) {
00499         stmt->next_false = stmt;
00500       } else if( false_id != 0 ) {
00501         stmtl = stmt_link_find( false_id, curr_funit->stmt_head );
00502         if( stmtl == NULL ) {
00503           statement_queue_add( stmt, false_id, 1 );
00504         } else {
00505           stmt->next_false = stmtl->stmt;
00506         }
00507         statement_queue_compare( stmt );
00508       }
00509 
00510       /* Find and link head */
00511       if( head_id == id ) {
00512         stmt->head = stmt;
00513       } else if( head_id != 0 ) {
00514         stmtl = stmt_link_find( head_id, curr_funit->stmt_head );
00515         if( stmtl == NULL ) {
00516           statement_queue_add( stmt, head_id, 2 );
00517         } else {
00518           stmt->head = stmtl->stmt;
00519         }
00520         statement_queue_compare( stmt );
00521       }
00522 
00523       /* Add the statement to the functional unit list */
00524       (void)stmt_link_add( stmt, TRUE, &(curr_funit->stmt_head), &(curr_funit->stmt_tail) );
00525 
00526       /*
00527        Possibly add statement to presimulation queue (if the current functional unit is a task
00528        or function, do not add this to the presimulation queue (this will be added when the expression
00529        is called.
00530       */
00531       if( (read_mode == READ_MODE_NO_MERGE) && (stmt->suppl.part.is_called == 0) ) {
00532         sim_time tmp_time = {0,0,0,FALSE};
00533         (void)sim_add_thread( NULL, stmt, curr_funit, &tmp_time );
00534       }
00535 
00536     }
00537 
00538   } else {
00539 
00540     print_output( "Unable to read statement value", FATAL, __FILE__, __LINE__ );
00541     Throw 0;
00542 
00543   }
00544 
00545   PROFILE_END;
00546 
00547 }

void statement_db_write ( statement stmt,
FILE *  ofile,
bool  ids_issued 
)

Writes specified statement to the specified output file.

Recursively writes the contents of the specified statement tree (and its associated expression trees to the specified output stream.

Parameters:
stmt Pointer to statement to write out value
ofile Pointer to output file to write statement line to
ids_issued Specifies that IDs were issued just prior to calling this function

References statement_s::all, expression_s::col, DB_TYPE_STATEMENT, statement_s::exp, expression_get_id(), statement_s::head, statement_s::next_false, statement_s::next_true, expression_s::part, statement_s::ppline, PROFILE, PROFILE_END, and statement_s::suppl.

Referenced by funit_db_write(), and statement_db_write_tree().

00332   { PROFILE(STATEMENT_DB_WRITE);
00333 
00334   assert( stmt != NULL );
00335 
00336   /* Write out contents of this statement last */
00337   fprintf( ofile, "%d %d %u %u %x %d %d %d",
00338     DB_TYPE_STATEMENT,
00339     expression_get_id( stmt->exp, ids_issued ),
00340     stmt->ppline,
00341     stmt->exp->col.part.first,
00342     (stmt->suppl.all & 0xff),
00343     ((stmt->next_true   == NULL) ? 0 : expression_get_id( stmt->next_true->exp, ids_issued )),
00344     ((stmt->next_false  == NULL) ? 0 : expression_get_id( stmt->next_false->exp, ids_issued )),
00345     ((stmt->head        == NULL) ? 0 : expression_get_id( stmt->head->exp, ids_issued ))
00346   );
00347 
00348   fprintf( ofile, "\n" );
00349 
00350   PROFILE_END;
00351 
00352 }

void statement_db_write_expr_tree ( statement stmt,
FILE *  ofile 
)

Writes specified expression trees for given statement block to specified output file.

Parameters:
stmt Pointer to specified statement tree to display
ofile Pointer to output file to write

Traverses the specified statement block, writing all expression trees to specified output file.

References statement_s::exp, expression_db_write_tree(), statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_db_write_expr_tree(), and statement_s::suppl.

Referenced by gen_item_db_write_expr_tree(), and statement_db_write_expr_tree().

00397   { PROFILE(STATEMENT_DB_WRITE_EXPR_TREE);
00398 
00399   if( stmt != NULL ) {
00400 
00401     /* Output ourselves first */
00402     expression_db_write_tree( stmt->exp, ofile );
00403 
00404     /* Traverse down the rest of the statement block */
00405     if( (stmt->next_true == stmt->next_false) && (stmt->suppl.part.stop_true == 0) ) {
00406       statement_db_write_expr_tree( stmt->next_true, ofile );
00407     } else {
00408       if( stmt->suppl.part.stop_false == 0 ) {
00409         statement_db_write_expr_tree( stmt->next_false, ofile );
00410       }
00411       if( stmt->suppl.part.stop_true == 0 ) {
00412         statement_db_write_expr_tree( stmt->next_true, ofile );
00413       }
00414     }
00415 
00416   }
00417 
00418   PROFILE_END;
00419 
00420 }

void statement_db_write_tree ( statement stmt,
FILE *  ofile 
)

Writes specified statement tree to the specified output file.

Parameters:
stmt Pointer to root of statement tree to output
ofile Pointer to output file to write statements to

Traverses specified statement tree, outputting all statements within that tree.

References statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_db_write(), statement_db_write_tree(), statement_s::suppl, and TRUE.

Referenced by gen_item_db_write(), and statement_db_write_tree().

00363   { PROFILE(STATEMENT_DB_WRITE_TREE);
00364 
00365   if( stmt != NULL ) {
00366 
00367     /* Traverse down the rest of the statement block */
00368     if( (stmt->next_true == stmt->next_false) && (stmt->suppl.part.stop_true == 0) ) {
00369       statement_db_write_tree( stmt->next_true, ofile );
00370     } else {
00371       if( stmt->suppl.part.stop_false == 0 ) {
00372         statement_db_write_tree( stmt->next_false, ofile );
00373       }
00374       if( stmt->suppl.part.stop_true == 0 ) {
00375         statement_db_write_tree( stmt->next_true, ofile );
00376       }
00377     }
00378 
00379     /* Output ourselves first */
00380     statement_db_write( stmt, ofile, TRUE );
00381 
00382   }
00383 
00384   PROFILE_END;
00385 
00386 }

void statement_dealloc ( statement stmt  ) 

Deallocates statement memory and associated expression tree from the heap.

Deallocates specified statement from heap memory. Does not remove attached expression (this is assumed to be cleaned up by the expression list removal function).

Parameters:
stmt Pointer to statement to deallocate

References free_safe, PROFILE, and PROFILE_END.

Referenced by db_create_statement(), fsm_var_cleanup(), and stmt_link_delete_list().

00951   { PROFILE(STATEMENT_DEALLOC);
00952 
00953   if( stmt != NULL ) {
00954  
00955     /* Finally, deallocate this statement */
00956     free_safe( stmt, sizeof( statement ) );
00957 
00958   }
00959 
00960   PROFILE_END;
00961 
00962 }

void statement_dealloc_recursive ( statement stmt,
bool  rm_stmt_blk 
)

Recursively deallocates specified statement tree.

Parameters:
stmt Pointer to head of statement tree to deallocate
rm_stmt_blk If set to TRUE, removes the statement block this statement points to (if any)

References db_remove_statement_from_current_funit(), expression_s::elem, ESUPPL_TYPE, ETYPE_FUNIT, statement_s::exp, EXP_OP_FORK, EXP_OP_NB_CALL, func_unit_s::first_stmt, free_safe, expression_s::funit, FUNIT_NO_SCORE, statement_s::next_false, statement_s::next_true, expression_s::op, statement_s::part, PROFILE, PROFILE_END, statement_dealloc_recursive(), stmt_blk_add_to_remove_list(), statement_s::suppl, expression_s::suppl, and func_unit_s::type.

Referenced by db_remove_statement(), gen_item_dealloc(), statement_dealloc_recursive(), and stmt_blk_remove().

00898   { PROFILE(STATEMENT_DEALLOC_RECURSIVE);
00899     
00900   if( stmt != NULL ) {
00901   
00902     assert( stmt->exp != NULL );
00903 
00904     /* If we are a named block or fork call statement, remove that statement block */
00905     if( (stmt->exp->op == EXP_OP_NB_CALL) || (stmt->exp->op == EXP_OP_FORK) ) {
00906 
00907       if( rm_stmt_blk && (ESUPPL_TYPE( stmt->exp->suppl ) == ETYPE_FUNIT) && (stmt->exp->elem.funit->type != FUNIT_NO_SCORE) ) {
00908         stmt_blk_add_to_remove_list( stmt->exp->elem.funit->first_stmt );
00909       }
00910 
00911     }
00912 
00913     /* Remove TRUE path */
00914     if( stmt->next_true == stmt->next_false ) {
00915 
00916       if( stmt->suppl.part.stop_true == 0 ) {
00917         statement_dealloc_recursive( stmt->next_true, rm_stmt_blk );
00918       }
00919 
00920     } else {
00921 
00922       if( stmt->suppl.part.stop_true == 0 ) {
00923         statement_dealloc_recursive( stmt->next_true, rm_stmt_blk );
00924       }
00925   
00926       /* Remove FALSE path */
00927       if( stmt->suppl.part.stop_false == 0 ) {
00928         statement_dealloc_recursive( stmt->next_false, rm_stmt_blk );
00929       }
00930 
00931     }
00932 
00933     /* Disconnect statement from current functional unit */
00934     db_remove_statement_from_current_funit( stmt );
00935 
00936     free_safe( stmt, sizeof( statement ) );
00937     
00938   }
00939 
00940   PROFILE_END;
00941   
00942 }

void statement_find_rhs_sigs ( statement stmt,
str_link **  head,
str_link **  tail 
)

Creates a list of all signals on the RHS of expressions in the given statement block.

Searches the specified statement block and returns a list of all signals on the right-hand-side of expressions.

Parameters:
stmt Pointer to current statement block to traverse
head Pointer to head of signal name list that will contain a list of all RHS signals
tail Pointer to tail of signal name list that will contain a list of all RHS signals

References expression_s::elem, statement_s::exp, EXP_OP_FORK, EXP_OP_NB_CALL, expression_find_rhs_sigs(), func_unit_s::first_stmt, expression_s::funit, statement_s::next_false, statement_s::next_true, expression_s::op, statement_s::part, PROFILE, PROFILE_END, statement_find_rhs_sigs(), and statement_s::suppl.

Referenced by db_create_sensitivity_list(), and statement_find_rhs_sigs().

00780   { PROFILE(STATEMENT_FIND_RHS_SIGS);
00781 
00782   if( stmt != NULL ) {
00783 
00784     if( (stmt->exp->op == EXP_OP_NB_CALL) || (stmt->exp->op == EXP_OP_FORK) ) {
00785 
00786       statement_find_rhs_sigs( stmt->exp->elem.funit->first_stmt, head, tail );
00787 
00788     } else {
00789 
00790       /* Find all RHS signals in this statement's expression tree */
00791       expression_find_rhs_sigs( stmt->exp, head, tail );
00792 
00793     }
00794 
00795     /* If both true and false paths lead to same statement, just traverse the true path */
00796     if( stmt->next_true == stmt->next_false ) {
00797 
00798       if( stmt->suppl.part.stop_true == 0 ) {
00799         statement_find_rhs_sigs( stmt->next_true, head, tail );
00800       }
00801 
00802     /* Otherwise, traverse both true and false paths */
00803     } else {
00804 
00805       if( stmt->suppl.part.stop_true == 0 ) {
00806         statement_find_rhs_sigs( stmt->next_true, head, tail );
00807       }
00808 
00809       if( stmt->suppl.part.stop_false == 0 ) {
00810         statement_find_rhs_sigs( stmt->next_false, head, tail );
00811       }
00812 
00813     }
00814 
00815   }
00816 
00817   PROFILE_END;
00818 
00819 }

statement* statement_find_statement ( statement curr,
int  id 
)

Searches for statement with ID in the given statement block.

Returns:
Returns a pointer to the found statement found within the given statement block. If the statement ID could not be found, returns NULL.

Recursively searches the given statement block for the expression that matches the given ID.

Parameters:
curr Pointer to current statement in statement block being evaluated
id Statement ID to find

References statement_s::exp, expression_s::id, statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_find_statement(), and statement_s::suppl.

Referenced by generate_remove_stmt_helper(), and statement_find_statement().

00831   { PROFILE(STATEMENT_FIND_STATEMENT);
00832 
00833   statement* found = NULL;  /* Pointer to found statement */
00834 
00835   if( curr != NULL ) {
00836 
00837     if( curr->exp->id == id ) {
00838 
00839       found = curr;
00840 
00841     } else {
00842 
00843       /* If both true and false paths lead to same item, just traverse the true path */
00844       if( curr->next_true == curr->next_false ) {
00845 
00846         if( curr->suppl.part.stop_true == 0 ) {
00847           found = statement_find_statement( curr->next_true, id );
00848         }
00849 
00850       /* Otherwise, traverse both true and false paths */
00851       } else if( (curr->suppl.part.stop_true == 0) &&
00852                  ((found = statement_find_statement( curr->next_true, id )) == NULL) ) {
00853 
00854         if( curr->suppl.part.stop_false == 0 ) {
00855           found = statement_find_statement( curr->next_false, id );
00856         }
00857 
00858       }
00859 
00860     }
00861 
00862   }
00863 
00864   PROFILE_END;
00865 
00866   return( found );
00867 
00868 }

int statement_get_last_line ( statement stmt  ) 

Calculates the last line of the specified statement tree.

Returns:
Returns the last line number in the given statement.
Parameters:
stmt Pointer to statement to get last line number for

References PROFILE, PROFILE_END, and statement_get_last_line_helper().

Referenced by race_handle_race_condition().

00762   { PROFILE(STATEMENT_GET_LAST_LINE);
00763 
00764   int retval = statement_get_last_line_helper( stmt, stmt );
00765 
00766   PROFILE_END;
00767 
00768   return( retval );
00769 
00770 }

void statement_size_elements ( statement stmt,
func_unit funit 
)

Sizes all expressions for the given statement block.

Parameters:
stmt Pointer to statement block to size elements for
funit Pointer to functional unit containing this statement block
Exceptions:
anonymous expression_resize statement_size_elements statement_size_elements statement_size_elements

Recursively sizes all elements for the given statement block.

References statement_s::exp, expression_resize(), FALSE, statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_size_elements(), statement_s::suppl, and TRUE.

Referenced by gen_item_resize_stmts_and_sigs(), and statement_size_elements().

00297   { PROFILE(STATEMENT_SIZE_ELEMENTS);
00298 
00299   if( stmt != NULL ) {
00300 
00301     /* Size the current statement */
00302     expression_resize( stmt->exp, funit, TRUE, FALSE );
00303 
00304     /* Iterate to the next statement */
00305     if( stmt->next_true == stmt->next_false ) {
00306       if( stmt->suppl.part.stop_true == 0 ) {
00307         statement_size_elements( stmt->next_true, funit );
00308       }
00309     } else {
00310       if( stmt->suppl.part.stop_false == 0 ) {
00311         statement_size_elements( stmt->next_false, funit );
00312       }
00313       if( stmt->suppl.part.stop_true == 0 ) {
00314         statement_size_elements( stmt->next_true, funit );
00315       }
00316     }
00317 
00318   }
00319 
00320   PROFILE_END;
00321 
00322 }

Generated on Sun Nov 21 00:55:41 2010 for Covered by  doxygen 1.6.3