stage3/constant_folding.cc
changeset 989 d4f8931d80cd
parent 988 3b12a6cf9fbd
child 990 4c235d65afdd
equal deleted inserted replaced
988:3b12a6cf9fbd 989:d4f8931d80cd
  1350    *         times (if it is instantiated multiple times in the same configuration, or once
  1350    *         times (if it is instantiated multiple times in the same configuration, or once
  1351    *         in several configurations). This should not be a problem because the constant
  1351    *         in several configurations). This should not be a problem because the constant
  1352    *         propagation algorithm is idem-potent (assuming the same constant values in the 
  1352    *         propagation algorithm is idem-potent (assuming the same constant values in the 
  1353    *         beginning), and we can use these multiple calls to the same POU to detect if
  1353    *         beginning), and we can use these multiple calls to the same POU to detect if
  1354    *         the situation mentioned in (1) is ocurring.
  1354    *         the situation mentioned in (1) is ocurring.
       
  1355    *         Note too that FBs may also include VAR_EXTERN CONSTANT variables, which must also
       
  1356    *         get their constant value from the corresponding global variable (declared in the 
       
  1357    *         configuration, program and FBs currently in scope). For this reason, when a FB
       
  1358    *         variable is instantiated inside a configuration, program or FB, we must recursively
       
  1359    *         visit the FB type declaration!
  1355    *       - After analysing all the configurations, we analyse all the other POUs that have
  1360    *       - After analysing all the configurations, we analyse all the other POUs that have
  1356    *         not yet been called (because they are not instantiated directly from within
  1361    *         not yet been called (because they are not instantiated directly from within
  1357    *         any configuration - e.g. functions, and most FBs!).
  1362    *         any configuration - e.g. functions, and most FBs!).
  1358    *       It is for this reason (3) why we have the two loops on the following code!
  1363    *       It is for this reason (3) why we have the two loops on the following code!
  1359    */
  1364    */
  1412 }
  1417 }
  1413 
  1418 
  1414 void *constant_propagation_c::handle_var_list_decl(symbol_c *var_list, symbol_c *type_decl, bool is_global_var) {
  1419 void *constant_propagation_c::handle_var_list_decl(symbol_c *var_list, symbol_c *type_decl, bool is_global_var) {
  1415   type_decl->accept(*this);  // Do constant folding of the initial value, and literals in subranges! (we will probably be doing this multiple times for the same init value, but this is safe as the cvalue is idem-potent)
  1420   type_decl->accept(*this);  // Do constant folding of the initial value, and literals in subranges! (we will probably be doing this multiple times for the same init value, but this is safe as the cvalue is idem-potent)
  1416   symbol_c *init_value = type_initial_value_c::get(type_decl);  
  1421   symbol_c *init_value = type_initial_value_c::get(type_decl);  
  1417   if (NULL == init_value)   {return NULL;} // this is probably a FB datatype, for which no initial value exists! Do nothing and return.
  1422 
       
  1423   /* There are two main possibilities here: either we are instantiating FBs, or some other variable.
       
  1424    *   (1) if it is a FB, we must recursively visit the FB type declaration, to let any VAR_EXTERN
       
  1425    *       variables there get their initial value from the current var_global_values[] map!!
       
  1426    *   (2) if it is a normal variable, we will store the initial value of that variable in the values[] map.
       
  1427    *        (and also store it in the var_global_values[] map is it is a VAR_GLOBAL variable!)
       
  1428    */
       
  1429    
       
  1430   /* Check whether we have situation (1) mentioned above! */ 
       
  1431   /* find the possible declaration (i.e. the datatype) of the possible FB being instantiated */
       
  1432   // NOTE: we do not use symbol->datatype so this const propagation algorithm will not depend on the fill/narrow datatypes algorithm!
       
  1433   function_block_type_symtable_t::iterator itr = function_block_type_symtable.end(); // assume not a FB!
       
  1434   symbol_c *type_symbol = spec_init_sperator_c::get_spec(type_decl);
       
  1435   token_c  *type_name  = dynamic_cast<token_c *>(type_symbol);
       
  1436   if (type_name != NULL)
       
  1437     itr = function_block_type_symtable.find(type_name);
       
  1438   if (itr != function_block_type_symtable.end()) {
       
  1439     // Handle the situation (1) mentioned above, i.e. handle the instantiation of FBs. 
       
  1440     // -------------------------------------------------------------------------------
       
  1441     //  Remmeber that in this case we will recursively visit the FB type declaration!!
       
  1442     function_block_declaration_c *fb_type = itr->second;
       
  1443     if (NULL == fb_type) ERROR; // syntax parsing should not allow this!
       
  1444     // TODO: detect whether we are already currently visiting this exact same FB declaration (possible with -p option), so we do not get into an infinite loop!!
       
  1445     fb_type->accept(*this);
       
  1446     return NULL;
       
  1447   }
       
  1448   
       
  1449   // Handle the situation (2) mentioned above, i.e. handle the instantiation of non-FB variables. 
       
  1450   // --------------------------------------------------------------------------------------------
       
  1451   if (NULL == init_value)   {return NULL;} // this is some datatype for which no initial value exists! Do nothing and return.
  1418   init_value->accept(*this); // necessary when handling default initial values, that were not constant folded in the call type_decl->accept(*this)
  1452   init_value->accept(*this); // necessary when handling default initial values, that were not constant folded in the call type_decl->accept(*this)
  1419   
  1453   
  1420   list_c *list = dynamic_cast<list_c *>(var_list);
  1454   list_c *list = dynamic_cast<list_c *>(var_list);
  1421   if (NULL == list) ERROR;
  1455   if (NULL == list) ERROR;
  1422   for (int i = 0; i < list->n; i++) {
  1456   for (int i = 0; i < list->n; i++) {
  1468 
  1502 
  1469 /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
  1503 /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
  1470 //SYM_REF2(fb_name_decl_c, fb_name_list, fb_spec_init)
  1504 //SYM_REF2(fb_name_decl_c, fb_name_list, fb_spec_init)
  1471 void *constant_propagation_c::visit(fb_name_decl_c *symbol) {
  1505 void *constant_propagation_c::visit(fb_name_decl_c *symbol) {
  1472   /* A FB has been instantiated inside the POU currently being analysed. We must therefore visit this FB's type declaration
  1506   /* A FB has been instantiated inside the POU currently being analysed. We must therefore visit this FB's type declaration
  1473    *  and give a chance of the VAR_EXTERNs in that FB to get the const values from the global variables currently in scope!
  1507    *  and give the VAR_EXTERNs in that FB a chance to get the const values from the global variables currently in scope!
  1474    */
  1508    */
  1475   /* find the declaration (i.e. the datatype) of the FB being instantiated */
  1509   // NOTE: The generic handle_var_list_decl() can handle the above situation, so we simply call it!
  1476   // NOTE: we do not use symbol->datatype so this const propagation algorithm will not depend on the fill/narrow datatypes algorithm!
  1510   // NOTE: The handle_var_list_decl() should not be needing the fb_name_list to do the above, so we call
  1477   symbol_c *fb_type_name = spec_init_sperator_c::get_spec(symbol->fb_spec_init);
  1511   //         it with NULL to highlight this fact!
  1478   function_block_type_symtable_t::iterator itr = function_block_type_symtable.find(fb_type_name);
  1512   return handle_var_list_decl(NULL, symbol->fb_spec_init);
  1479   if (itr == function_block_type_symtable.end()) ERROR; // syntax parsing should not allow this!
       
  1480   function_block_declaration_c *fb_type = itr->second;
       
  1481   if (NULL == fb_type) ERROR; // syntax parsing should not allow this!
       
  1482   // TODO: detect whether we are already currently visiting this exact same FB declaration (possible with -p option), so we do not get into an infinite loop!!
       
  1483   fb_type->accept(*this);
       
  1484   return NULL;
       
  1485 }
  1513 }
  1486 
  1514 
  1487 
  1515 
  1488 /* fb_name_list ',' fb_name */
  1516 /* fb_name_list ',' fb_name */
  1489 //SYM_LIST(fb_name_list_c)                                               // Not needed!
  1517 //SYM_LIST(fb_name_list_c)                                               // Not needed!