/* Routines to implement minimum-cost maximal flow algorithm used to smooth
   basic block and edge frequency counts.
   Copyright (C) 2008-2021 Free Software Foundation, Inc.
   Contributed by Paul Yuan (yingbo.com@gmail.com) and
                  Vinodha Ramasamy (vinodha@google.com).

This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* References:
   [1] "Feedback-directed Optimizations in GCC with Estimated Edge Profiles
        from Hardware Event Sampling", Vinodha Ramasamy, Paul Yuan, Dehao Chen,
        and Robert Hundt; GCC Summit 2008.
   [2] "Complementing Missing and Inaccurate Profiling Using a Minimum Cost
        Circulation Algorithm", Roy Levin, Ilan Newman and Gadi Haber;
        HiPEAC '08.

   Algorithm to smooth basic block and edge counts:
   1. create_fixup_graph: Create fixup graph by translating function CFG into
      a graph that satisfies MCF algorithm requirements.
   2. find_max_flow: Find maximal flow.
   3. compute_residual_flow: Form residual network.
   4. Repeat:
      cancel_negative_cycle: While G contains a negative cost cycle C, reverse
      the flow on the found cycle by the minimum residual capacity in that
      cycle.
   5. Form the minimal cost flow
      f(u,v) = rf(v, u).
   6. adjust_cfg_counts: Update initial edge weights with corrected weights.
      delta(u.v) = f(u,v) -f(v,u).
      w*(u,v) = w(u,v) + delta(u,v).  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "profile.h"
#include "dumpfile.h"

/* CAP_INFINITY: Constant to represent infinite capacity.  */
#define CAP_INFINITY INTTYPE_MAXIMUM (int64_t)

/* COST FUNCTION.  */
#define K_POS(b)        ((b))
#define K_NEG(b)        (50 * (b))
#define COST(k, w)      ((k) / mcf_ln ((w) + 2))
/* Limit the number of iterations for cancel_negative_cycles() to ensure
   reasonable compile time.  */
#define MAX_ITER(n, e)  10 + (1000000 / ((n) * (e)))
enum edge_type
{
  INVALID_EDGE,
  VERTEX_SPLIT_EDGE,	    /* Edge to represent vertex with w(e) = w(v).  */
  REDIRECT_EDGE,	    /* Edge after vertex transformation.  */
  REVERSE_EDGE,
  SOURCE_CONNECT_EDGE,	    /* Single edge connecting to single source.  */
  SINK_CONNECT_EDGE,	    /* Single edge connecting to single sink.  */
  BALANCE_EDGE,		    /* Edge connecting with source/sink: cp(e) = 0.  */
  REDIRECT_NORMALIZED_EDGE, /* Normalized edge for a redirect edge.  */
  REVERSE_NORMALIZED_EDGE   /* Normalized edge for a reverse edge.  */
};

/* Structure to represent an edge in the fixup graph.  */
struct fixup_edge_type
{
  int src;
  int dest;
  /* Flag denoting type of edge and attributes for the flow field.  */
  edge_type type;
  bool is_rflow_valid;
  /* Index to the normalization vertex added for this edge.  */
  int norm_vertex_index;
  /* Flow for this edge.  */
  gcov_type flow;
  /* Residual flow for this edge - used during negative cycle canceling.  */
  gcov_type rflow;
  gcov_type weight;
  gcov_type cost;
  gcov_type max_capacity;
};

typedef fixup_edge_type *fixup_edge_p;


/* Structure to represent a vertex in the fixup graph.  */
struct fixup_vertex_type
{
  vec<fixup_edge_p> succ_edges;
};

typedef fixup_vertex_type *fixup_vertex_p;

/* Fixup graph used in the MCF algorithm.  */
struct fixup_graph_type
{
  /* Current number of vertices for the graph.  */
  int num_vertices;
  /* Current number of edges for the graph.  */
  int num_edges;
  /* Index of new entry vertex.  */
  int new_entry_index;
  /* Index of new exit vertex.  */
  int new_exit_index;
  /* Fixup vertex list. Adjacency list for fixup graph.  */
  fixup_vertex_p vertex_list;
  /* Fixup edge list.  */
  fixup_edge_p edge_list;
};

struct queue_type
{
  int *queue;
  int head;
  int tail;
  int size;
};

/* Structure used in the maximal flow routines to find augmenting path.  */
struct augmenting_path_type
{
  /* Queue used to hold vertex indices.  */
  queue_type queue_list;
  /* Vector to hold chain of pred vertex indices in augmenting path.  */
  int *bb_pred;
  /* Vector that indicates if basic block i has been visited.  */
  int *is_visited;
};


/* Function definitions.  */

/* Dump routines to aid debugging.  */

/* Print basic block with index N for FIXUP_GRAPH in n' and n'' format.  */

static void
print_basic_block (FILE *file, fixup_graph_type *fixup_graph, int n)
{
  if (n == ENTRY_BLOCK)
    fputs ("ENTRY", file);
  else if (n == ENTRY_BLOCK + 1)
    fputs ("ENTRY''", file);
  else if (n == 2 * EXIT_BLOCK)
    fputs ("EXIT", file);
  else if (n == 2 * EXIT_BLOCK + 1)
    fputs ("EXIT''", file);
  else if (n == fixup_graph->new_exit_index)
    fputs ("NEW_EXIT", file);
  else if (n == fixup_graph->new_entry_index)
    fputs ("NEW_ENTRY", file);
  else
    {
      fprintf (file, "%d", n / 2);
      if (n % 2)
	fputs ("''", file);
      else
	fputs ("'", file);
    }
}


/* Print edge S->D for given fixup_graph with n' and n'' format.
   PARAMETERS:
   S is the index of the source vertex of the edge (input) and
   D is the index of the destination vertex of the edge (input) for the given
   fixup_graph (input).  */

