[PATCH] Improve discriminator assignment in for loops

Cary Coutant ccoutant@google.com
Fri Jul 24 22:03:00 GMT 2009


This patch fixes two small problems with discriminator assignment that
were hurting the accuracy of sample-based profiling.

First, in for loops, the increment portion of the loop is found at the
end of the basic block that contains the body, and the code was
checking for a line number match only at the beginning of the block.
Rather than loop through all the instructions of the block, it's
sufficient to check the last instruction in addition to the first --
if either matches the location of the predecessor block, we need to
assign a new discriminator to the "to" block.

Second, when gcc creates loop preheaders, it splits a basic block, and
in some cases all the interesting code ends up in the new block, but
that new block gets a 0 discriminator. This patch changes it so that
when a block is split, the new block gets the original block's
discriminator.

Tested on x86_64-linux-gnu. OK for trunk?

-cary


	* cfghooks.c (split_block): Copy discriminator to new block.
	* tree-cfg.c (assign_discriminator): Check location of last
	instruction in block as well as first.


Index: cfghooks.c
===================================================================
--- cfghooks.c	(revision 150061)
+++ cfghooks.c	(working copy)
@@ -437,6 +437,7 @@ split_block (basic_block bb, void *i)
   new_bb->count = bb->count;
   new_bb->frequency = bb->frequency;
   new_bb->loop_depth = bb->loop_depth;
+  new_bb->discriminator = bb->discriminator;

   if (dom_info_available_p (CDI_DOMINATORS))
     {
Index: tree-cfg.c
===================================================================
--- tree-cfg.c	(revision 150061)
+++ tree-cfg.c	(working copy)
@@ -756,13 +756,15 @@ same_line_p (location_t locus1, location
 static void
 assign_discriminator (location_t locus, basic_block bb)
 {
-  gimple to_stmt;
+  gimple first_in_to_bb, last_in_to_bb;

   if (locus == 0 || bb->discriminator != 0)
     return;

-  to_stmt = first_non_label_stmt (bb);
-  if (to_stmt && same_line_p (locus, gimple_location (to_stmt)))
+  first_in_to_bb = first_non_label_stmt (bb);
+  last_in_to_bb = last_stmt (bb);
+  if (first_in_to_bb && same_line_p (locus, gimple_location (first_in_to_bb))
+      || last_in_to_bb && same_line_p (locus, gimple_location (last_in_to_bb)))
     bb->discriminator = next_discriminator_for_locus (locus);
 }



More information about the Gcc-patches mailing list