Studying note of GCC-3.4.6 source (175)

5.13.5.3.2.        Optimization based on cgraph

Back finish_file from cgraph_finalize_compilation_unit , at that time global variables and reachable static variables have assembler code output, and functions needed are also built into cgraph map, in which relationship of caller and callee is clear. Following, in cgraph_optimize , it will do optimization according to this cgraph map and output assembler code for the function.

 

1579 void

1580 cgraph_optimize (void)                                                                       in cgraphunit.c

1581 {

1582   if (!flag_unit_at_a_time )

1583     return ;

1584   timevar_push (TV_CGRAPHOPT);

1585   if (!quiet_flag )

1586     fprintf (stderr , "Performing intraprocedural optimizations/n");

1587

1588   cgraph_mark_local_functions ();

1589   if (cgraph_dump_file )

1590   {

1591     fprintf (cgraph_dump_file , "Marked ");

1592     dump_cgraph (cgraph_dump_file );

1593   }

1594

1595   cgraph_decide_inlining ();

1596   cgraph_global_info_ready = true;

1597   if (cgraph_dump_file )

1598   {

1599     fprintf (cgraph_dump_file , "Optimized ");

1600     dump_cgraph (cgraph_dump_file );

1601   }

1602   timevar_pop (TV_CGRAPHOPT);

1603

1604   /* Output everything.  */

1605   if (!quiet_flag )

1606     fprintf (stderr , "Assembling functions:/n");

1607   cgraph_expand_all_functions ();

1608   if (cgraph_dump_file )

1609   {

1610     fprintf (cgraph_dump_file , "/nFinal ");

1611     dump_cgraph (cgraph_dump_file );

1612   }

1613 }

 

See that it is a heavy optimization, which is done only the switch is on.

5.13.5.3.2.1.  Mark local function

First mark local function. A local function is one whose calls can occur only in the current compilation unit and all it's calls are explicit, so we can change its calling convention.

 

1556 static void

1557 cgraph_mark_local_functions (void)                                                     in cgraphunit.c

1558 {

1559   struct cgraph_node *node;

1560

1561   if (cgraph_dump_file )

1562     fprintf (cgraph_dump_file , "/nMarking local functions:");

1563

1564   /* Figure out functions we want to assemble.  * /

1565   for (node = cgraph_nodes ; node; node = node->next)

1566   {

1567     node->local.local = (!node->needed

1568                       && DECL_SAVED_TREE (node->decl)

1569                       && !TREE_PUBLIC (node->decl));

1570     if (cgraph_dump_file && node->local.local)

1571       fprintf (cgraph_dump_file , " %s", cgraph_node_name (node));

1572   }

1573   if (cgraph_dump_file )

1574     fprintf (cgraph_dump_file , "/n/n");

1575 }

 

The function makes the right hand side of the assignment expression at line 1567 is static function (TREE_PUBLIC is 0) that having address referred (thus node->needed is 0).

5.13.5.3.2.2.  Determine inlinability

Before we have analyzed functions declared as inline, now we need further decide if function inlinable in theory can be inlined really.

 

1233 static void

1234 cgraph_decide_inlining (void)                                                               in cgraphunit.c

1235 {

1236   struct cgraph_node *node;

1237   int nnodes;

1238   struct cgraph_node **order =

1239     xcalloc (cgraph_n_nodes , sizeof (struct cgraph_node *));

1240   struct cgraph_node **inlined =

1241     xcalloc (cgraph_n_nodes , sizeof (struct cgraph_node *));

1242   struct cgraph_node **inlined_callees =

1243     xcalloc (cgraph_n_nodes , sizeof (struct cgraph_node *));

1244   int ninlined;

1245   int ninlined_callees;

1246   int old_insns = 0;

1247   int i, y;

1248

1249   for (node = cgraph_nodes ; node; node = node->next)

1250     initial_insns += node->local.self_insns;

1251   overall_insns = initial_insns ;

1252

1253   nnodes = cgraph_postorder (order);

1254

1255   if (cgraph_dump_file )

1256     fprintf (cgraph_dump_file ,

1257            "/nDeciding on inlining.  Starting with %i insns./n",

1258             initial_insns);

1259

1260   for (node = cgraph_nodes ; node; node = node->next)

1261     node->aux = 0;

1262

1263   if (cgraph_dump_file )

1264     fprintf (cgraph_dump_file , "/nInlining always_inline functions:/n");

1265 #ifdef ENABLE_CHECKING

1266   for (node = cgraph_nodes ; node; node = node->next)

1267     if (node->aux || node->output)

1268       abort ();

1269 #endif

 

In previous, in cgraph_node, local.self_insns saves the estimated instruction number of the function (not confined to inlined function), so at line 1251, overall_insns and initial_insns get the total instruction number of this translation-unit.

 

你可能感兴趣的:(Studying note of GCC-3.4.6 source (175))