static void
print_edge (FILE *file, fixup_graph_type *fixup_graph, int s, int d)
{
  print_basic_block (file, fixup_graph, s);
  fputs ("->", file);
  print_basic_block (file, fixup_graph, d);
}


/* Dump out the attributes of a given edge FEDGE in the fixup_graph to a
   file.  */
static void
dump_fixup_edge (FILE *file, fixup_graph_type *fixup_graph, fixup_edge_p fedge)
{
  if (!fedge)
    {
      fputs ("NULL fixup graph edge.\n", file);
      return;
    }

  print_edge (file, fixup_graph, fedge->src, fedge->dest);
  fputs (": ", file);

  if (fedge->type)
    {
      fprintf (file, "flow/capacity=%" PRId64 "/",
	       fedge->flow);
      if (fedge->max_capacity == CAP_INFINITY)
	fputs ("+oo,", file);
      else
	fprintf (file, "%" PRId64 ",", fedge->max_capacity);
    }

  if (fedge->is_rflow_valid)
    {
      if (fedge->rflow == CAP_INFINITY)
	fputs (" rflow=+oo.", file);
      else
	fprintf (file, " rflow=%" PRId64 ",", fedge->rflow);
    }

  fprintf (file, " cost=%" PRId64 ".", fedge->cost);

  fprintf (file, "\t(%d->%d)", fedge->src, fedge->dest);

  if (fedge->type)
    {
      switch (fedge->type)
	{
	case VERTEX_SPLIT_EDGE:
	  fputs (" @VERTEX_SPLIT_EDGE", file);
	  break;

	case REDIRECT_EDGE:
	  fputs (" @REDIRECT_EDGE", file);
	  break;

	case SOURCE_CONNECT_EDGE:
	  fputs (" @SOURCE_CONNECT_EDGE", file);
	  break;

	case SINK_CONNECT_EDGE:
	  fputs (" @SINK_CONNECT_EDGE", file);
	  break;

	case REVERSE_EDGE:
	  fputs (" @REVERSE_EDGE", file);
	  break;

	case BALANCE_EDGE:
	  fputs (" @BALANCE_EDGE", file);
	  break;

	case REDIRECT_NORMALIZED_EDGE:
	case REVERSE_NORMALIZED_EDGE:
	  fputs ("  @NORMALIZED_EDGE", file);
	  break;

	default:
	  fputs (" @INVALID_EDGE", file);
	  break;
	}
    }
  fputs ("\n", file);
}


/* Print out the edges and vertices of the given FIXUP_GRAPH, into the dump
   file. The input string MSG is printed out as a heading.  */

static void
dump_fixup_graph (FILE *file, fixup_graph_type *fixup_graph, const char *msg)
{
  int i, j;
  int fnum_vertices, fnum_edges;

  fixup_vertex_p fvertex_list, pfvertex;
  fixup_edge_p pfedge;

  gcc_assert (fixup_graph);
  fvertex_list = fixup_graph->vertex_list;
  fnum_vertices = fixup_graph->num_vertices;
  fnum_edges = fixup_graph->num_edges;

  fprintf (file, "\nDump fixup graph for %s(): %s.\n",
	   current_function_name (), msg);
  fprintf (file,
	   "There are %d vertices and %d edges. new_exit_index is %d.\n\n",
	   fnum_vertices, fnum_edges, fixup_graph->new_exit_index);

  for (i = 0; i < fnum_vertices; i++)
    {
      pfvertex = fvertex_list + i;
      fprintf (file, "vertex_list[%d]: %d succ fixup edges.\n",
	       i, pfvertex->succ_edges.length ());

      for (j = 0; pfvertex->succ_edges.iterate (j, &pfedge);
	   j++)
	{
	  /* Distinguish forward edges and backward edges in the residual flow
             network.  */
	  if (pfedge->type)
	    fputs ("(f) ", file);
	  else if (pfedge->is_rflow_valid)
	    fputs ("(b) ", file);
	  dump_fixup_edge (file, fixup_graph, pfedge);
	}
    }

  fputs ("\n", file);
}


/* Utility routines.  */
/* ln() implementation: approximate calculation. Returns ln of X.  */

static double
mcf_ln (double x)
{
#define E       2.71828
  int l = 1;
  double m = E;

  gcc_assert (x >= 0);

  while (m < x)
    {
      m *= E;
      l++;
    }

  return l;
}


/* sqrt() implementation: based on open source QUAKE3 code (magic sqrt
   implementation) by John Carmack.  Returns sqrt of X.  */

static double
mcf_sqrt (double x)
{
#define MAGIC_CONST1    0x1fbcf800
#define MAGIC_CONST2    0x5f3759df
  union {
    int intPart;
    float floatPart;
  } convertor, convertor2;

  gcc_assert (x >= 0);

  convertor.floatPart = x;
  convertor2.floatPart = x;
  convertor.intPart = MAGIC_CONST1 + (convertor.intPart >> 1);
  convertor2.intPart = MAGIC_CONST2 - (convertor2.intPart >> 1);

  return 0.5f * (convertor.floatPart + (x * convertor2.floatPart));
}


/* Common code shared between add_fixup_edge and add_rfixup_edge. Adds an edge
   (SRC->DEST) to the edge_list maintained in FIXUP_GRAPH with cost of the edge
   added set to COST.  */

static fixup_edge_p
add_edge (fixup_graph_type *fixup_graph, int src, int dest, gcov_type cost)
{
  fixup_vertex_p curr_vertex = fixup_graph->vertex_list + src;
  fixup_edge_p curr_edge = fixup_graph->edge_list + fixup_graph->num_edges;
  curr_edge->src = src;
  curr_edge->dest = dest;
  curr_edge->cost = cost;
  fixup_graph->num_edges++;
  if (dump_file)
    dump_fixup_edge (dump_file, fixup_graph, curr_edge);
  curr_vertex->succ_edges.safe_push (curr_edge);
  return curr_edge;
}


/* Add a fixup edge (src->dest) with attributes TYPE, WEIGHT, COST and
   MAX_CAPACITY to the edge_list in the fixup graph.  */

