GCC alwayszero function attribute

From CDOT Wiki
Revision as of 19:53, 23 October 2009 by Egmetcalfe (talk | contribs)
Jump to: navigation, search

Project Name

GCC alwayszero function attribute

Project Description

This project involves extending gcc to support an alwayszero function attribute (see Bug #517370).

Project Leader(s)

Ehren Metcalfe

Project Contributor(s)

Project Details

Relevant blog posts:

A Gimple Call Flags Mystery

Adding a new function attribute to GCC

Popping My GIMPLES (a plan)

Building GCC from trunk

Possible Bug

Recognizing the call flags

In tree-ssa-ccp.c:

/* Compute a default value for variable VAR and store it in the

  CONST_VAL array.  The following rules are used to get default
  values:
  1- Global and static variables that are declared constant are
     considered CONSTANT.
  2- Any other value is considered UNDEFINED.  This is useful when
     considering PHI nodes.  PHI arguments that are undefined do not
     change the constant value of the PHI node, which allows for more
     constants to be propagated.
  3- Variables defined by statements other than assignments and PHI
     nodes are considered VARYING.
  4- Initial values of variables that are not GIMPLE registers are
     considered VARYING.  */

static prop_value_t get_default_value (tree var) {

 tree sym = SSA_NAME_VAR (var);
 prop_value_t val = { UNINITIALIZED, NULL_TREE };
 gimple stmt;
 stmt = SSA_NAME_DEF_STMT (var);


 /* My debugging statment */
 if (is_gimple_call (stmt))
   fprintf(stderr, "Call flags: %d\n", gimple_call_flags (stmt));
 /* End My Debugging Statement */


 if (gimple_nop_p (stmt))
   {
     /* Variables defined by an empty statement are those used
  before being initialized.  If VAR is a local variable, we
  can assume initially that it is UNDEFINED, otherwise we must
  consider it VARYING.  */
     if (is_gimple_reg (sym) && TREE_CODE (sym) != PARM_DECL)
 val.lattice_val = UNDEFINED;
     else
 val.lattice_val = VARYING;
   }
 else if (is_gimple_assign (stmt)
    /* Value-returning GIMPLE_CALL statements assign to
       a variable, and are treated similarly to GIMPLE_ASSIGN.  */
    || (is_gimple_call (stmt)
        && gimple_call_lhs (stmt) != NULL_TREE)
    || gimple_code (stmt) == GIMPLE_PHI)
   {
     tree cst;
     if (gimple_assign_single_p (stmt)
   && DECL_P (gimple_assign_rhs1 (stmt))
   && (cst = get_symbol_constant_value (gimple_assign_rhs1 (stmt))))
 {
   val.lattice_val = CONSTANT;
   val.value = cst;
 }
     else
 /* Any other variable defined by an assignment or a PHI node
    is considered UNDEFINED.  */
 val.lattice_val = UNDEFINED;
   }
 else
   {
     /* Otherwise, VAR will never take on a constant value.  */
     val.lattice_val = VARYING;
   }
 return val;

}


In tree-optimize.c:

unsigned int execute_fixup_cfg (void) {

 basic_block bb;
 gimple_stmt_iterator gsi;
 int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
 if (cfun->eh)
   FOR_EACH_BB (bb)
     {
 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
   {
     gimple stmt = gsi_stmt (gsi);
     tree decl = is_gimple_call (stmt)
                 ? gimple_call_fndecl (stmt)
     : NULL;


     /* My debugging statement */
     if (decl)
       {
         fprintf(stderr, "Call flags from tree-optimize.c: %d\n",
             gimple_call_flags (stmt));
       }
     /* End my debugging statement */


     if (decl
   && gimple_call_flags (stmt) & (ECF_CONST
                | ECF_PURE 
                | ECF_LOOPING_CONST_OR_PURE))
       {
   if (gimple_in_ssa_p (cfun))
     {
       todo |= TODO_update_ssa | TODO_cleanup_cfg;
       mark_symbols_for_renaming (stmt);
             update_stmt (stmt);
     }
       }
     maybe_clean_eh_stmt (stmt);
   }
 if (gimple_purge_dead_eh_edges (bb))
         todo |= TODO_cleanup_cfg;
     }
 /* Dump a textual representation of the flowgraph.  */
 if (dump_file)
   gimple_dump_cfg (dump_file, dump_flags);
 return todo;

}