现在的位置: 首页 > 综合 > 正文

Studying note of GCC-3.4.6 source (175)

2013年09月28日 ⁄ 综合 ⁄ 共 3850字 ⁄ 字号 评论关闭

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.

 

抱歉!评论已关闭.