static void
add_fixup_edge (fixup_graph_type *fixup_graph, int src, int dest,
		edge_type type, gcov_type weight, gcov_type cost,
		gcov_type max_capacity)
{
  fixup_edge_p curr_edge = add_edge (fixup_graph, src, dest, cost);
  curr_edge->type = type;
  curr_edge->weight = weight;
  curr_edge->max_capacity = max_capacity;
}


/* Add a residual edge (SRC->DEST) with attributes RFLOW and COST
   to the fixup graph.  */

static void
add_rfixup_edge (fixup_graph_type *fixup_graph, int src, int dest,
		 gcov_type rflow, gcov_type cost)
{
  fixup_edge_p curr_edge = add_edge (fixup_graph, src, dest, cost);
  curr_edge->rflow = rflow;
  curr_edge->is_rflow_valid = true;
  /* This edge is not a valid edge - merely used to hold residual flow.  */
  curr_edge->type = INVALID_EDGE;
}


/* Return the pointer to fixup edge SRC->DEST or NULL if edge does not
   exist in the FIXUP_GRAPH.  */

static fixup_edge_p
find_fixup_edge (fixup_graph_type *fixup_graph, int src, int dest)
{
  int j;
  fixup_edge_p pfedge;
  fixup_vertex_p pfvertex;

  gcc_assert (src < fixup_graph->num_vertices);

  pfvertex = fixup_graph->vertex_list + src;

  for (j = 0; pfvertex->succ_edges.iterate (j, &pfedge);
       j++)
    if (pfedge->dest == dest)
      return pfedge;

  return NULL;
}


/* Cleanup routine to free structures in FIXUP_GRAPH.  */

static void
delete_fixup_graph (fixup_graph_type *fixup_graph)
{
  int i;
  int fnum_vertices = fixup_graph->num_vertices;
  fixup_vertex_p pfvertex = fixup_graph->vertex_list;

  for (i = 0; i < fnum_vertices; i++, pfvertex++)
    pfvertex->succ_edges.release ();

  free (fixup_graph->vertex_list);
  free (fixup_graph->edge_list);
}


/* Creates a fixup graph FIXUP_GRAPH from the function CFG.  */

static void
create_fixup_graph (fixup_graph_type *fixup_graph)
{
  double sqrt_avg_vertex_weight = 0;
  double total_vertex_weight = 0;
  double k_pos = 0;
  double k_neg = 0;
  /* Vector to hold D(v) = sum_out_edges(v) - sum_in_edges(v).  */
  gcov_type *diff_out_in = NULL;
  gcov_type supply_value = 1, demand_value = 0;
  gcov_type fcost = 0;
  int new_entry_index = 0, new_exit_index = 0;
  int i = 0, j = 0;
  int new_index = 0;
  basic_block bb;
  edge e;
  edge_iterator ei;
  fixup_edge_p pfedge, r_pfedge;
  fixup_edge_p fedge_list;
  int fnum_edges;

  /* Each basic_block will be split into 2 during vertex transformation.  */
  int fnum_vertices_after_transform =  2 * n_basic_blocks_for_fn (cfun);
  int fnum_edges_after_transform =
    n_edges_for_fn (cfun) + n_basic_blocks_for_fn (cfun);

  /* Count the new SOURCE and EXIT vertices to be added.  */
  int fmax_num_vertices =
    (fnum_vertices_after_transform + n_edges_for_fn (cfun)
     + n_basic_blocks_for_fn (cfun) + 2);

  /* In create_fixup_graph: Each basic block and edge can be split into 3
     edges. Number of balance edges = n_basic_blocks. So after
     create_fixup_graph:
     max_edges = 4 * n_basic_blocks + 3 * n_edges
     Accounting for residual flow edges
     max_edges = 2 * (4 * n_basic_blocks + 3 * n_edges)
     = 8 * n_basic_blocks + 6 * n_edges
     < 8 * n_basic_blocks + 8 * n_edges.  */
  int fmax_num_edges = 8 * (n_basic_blocks_for_fn (cfun) +
			    n_edges_for_fn (cfun));

  /* Initial num of vertices in the fixup graph.  */
  fixup_graph->num_vertices = n_basic_blocks_for_fn (cfun);

  /* Fixup graph vertex list.  */
  fixup_graph->vertex_list =
    (fixup_vertex_p) xcalloc (fmax_num_vertices, sizeof (fixup_vertex_type));

  /* Fixup graph edge list.  */
  fixup_graph->edge_list =
    (fixup_edge_p) xcalloc (fmax_num_edges, sizeof (fixup_edge_type));

  diff_out_in =
    (gcov_type *) xcalloc (1 + fnum_vertices_after_transform,
			   sizeof (gcov_type));

  /* Compute constants b, k_pos, k_neg used in the cost function calculation.
     b = sqrt(avg_vertex_weight(cfg)); k_pos = b; k_neg = 50b.  */
  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
    total_vertex_weight += bb_gcov_count (bb);

  sqrt_avg_vertex_weight = mcf_sqrt (total_vertex_weight /
				     n_basic_blocks_for_fn (cfun));

  k_pos = K_POS (sqrt_avg_vertex_weight);
  k_neg = K_NEG (sqrt_avg_vertex_weight);

  /* 1. Vertex Transformation: Split each vertex v into two vertices v' and v'',
     connected by an edge e from v' to v''. w(e) = w(v).  */

  if (dump_file)
    fprintf (dump_file, "\nVertex transformation:\n");

  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
  {
    /* v'->v'': index1->(index1+1).  */
    i = 2 * bb->index;
    fcost = (gcov_type) COST (k_pos, bb_gcov_count (bb));
    add_fixup_edge (fixup_graph, i, i + 1, VERTEX_SPLIT_EDGE, bb_gcov_count (bb),
                    fcost, CAP_INFINITY);
    fixup_graph->num_vertices++;

    FOR_EACH_EDGE (e, ei, bb->succs)
    {
      /* Edges with ignore attribute set should be treated like they don't
         exist.  */
      if (EDGE_INFO (e) && EDGE_INFO (e)->ignore)
        continue;
      j = 2 * e->dest->index;
      fcost = (gcov_type) COST (k_pos, edge_gcov_count (e));
      add_fixup_edge (fixup_graph, i + 1, j, REDIRECT_EDGE, edge_gcov_count (e),
		      fcost, CAP_INFINITY);
    }
  }

  /* After vertex transformation.  */
  gcc_assert (fixup_graph->num_vertices == fnum_vertices_after_transform);
  /* Redirect edges are not added for edges with ignore attribute.  */
  gcc_assert (fixup_graph->num_edges <= fnum_edges_after_transform);

  fnum_edges_after_transform = fixup_graph->num_edges;

  /* 2. Initialize D(v).  */
  for (i = 0; i < fnum_edges_after_transform; i++)
    {
      pfedge = fixup_graph->edge_list + i;
      diff_out_in[pfedge->src] += pfedge->weight;
      diff_out_in[pfedge->dest] -= pfedge->weight;
    }

  /* Entry block - vertex indices 0, 1; EXIT block - vertex indices 2, 3.  */
  for (i = 0; i <= 3; i++)
    diff_out_in[i] = 0;

  /* 3. Add reverse edges: needed to decrease counts during smoothing.  */
  if (dump_file)
    fprintf (dump_file, "\nReverse edges:\n");
  for (i = 0; i < fnum_edges_after_transform; i++)
    {
      pfedge = fixup_graph->edge_list + i;
      if ((pfedge->src == 0) || (pfedge->src == 2))
        continue;
      r_pfedge = find_fixup_edge (fixup_graph, pfedge->dest, pfedge->src);
      if (!r_pfedge && pfedge->weight)
	{
	  /* Skip adding reverse edges for edges with w(e) = 0, as its maximum
	     capacity is 0.  */
	  fcost = (gcov_type) COST (k_neg, pfedge->weight);
	  add_fixup_edge (fixup_graph, pfedge->dest, pfedge->src,
			  REVERSE_EDGE, 0, fcost, pfedge->weight);
	}
    }

  /* 4. Create single source and sink. Connect new source vertex s' to function
     entry block. Connect sink vertex t' to function exit.  */
  if (dump_file)
    fprintf (dump_file, "\ns'->S, T->t':\n");

  new_entry_index = fixup_graph->new_entry_index = fixup_graph->num_vertices;
  fixup_graph->num_vertices++;
  /* Set supply_value to 1 to avoid zero count function ENTRY.  */
  add_fixup_edge (fixup_graph, new_entry_index, ENTRY_BLOCK, SOURCE_CONNECT_EDGE,
		  1 /* supply_value */, 0, 1 /* supply_value */);

  /* Create new exit with EXIT_BLOCK as single pred.  */
  new_exit_index = fixup_graph->new_exit_index = fixup_graph->num_vertices;
  fixup_graph->num_vertices++;
  add_fixup_edge (fixup_graph, 2 * EXIT_BLOCK + 1, new_exit_index,
                  SINK_CONNECT_EDGE,
                  0 /* demand_value */, 0, 0 /* demand_value */);

  /* Connect vertices with unbalanced D(v) to source/sink.  */
  if (dump_file)
    fprintf (dump_file, "\nD(v) balance:\n");
  /* Skip vertices for ENTRY (0, 1) and EXIT (2,3) blocks, so start with i = 4.
     diff_out_in[v''] will be 0, so skip v'' vertices, hence i += 2.  */
  for (i = 4; i < new_entry_index; i += 2)
    {
      if (diff_out_in[i] > 0)
	{
	  add_fixup_edge (fixup_graph, i, new_exit_index, BALANCE_EDGE, 0, 0,
			  diff_out_in[i]);
	  demand_value += diff_out_in[i];
	}
      else if (diff_out_in[i] < 0)
	{
	  add_fixup_edge (fixup_graph, new_entry_index, i, BALANCE_EDGE, 0, 0,
			  -diff_out_in[i]);
	  supply_value -= diff_out_in[i];
	}
    }

  /* Set supply = demand.  */
  if (dump_file)
    {
      fprintf (dump_file, "\nAdjust supply and demand:\n");
      fprintf (dump_file, "supply_value=%" PRId64 "\n",
	       supply_value);
      fprintf (dump_file, "demand_value=%" PRId64 "\n",
	       demand_value);
    }

  if (demand_value > supply_value)
    {
      pfedge = find_fixup_edge (fixup_graph, new_entry_index, ENTRY_BLOCK);
      pfedge->max_capacity += (demand_value - supply_value);
    }
  else
    {
      pfedge = find_fixup_edge (fixup_graph, 2 * EXIT_BLOCK + 1, new_exit_index);
      pfedge->max_capacity += (supply_value - demand_value);
    }

  /* 6. Normalize edges: remove anti-parallel edges. Anti-parallel edges are
     created by the vertex transformation step from self-edges in the original
     CFG and by the reverse edges added earlier.  */
  if (dump_file)
    fprintf (dump_file, "\nNormalize edges:\n");

  fnum_edges = fixup_graph->num_edges;
  fedge_list = fixup_graph->edge_list;

  for (i = 0; i < fnum_edges; i++)
    {
      pfedge = fedge_list + i;
      r_pfedge = find_fixup_edge (fixup_graph, pfedge->dest, pfedge->src);
      if (((pfedge->type == VERTEX_SPLIT_EDGE)
	   || (pfedge->type == REDIRECT_EDGE)) && r_pfedge)
	{
	  new_index = fixup_graph->num_vertices;
	  fixup_graph->num_vertices++;

	  if (dump_file)
	    {
	      fprintf (dump_file, "\nAnti-parallel edge:\n");
	      dump_fixup_edge (dump_file, fixup_graph, pfedge);
	      dump_fixup_edge (dump_file, fixup_graph, r_pfedge);
	      fprintf (dump_file, "New vertex is %d.\n", new_index);
	      fprintf (dump_file, "------------------\n");
	    }

	  pfedge->cost /= 2;
	  pfedge->norm_vertex_index = new_index;
	  if (dump_file)
	    {
	      fprintf (dump_file, "After normalization:\n");
	      dump_fixup_edge (dump_file, fixup_graph, pfedge);
	    }

	  /* Add a new fixup edge: new_index->src.  */
	  add_fixup_edge (fixup_graph, new_index, pfedge->src,
			  REVERSE_NORMALIZED_EDGE, 0, r_pfedge->cost,
			  r_pfedge->max_capacity);
	  gcc_assert (fixup_graph->num_vertices <= fmax_num_vertices);

	  /* Edge: r_pfedge->src -> r_pfedge->dest
             ==> r_pfedge->src -> new_index.  */
	  r_pfedge->dest = new_index;
	  r_pfedge->type = REVERSE_NORMALIZED_EDGE;
	  r_pfedge->cost = pfedge->cost;
	  r_pfedge->max_capacity = pfedge->max_capacity;
	  if (dump_file)
	    dump_fixup_edge (dump_file, fixup_graph, r_pfedge);
	}
    }

  if (dump_file)
    dump_fixup_graph (dump_file, fixup_graph, "After create_fixup_graph()");

  /* Cleanup.  */
  free (diff_out_in);
}


/* Allocates space for the structures in AUGMENTING_PATH.  The space needed is
   proportional to the number of nodes in the graph, which is given by
   GRAPH_SIZE.  */

static void
init_augmenting_path (augmenting_path_type *augmenting_path, int graph_size)
{
  augmenting_path->queue_list.queue = (int *)
    xcalloc (graph_size + 2, sizeof (int));
  augmenting_path->queue_list.size = graph_size + 2;
  augmenting_path->bb_pred = (int *) xcalloc (graph_size, sizeof (int));
  augmenting_path->is_visited = (int *) xcalloc (graph_size, sizeof (int));
}

/* Free the structures in AUGMENTING_PATH.  */
static void
free_augmenting_path (augmenting_path_type *augmenting_path)
{
  free (augmenting_path->queue_list.queue);
  free (augmenting_path->bb_pred);
  free (augmenting_path->is_visited);
}


/* Queue routines. Assumes queue will never overflow.  */

static void
init_queue (queue_type *queue_list)
{
  gcc_assert (queue_list);
  queue_list->head = 0;
  queue_list->tail = 0;
}

/* Return true if QUEUE_LIST is empty.  */
static bool
is_empty (queue_type *queue_list)
{
  return (queue_list->head == queue_list->tail);
}

/* Insert element X into QUEUE_LIST.  */
static void
enqueue (queue_type *queue_list, int x)
{
  gcc_assert (queue_list->tail < queue_list->size);
  queue_list->queue[queue_list->tail] = x;
  (queue_list->tail)++;
}

/* Return the first element in QUEUE_LIST.  */
static int
dequeue (queue_type *queue_list)
{
  int x;
  gcc_assert (queue_list->head >= 0);
  x = queue_list->queue[queue_list->head];
  (queue_list->head)++;
  return x;
}


/* Finds a negative cycle in the residual network using
   the Bellman-Ford algorithm. The flow on the found cycle is reversed by the
   minimum residual capacity of that cycle. ENTRY and EXIT vertices are not
   considered.

Parameters:
   FIXUP_GRAPH - Residual graph  (input/output)
   The following are allocated/freed by the caller:
   PI - Vector to hold predecessors in path  (pi = pred index)
   D - D[I] holds minimum cost of path from i to sink
   CYCLE - Vector to hold the minimum cost cycle

Return:
   true if a negative cycle was found, false otherwise.  */

static bool
cancel_negative_cycle (fixup_graph_type *fixup_graph,
		       int *pi, gcov_type *d, int *cycle)
{
  int i, j, k;
  int fnum_vertices, fnum_edges;
  fixup_edge_p fedge_list, pfedge, r_pfedge;
  bool found_cycle = false;
  int cycle_start = 0, cycle_end = 0;
  gcov_type sum_cost = 0, cycle_flow = 0;
  int new_entry_index;
  bool propagated = false;

  gcc_assert (fixup_graph);
  fnum_vertices = fixup_graph->num_vertices;
  fnum_edges = fixup_graph->num_edges;
  fedge_list = fixup_graph->edge_list;
  new_entry_index = fixup_graph->new_entry_index;

  /* Initialize.  */
  /* Skip ENTRY.  */
  for (i = 1; i < fnum_vertices; i++)
    {
      d[i] = CAP_INFINITY;
      pi[i] = -1;
      cycle[i] = -1;
    }
  d[ENTRY_BLOCK] = 0;

  /* Relax.  */
  for (k = 1; k < fnum_vertices; k++)
  {
    propagated = false;
    for (i = 0; i < fnum_edges; i++)
      {
	pfedge = fedge_list + i;
	if (pfedge->src == new_entry_index)
	  continue;
	if (pfedge->is_rflow_valid && pfedge->rflow
            && d[pfedge->src] != CAP_INFINITY
	    && (d[pfedge->dest] > d[pfedge->src] + pfedge->cost))
	  {
	    d[pfedge->dest] = d[pfedge->src] + pfedge->cost;
	    pi[pfedge->dest] = pfedge->src;
            propagated = true;
	  }
      }
    if (!propagated)
      break;
  }

  if (!propagated)
  /* No negative cycles exist.  */
    return 0;

  /* Detect.  */
  for (i = 0; i < fnum_edges; i++)
    {
      pfedge = fedge_list + i;
      if (pfedge->src == new_entry_index)
	continue;
      if (pfedge->is_rflow_valid && pfedge->rflow
          && d[pfedge->src] != CAP_INFINITY
	  && (d[pfedge->dest] > d[pfedge->src] + pfedge->cost))
	{
	  found_cycle = true;
	  break;
	}
    }

  if (!found_cycle)
    return 0;

  /* Augment the cycle with the cycle's minimum residual capacity.  */
  found_cycle = false;
  cycle[0] = pfedge->dest;
  j = pfedge->dest;

  for (i = 1; i < fnum_vertices; i++)
    {
      j = pi[j];
      cycle[i] = j;
      for (k = 0; k < i; k++)
	{
	  if (cycle[k] == j)
	    {
	      /* cycle[k] -> ... -> cycle[i].  */
	      cycle_start = k;
	      cycle_end = i;
	      found_cycle = true;
	      break;
	    }
	}
      if (found_cycle)
	break;
    }

  gcc_assert (cycle[cycle_start] == cycle[cycle_end]);
  if (dump_file)
    fprintf (dump_file, "\nNegative cycle length is %d:\n",
	     cycle_end - cycle_start);

  sum_cost = 0;
  cycle_flow = CAP_INFINITY;
  for (k = cycle_start; k < cycle_end; k++)
    {
      pfedge = find_fixup_edge (fixup_graph, cycle[k + 1], cycle[k]);
      cycle_flow = MIN (cycle_flow, pfedge->rflow);
      sum_cost += pfedge->cost;
      if (dump_file)
	fprintf (dump_file, "%d ", cycle[k]);
    }

  if (dump_file)
    {
      fprintf (dump_file, "%d", cycle[k]);
      fprintf (dump_file,
	       ": (%" PRId64 ", %" PRId64
	       ")\n", sum_cost, cycle_flow);
      fprintf (dump_file,
	       "Augment cycle with %" PRId64 "\n",
	       cycle_flow);
    }

  for (k = cycle_start; k < cycle_end; k++)
    {
      pfedge = find_fixup_edge (fixup_graph, cycle[k + 1], cycle[k]);
      r_pfedge = find_fixup_edge (fixup_graph, cycle[k], cycle[k + 1]);
      pfedge->rflow -= cycle_flow;
      if (pfedge->type)
	pfedge->flow += cycle_flow;
      r_pfedge->rflow += cycle_flow;
      if (r_pfedge->type)
	r_pfedge->flow -= cycle_flow;
    }

  return true;
}


/* Computes the residual flow for FIXUP_GRAPH by setting the rflow field of
   the edges. ENTRY and EXIT vertices should not be considered.  */

static void
compute_residual_flow (fixup_graph_type *fixup_graph)
{
  int i;
  int fnum_edges;
  fixup_edge_p fedge_list, pfedge;

  gcc_assert (fixup_graph);

  if (dump_file)
    fputs ("\ncompute_residual_flow():\n", dump_file);

  fnum_edges = fixup_graph->num_edges;
  fedge_list = fixup_graph->edge_list;

  for (i = 0; i < fnum_edges; i++)
    {
      pfedge = fedge_list + i;
      pfedge->rflow = pfedge->max_capacity - pfedge->flow;
      pfedge->is_rflow_valid = true;
      add_rfixup_edge (fixup_graph, pfedge->dest, pfedge->src, pfedge->flow,
		       -pfedge->cost);
    }
}


/* Uses Edmonds-Karp algorithm - BFS to find augmenting path from SOURCE to
   SINK. The fields in the edge vector in the FIXUP_GRAPH are not modified by
   this routine. The vector bb_pred in the AUGMENTING_PATH structure is updated
   to reflect the path found.
   Returns: 0 if no augmenting path is found, 1 otherwise.  */

static int
find_augmenting_path (fixup_graph_type *fixup_graph,
		      augmenting_path_type *augmenting_path, int source,
		      int sink)
{
  int u = 0;
  int i;
  fixup_vertex_p fvertex_list, pfvertex;
  fixup_edge_p pfedge;
  int *bb_pred, *is_visited;
  queue_type *queue_list;

  gcc_assert (augmenting_path);
  bb_pred = augmenting_path->bb_pred;
  gcc_assert (bb_pred);
  is_visited = augmenting_path->is_visited;
  gcc_assert (is_visited);
  queue_list = &(augmenting_path->queue_list);

  gcc_assert (fixup_graph);

  fvertex_list = fixup_graph->vertex_list;

  for (u = 0; u < fixup_graph->num_vertices; u++)
    is_visited[u] = 0;

  init_queue (queue_list);
  enqueue (queue_list, source);
  bb_pred[source] = -1;

  while (!is_empty (queue_list))
    {
      u = dequeue (queue_list);
      is_visited[u] = 1;
      pfvertex = fvertex_list + u;
      for (i = 0; pfvertex->succ_edges.iterate (i, &pfedge);
	   i++)
	{
	  int dest = pfedge->dest;
	  if ((pfedge->rflow > 0) && (is_visited[dest] == 0))
	    {
	      enqueue (queue_list, dest);
	      bb_pred[dest] = u;
	      is_visited[dest] = 1;
	      if (dest == sink)
		return 1;
	    }
	}
    }

  return 0;
}


/* Routine to find the maximal flow:
   Algorithm:
   1. Initialize flow to 0
   2. Find an augmenting path form source to sink.
   3. Send flow equal to the path's residual capacity along the edges of this path.
   4. Repeat steps 2 and 3 until no new augmenting path is found.

Parameters:
SOURCE: index of source vertex (input)
SINK: index of sink vertex    (input)
FIXUP_GRAPH: adjacency matrix representing the graph. The flow of the edges will be
             set to have a valid maximal flow by this routine. (input)
Return: Maximum flow possible.  */

static gcov_type
find_max_flow (fixup_graph_type *fixup_graph, int source, int sink)
{
  int fnum_edges;
  augmenting_path_type augmenting_path;
  int *bb_pred;
  gcov_type max_flow = 0;
  int i, u;
  fixup_edge_p fedge_list, pfedge, r_pfedge;

  gcc_assert (fixup_graph);

  fnum_edges = fixup_graph->num_edges;
  fedge_list = fixup_graph->edge_list;

  /* Initialize flow to 0.  */
  for (i = 0; i < fnum_edges; i++)
    {
      pfedge = fedge_list + i;
      pfedge->flow = 0;
    }

  compute_residual_flow (fixup_graph);

  init_augmenting_path (&augmenting_path, fixup_graph->num_vertices);

  bb_pred = augmenting_path.bb_pred;
  while (find_augmenting_path (fixup_graph, &augmenting_path, source, sink))
    {
      /* Determine the amount by which we can increment the flow.  */
      gcov_type increment = CAP_INFINITY;
      for (u = sink; u != source; u = bb_pred[u])
	{
	  pfedge = find_fixup_edge (fixup_graph, bb_pred[u], u);
	  increment = MIN (increment, pfedge->rflow);
	}
      max_flow += increment;

      /* Now increment the flow. EXIT vertex index is 1.  */
      for (u = sink; u != source; u = bb_pred[u])
	{
	  pfedge = find_fixup_edge (fixup_graph, bb_pred[u], u);
	  r_pfedge = find_fixup_edge (fixup_graph, u, bb_pred[u]);
	  if (pfedge->type)
	    {
	      /* forward edge.  */
	      pfedge->flow += increment;
	      pfedge->rflow -= increment;
	      r_pfedge->rflow += increment;
	    }
	  else
	    {
	      /* backward edge.  */
	      gcc_assert (r_pfedge->type);
	      r_pfedge->rflow += increment;
	      r_pfedge->flow -= increment;
	      pfedge->rflow -= increment;
	    }
	}

      if (dump_file)
	{
	  fprintf (dump_file, "\nDump augmenting path:\n");
	  for (u = sink; u != source; u = bb_pred[u])
	    {
	      print_basic_block (dump_file, fixup_graph, u);
	      fprintf (dump_file, "<-");
	    }
	  fprintf (dump_file,
		   "ENTRY  (path_capacity=%" PRId64 ")\n",
		   increment);
	  fprintf (dump_file,
		   "Network flow is %" PRId64 ".\n",
		   max_flow);
	}
    }

  free_augmenting_path (&augmenting_path);
  if (dump_file)
    dump_fixup_graph (dump_file, fixup_graph, "After find_max_flow()");
  return max_flow;
}


/* Computes the corrected edge and basic block weights using FIXUP_GRAPH
   after applying the find_minimum_cost_flow() routine.  */

static void
adjust_cfg_counts (fixup_graph_type *fixup_graph)
{
  basic_block bb;
  edge e;
  edge_iterator ei;
  int i, j;
  fixup_edge_p pfedge, pfedge_n;

  gcc_assert (fixup_graph);

  if (dump_file)
    fprintf (dump_file, "\nadjust_cfg_counts():\n");

  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
		  EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
    {
      i = 2 * bb->index;

      /* Fixup BB.  */
      if (dump_file)
        fprintf (dump_file,
                 "BB%d: %" PRId64 "", bb->index, bb_gcov_count (bb));

      pfedge = find_fixup_edge (fixup_graph, i, i + 1);
      if (pfedge->flow)
        {
          bb_gcov_count (bb) += pfedge->flow;
	  if (dump_file)
	    {
	      fprintf (dump_file, " + %" PRId64 "(",
	               pfedge->flow);
	      print_edge (dump_file, fixup_graph, i, i + 1);
	      fprintf (dump_file, ")");
	    }
        }

      pfedge_n =
        find_fixup_edge (fixup_graph, i + 1, pfedge->norm_vertex_index);
      /* Deduct flow from normalized reverse edge.  */
      if (pfedge->norm_vertex_index && pfedge_n->flow)
        {
          bb_gcov_count (bb) -= pfedge_n->flow;
	  if (dump_file)
	    {
	      fprintf (dump_file, " - %" PRId64 "(",
		       pfedge_n->flow);
	      print_edge (dump_file, fixup_graph, i + 1,
			  pfedge->norm_vertex_index);
	      fprintf (dump_file, ")");
	    }
        }
      if (dump_file)
        fprintf (dump_file, " = %" PRId64 "\n", bb_gcov_count (bb));

      /* Fixup edge.  */
      FOR_EACH_EDGE (e, ei, bb->succs)
        {
          /* Treat edges with ignore attribute set as if they don't exist.  */
          if (EDGE_INFO (e) && EDGE_INFO (e)->ignore)
	    continue;

          j = 2 * e->dest->index;
          if (dump_file)
	    fprintf (dump_file, "%d->%d: %" PRId64 "",
		     bb->index, e->dest->index, edge_gcov_count (e));

          pfedge = find_fixup_edge (fixup_graph, i + 1, j);

          if (bb->index != e->dest->index)
	    {
	      /* Non-self edge.  */
	      if (pfedge->flow)
	        {
	          edge_gcov_count (e) += pfedge->flow;
	          if (dump_file)
		    {
		      fprintf (dump_file, " + %" PRId64 "(",
			       pfedge->flow);
		      print_edge (dump_file, fixup_graph, i + 1, j);
		      fprintf (dump_file, ")");
		    }
	        }

	      pfedge_n =
	        find_fixup_edge (fixup_graph, j, pfedge->norm_vertex_index);
	      /* Deduct flow from normalized reverse edge.  */
	      if (pfedge->norm_vertex_index && pfedge_n->flow)
	        {
	          edge_gcov_count (e) -= pfedge_n->flow;
	          if (dump_file)
		    {
		      fprintf (dump_file, " - %" PRId64 "(",
			       pfedge_n->flow);
		      print_edge (dump_file, fixup_graph, j,
			          pfedge->norm_vertex_index);
		      fprintf (dump_file, ")");
		    }
	        }
	    }
          else
	    {
	      /* Handle self edges. Self edge is split with a normalization
                 vertex. Here i=j.  */
	      pfedge = find_fixup_edge (fixup_graph, j, i + 1);
	      pfedge_n =
	        find_fixup_edge (fixup_graph, i + 1, pfedge->norm_vertex_index);
	      edge_gcov_count (e) += pfedge_n->flow;
	      bb_gcov_count (bb) += pfedge_n->flow;
	      if (dump_file)
	        {
	          fprintf (dump_file, "(self edge)");
	          fprintf (dump_file, " + %" PRId64 "(",
		           pfedge_n->flow);
	          print_edge (dump_file, fixup_graph, i + 1,
			      pfedge->norm_vertex_index);
	          fprintf (dump_file, ")");
	        }
	    }

          if (bb_gcov_count (bb))
	    e->probability = profile_probability::probability_in_gcov_type
			 (edge_gcov_count (e), bb_gcov_count (bb));
          if (dump_file)
	    {
	      fprintf (dump_file, " = %" PRId64 "\t",
		       edge_gcov_count (e));
	      e->probability.dump (dump_file);
	      fprintf (dump_file, "\n");
	    }
        }
    }

  bb_gcov_count (ENTRY_BLOCK_PTR_FOR_FN (cfun)) =
		     sum_edge_counts (ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs);
  bb_gcov_count (EXIT_BLOCK_PTR_FOR_FN (cfun)) =
		     sum_edge_counts (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds);

  /* Compute edge probabilities.  */
  FOR_ALL_BB_FN (bb, cfun)
    {
      if (bb_gcov_count (bb))
        {
          FOR_EACH_EDGE (e, ei, bb->succs)
            e->probability = profile_probability::probability_in_gcov_type
				(edge_gcov_count (e), bb_gcov_count (bb));
        }
    }

  if (dump_file)
    {
      fprintf (dump_file, "\nCheck %s() CFG flow conservation:\n",
	       current_function_name ());
      FOR_EACH_BB_FN (bb, cfun)
        {
          if ((bb_gcov_count (bb) != sum_edge_counts (bb->preds))
               || (bb_gcov_count (bb) != sum_edge_counts (bb->succs)))
            {
              fprintf (dump_file,
                       "BB%d(%" PRId64 ")  **INVALID**: ",
                       bb->index, bb_gcov_count (bb));
              fprintf (stderr,
                       "******** BB%d(%" PRId64
                       ")  **INVALID**: \n", bb->index, bb_gcov_count (bb));
              fprintf (dump_file, "in_edges=%" PRId64 " ",
                       sum_edge_counts (bb->preds));
              fprintf (dump_file, "out_edges=%" PRId64 "\n",
                       sum_edge_counts (bb->succs));
            }
         }
    }
}


/* Implements the negative cycle canceling algorithm to compute a minimum cost
   flow.
Algorithm:
1. Find maximal flow.
2. Form residual network
3. Repeat:
  While G contains a negative cost cycle C, reverse the flow on the found cycle
  by the minimum residual capacity in that cycle.
4. Form the minimal cost flow
  f(u,v) = rf(v, u)
Input:
  FIXUP_GRAPH - Initial fixup graph.
  The flow field is modified to represent the minimum cost flow.  */

static void
find_minimum_cost_flow (fixup_graph_type *fixup_graph)
{
  /* Holds the index of predecessor in path.  */
  int *pred;
  /* Used to hold the minimum cost cycle.  */
  int *cycle;
  /* Used to record the number of iterations of cancel_negative_cycle.  */
  int iteration;
  /* Vector d[i] holds the minimum cost of path from i to sink.  */
  gcov_type *d;
  int fnum_vertices;
  int new_exit_index;
  int new_entry_index;

  gcc_assert (fixup_graph);
  fnum_vertices = fixup_graph->num_vertices;
  new_exit_index = fixup_graph->new_exit_index;
  new_entry_index = fixup_graph->new_entry_index;

  find_max_flow (fixup_graph, new_entry_index, new_exit_index);

  /* Initialize the structures for find_negative_cycle().  */
  pred = (int *) xcalloc (fnum_vertices, sizeof (int));
  d = (gcov_type *) xcalloc (fnum_vertices, sizeof (gcov_type));
  cycle = (int *) xcalloc (fnum_vertices, sizeof (int));

  /* Repeatedly find and cancel negative cost cycles, until
     no more negative cycles exist. This also updates the flow field
     to represent the minimum cost flow so far.  */
  iteration = 0;
  while (cancel_negative_cycle (fixup_graph, pred, d, cycle))
    {
      iteration++;
      if (iteration > MAX_ITER (fixup_graph->num_vertices,
                                fixup_graph->num_edges))
        break;
    }

  if (dump_file)
    dump_fixup_graph (dump_file, fixup_graph,
		      "After find_minimum_cost_flow()");

  /* Cleanup structures.  */
  free (pred);
  free (d);
  free (cycle);
}


/* Compute the sum of the edge counts in TO_EDGES.  */

gcov_type
sum_edge_counts (vec<edge, va_gc> *to_edges)
{
  gcov_type sum = 0;
  edge e;
  edge_iterator ei;

  FOR_EACH_EDGE (e, ei, to_edges)
    {
      if (EDGE_INFO (e) && EDGE_INFO (e)->ignore)
        continue;
      sum += edge_gcov_count (e);
    }
  return sum;
}


/* Main routine. Smoothes the initial assigned basic block and edge counts using
   a minimum cost flow algorithm, to ensure that the flow consistency rule is
   obeyed: sum of outgoing edges = sum of incoming edges for each basic
   block.  */

void
mcf_smooth_cfg (void)
{
  fixup_graph_type fixup_graph;
  memset (&fixup_graph, 0, sizeof (fixup_graph));
  create_fixup_graph (&fixup_graph);
  find_minimum_cost_flow (&fixup_graph);
  adjust_cfg_counts (&fixup_graph);
  delete_fixup_graph (&fixup_graph);
}
