/* Exception handling semantics and decomposition for trees.
   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.

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 2, 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 COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "flags.h"
#include "function.h"
#include "except.h"
#include "tree-flow.h"
#include "tree-dump.h"
#include "tree-inline.h"
#include "tree-iterator.h"
#include "tree-pass.h"
#include "timevar.h"
#include "langhooks.h"
#include "ggc.h"
#include "toplev.h"


/* Nonzero if we are using EH to handle cleanups.  */
static int using_eh_for_cleanups_p = 0;

void
using_eh_for_cleanups (void)
{
  using_eh_for_cleanups_p = 1;
}

/* Misc functions used in this file.  */

/* Compare and hash for any structure which begins with a canonical
   pointer.  Assumes all pointers are interchangeable, which is sort
   of already assumed by gcc elsewhere IIRC.  */

static int
struct_ptr_eq (const void *a, const void *b)
{
  const void * const * x = (const void * const *) a;
  const void * const * y = (const void * const *) b;
  return *x == *y;
}

static hashval_t
struct_ptr_hash (const void *a)
{
  const void * const * x = (const void * const *) a;
  return (size_t)*x >> 4;
}


/* Remember and lookup EH region data for arbitrary statements.
   Really this means any statement that could_throw_p.  We could
   stuff this information into the stmt_ann data structure, but:

   (1) We absolutely rely on this information being kept until
   we get to rtl.  Once we're done with lowering here, if we lose
   the information there's no way to recover it!

   (2) There are many more statements that *cannot* throw as
   compared to those that can.  We should be saving some amount
   of space by only allocating memory for those that can throw.  */

static void
record_stmt_eh_region (struct eh_region *region, tree t)
{
  if (!region)
    return;

  add_stmt_to_eh_region (t, get_eh_region_number (region));
}

void
add_stmt_to_eh_region_fn (struct function *ifun, tree t, int num)
{
  struct throw_stmt_node *n;
  void **slot;

  gcc_assert (num >= 0);
  gcc_assert (TREE_CODE (t) != RESX_EXPR);

  n = GGC_NEW (struct throw_stmt_node);
  n->stmt = t;
  n->region_nr = num;

  if (!get_eh_throw_stmt_table (ifun))
    set_eh_throw_stmt_table (ifun, htab_create_ggc (31, struct_ptr_hash,
						    struct_ptr_eq,
						    ggc_free));

  slot = htab_find_slot (get_eh_throw_stmt_table (ifun), n, INSERT);
  gcc_assert (!*slot);
  *slot = n;
  /* ??? For the benefit of calls.c, converting all this to rtl,
     we need to record the call expression, not just the outer
     modify statement.  */
  if (TREE_CODE (t) == MODIFY_EXPR
      && (t = get_call_expr_in (t)))
    add_stmt_to_eh_region_fn (ifun, t, num);
}

void
add_stmt_to_eh_region (tree t, int num)
{
  add_stmt_to_eh_region_fn (cfun, t, num);
}

bool
remove_stmt_from_eh_region_fn (struct function *ifun, tree t)
{
  struct throw_stmt_node dummy;
  void **slot;

  if (!get_eh_throw_stmt_table (ifun))
    return false;

  dummy.stmt = t;
  slot = htab_find_slot (get_eh_throw_stmt_table (ifun), &dummy,
                        NO_INSERT);
  if (slot)
    {
      htab_clear_slot (get_eh_throw_stmt_table (ifun), slot);
      /* ??? For the benefit of calls.c, converting all this to rtl,
	 we need to record the call expression, not just the outer
	 modify statement.  */
      if (TREE_CODE (t) == MODIFY_EXPR
	  && (t = get_call_expr_in (t)))
	remove_stmt_from_eh_region_fn (ifun, t);
      return true;
    }
  else
    return false;
}

bool
remove_stmt_from_eh_region (tree t)
{
  return remove_stmt_from_eh_region_fn (cfun, t);
}

int
lookup_stmt_eh_region_fn (struct function *ifun, tree t)
{
  struct throw_stmt_node *p, n;

  if (!get_eh_throw_stmt_table (ifun))
    return -2;

  n.stmt = t;
  p = (struct throw_stmt_node *) htab_find (get_eh_throw_stmt_table (ifun),
                                            &n);

  return (p ? p->region_nr : -1);
}

int
lookup_stmt_eh_region (tree t)
{
  /* We can get called from initialized data when -fnon-call-exceptions
     is on; prevent crash.  */
  if (!cfun)
    return -1;
  return lookup_stmt_eh_region_fn (cfun, t);
}


/* First pass of EH node decomposition.  Build up a tree of TRY_FINALLY_EXPR
   nodes and LABEL_DECL nodes.  We will use this during the second phase to
   determine if a goto leaves the body of a TRY_FINALLY_EXPR node.  */

struct finally_tree_node
{
  tree child, parent;
};

/* Note that this table is *not* marked GTY.  It is short-lived.  */
static htab_t finally_tree;

static void
record_in_finally_tree (tree child, tree parent)
{
  struct finally_tree_node *n;
  void **slot;

  n = XNEW (struct finally_tree_node);
  n->child = child;
  n->parent = parent;

  slot = htab_find_slot (finally_tree, n, INSERT);
  gcc_assert (!*slot);
  *slot = n;
}

static void
collect_finally_tree (tree t, tree region)
{
 tailrecurse:
  switch (TREE_CODE (t))
    {
    case LABEL_EXPR:
      record_in_finally_tree (LABEL_EXPR_LABEL (t), region);
      break;

    case TRY_FINALLY_EXPR:
      record_in_finally_tree (t, region);
      collect_finally_tree (TREE_OPERAND (t, 0), t);
      t = TREE_OPERAND (t, 1);
      goto tailrecurse;

    case TRY_CATCH_EXPR:
      collect_finally_tree (TREE_OPERAND (t, 0), region);
      t = TREE_OPERAND (t, 1);
      goto tailrecurse;

    case CATCH_EXPR:
      t = CATCH_BODY (t);
      goto tailrecurse;

    case EH_FILTER_EXPR:
      t = EH_FILTER_FAILURE (t);
      goto tailrecurse;

    case STATEMENT_LIST:
      {
	tree_stmt_iterator i;
	for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
	  collect_finally_tree (tsi_stmt (i), region);
      }
      break;

    default:
      /* A type, a decl, or some kind of statement that we're not
	 interested in.  Don't walk them.  */
      break;
    }
}

/* Use the finally tree to determine if a jump from START to TARGET
   would leave the try_finally node that START lives in.  */

static bool
outside_finally_tree (tree start, tree target)
{
  struct finally_tree_node n, *p;

  do
    {
      n.child = start;
      p = (struct finally_tree_node *) htab_find (finally_tree, &n);
      if (!p)
	return true;
      start = p->parent;
    }
  while (start != target);

  return false;
}

/* Second pass of EH node decomposition.  Actually transform the TRY_FINALLY
   and TRY_CATCH nodes into a set of gotos, magic labels, and eh regions.
   The eh region creation is straight-forward, but frobbing all the gotos
   and such into shape isn't.  */

/* State of the world while lowering.  */

struct leh_state
{
  /* What's "current" while constructing the eh region tree.  These
     correspond to variables of the same name in cfun->eh, which we
     don't have easy access to.  */
  struct eh_region *cur_region;
  struct eh_region *prev_try;

  /* Processing of TRY_FINALLY requires a bit more state.  This is
     split out into a separate structure so that we don't have to
     copy so much when processing other nodes.  */
  struct leh_tf_state *tf;
};

struct leh_tf_state
{
  /* Pointer to the TRY_FINALLY node under discussion.  The try_finally_expr
     is the original TRY_FINALLY_EXPR.  We need to retain this so that
     outside_finally_tree can reliably reference the tree used in the
     collect_finally_tree data structures.  */
  tree try_finally_expr;
  tree *top_p;

  /* The state outside this try_finally node.  */
  struct leh_state *outer;

  /* The exception region created for it.  */
  struct eh_region *region;

  /* The GOTO_QUEUE is is an array of GOTO_EXPR and RETURN_EXPR statements
     that are seen to escape this TRY_FINALLY_EXPR node.  */
  struct goto_queue_node {
    tree stmt;
    tree repl_stmt;
    tree cont_stmt;
    int index;
  } *goto_queue;
  size_t goto_queue_size;
  size_t goto_queue_active;

  /* The set of unique labels seen as entries in the goto queue.  */
  VEC(tree,heap) *dest_array;

  /* A label to be added at the end of the completed transformed
     sequence.  It will be set if may_fallthru was true *at one time*,
     though subsequent transformations may have cleared that flag.  */
  tree fallthru_label;

  /* A label that has been registered with except.c to be the
     landing pad for this try block.  */
  tree eh_label;

  /* True if it is possible to fall out the bottom of the try block.
     Cleared if the fallthru is converted to a goto.  */
  bool may_fallthru;

  /* True if any entry in goto_queue is a RETURN_EXPR.  */
  bool may_return;

  /* True if the finally block can receive an exception edge.
     Cleared if the exception case is handled by code duplication.  */
  bool may_throw;
};

static void lower_eh_filter (struct leh_state *, tree *);
static void lower_eh_constructs_1 (struct leh_state *, tree *);

/* Comparison function for qsort/bsearch.  We're interested in
   searching goto queue elements for source statements.  */

static int
goto_queue_cmp (const void *x, const void *y)
{
  tree a = ((const struct goto_queue_node *)x)->stmt;
  tree b = ((const struct goto_queue_node *)y)->stmt;
  return (a == b ? 0 : a < b ? -1 : 1);
}

/* Search for STMT in the goto queue.  Return the replacement,
   or null if the statement isn't in the queue.  */

static tree
find_goto_replacement (struct leh_tf_state *tf, tree stmt)
{
  struct goto_queue_node tmp, *ret;
  tmp.stmt = stmt;
  ret = (struct goto_queue_node *)
     bsearch (&tmp, tf->goto_queue, tf->goto_queue_active,
		 sizeof (struct goto_queue_node), goto_queue_cmp);
  return (ret ? ret->repl_stmt : NULL);
}

/* A subroutine of replace_goto_queue_1.  Handles the sub-clauses of a
   lowered COND_EXPR.  If, by chance, the replacement is a simple goto,
   then we can just splat it in, otherwise we add the new stmts immediately
   after the COND_EXPR and redirect.  */

static void
replace_goto_queue_cond_clause (tree *tp, struct leh_tf_state *tf,
				tree_stmt_iterator *tsi)
{
  tree new, one, label;

  new = find_goto_replacement (tf, *tp);
  if (!new)
    return;

  one = expr_only (new);
  if (one && TREE_CODE (one) == GOTO_EXPR)
    {
      *tp = one;
      return;
    }

  label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
  *tp = build_and_jump (&LABEL_EXPR_LABEL (label));

  tsi_link_after (tsi, label, TSI_CONTINUE_LINKING);
  tsi_link_after (tsi, new, TSI_CONTINUE_LINKING);
}

/* The real work of replace_goto_queue.  Returns with TSI updated to
   point to the next statement.  */

static void replace_goto_queue_stmt_list (tree, struct leh_tf_state *);

static void
replace_goto_queue_1 (tree t, struct leh_tf_state *tf, tree_stmt_iterator *tsi)
{
  switch (TREE_CODE (t))
    {
    case GOTO_EXPR:
    case RETURN_EXPR:
      t = find_goto_replacement (tf, t);
      if (t)
	{
	  tsi_link_before (tsi, t, TSI_SAME_STMT);
	  tsi_delink (tsi);
	  return;
	}
      break;

    case COND_EXPR:
      replace_goto_queue_cond_clause (&COND_EXPR_THEN (t), tf, tsi);
      replace_goto_queue_cond_clause (&COND_EXPR_ELSE (t), tf, tsi);
      break;

    case TRY_FINALLY_EXPR:
    case TRY_CATCH_EXPR:
      replace_goto_queue_stmt_list (TREE_OPERAND (t, 0), tf);
      replace_goto_queue_stmt_list (TREE_OPERAND (t, 1), tf);
      break;
    case CATCH_EXPR:
      replace_goto_queue_stmt_list (CATCH_BODY (t), tf);
      break;
    case EH_FILTER_EXPR:
      replace_goto_queue_stmt_list (EH_FILTER_FAILURE (t), tf);
      break;

    case STATEMENT_LIST:
      gcc_unreachable ();

    default:
      /* These won't have gotos in them.  */
      break;
    }

  tsi_next (tsi);
}

/* A subroutine of replace_goto_queue.  Handles STATEMENT_LISTs.  */

static void
replace_goto_queue_stmt_list (tree t, struct leh_tf_state *tf)
{
  tree_stmt_iterator i = tsi_start (t);
  while (!tsi_end_p (i))
    replace_goto_queue_1 (tsi_stmt (i), tf, &i);
}

/* Replace all goto queue members.  */

static void
replace_goto_queue (struct leh_tf_state *tf)
{
  if (tf->goto_queue_active == 0)
    return;
  replace_goto_queue_stmt_list (*tf->top_p, tf);
}

/* For any GOTO_EXPR or RETURN_EXPR, decide whether it leaves a try_finally
   node, and if so record that fact in the goto queue associated with that
   try_finally node.  */

static void
maybe_record_in_goto_queue (struct leh_state *state, tree stmt)
{
  struct leh_tf_state *tf = state->tf;
  struct goto_queue_node *q;
  size_t active, size;
  int index;

  if (!tf)
    return;

  switch (TREE_CODE (stmt))
    {
    case GOTO_EXPR:
      {
	tree lab = GOTO_DESTINATION (stmt);

	/* Computed and non-local gotos do not get processed.  Given
	   their nature we can neither tell whether we've escaped the
	   finally block nor redirect them if we knew.  */
	if (TREE_CODE (lab) != LABEL_DECL)
	  return;

	/* No need to record gotos that don't leave the try block.  */
	if (! outside_finally_tree (lab, tf->try_finally_expr))
	  return;

	if (! tf->dest_array)
	  {
	    tf->dest_array = VEC_alloc (tree, heap, 10);
	    VEC_quick_push (tree, tf->dest_array, lab);
	    index = 0;
	  }
	else
	  {
	    int n = VEC_length (tree, tf->dest_array);
	    for (index = 0; index < n; ++index)
	      if (VEC_index (tree, tf->dest_array, index) == lab)
		break;
	    if (index == n)
	      VEC_safe_push (tree, heap, tf->dest_array, lab);
	  }
      }
      break;

    case RETURN_EXPR:
      tf->may_return = true;
      index = -1;
      break;

    default:
      gcc_unreachable ();
    }

  active = tf->goto_queue_active;
  size = tf->goto_queue_size;
  if (active >= size)
    {
      size = (size ? size * 2 : 32);
      tf->goto_queue_size = size;
      tf->goto_queue
         = XRESIZEVEC (struct goto_queue_node, tf->goto_queue, size);
    }

  q = &tf->goto_queue[active];
  tf->goto_queue_active = active + 1;

  memset (q, 0, sizeof (*q));
  q->stmt = stmt;
  q->index = index;
}

#ifdef ENABLE_CHECKING
/* We do not process SWITCH_EXPRs for now.  As long as the original source
   was in fact structured, and we've not yet done jump threading, then none
   of the labels will leave outer TRY_FINALLY_EXPRs.  Verify this.  */

static void
verify_norecord_switch_expr (struct leh_state *state, tree switch_expr)
{
  struct leh_tf_state *tf = state->tf;
  size_t i, n;
  tree vec;

  if (!tf)
    return;

  vec = SWITCH_LABELS (switch_expr);
  n = TREE_VEC_LENGTH (vec);

  for (i = 0; i < n; ++i)
    {
      tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
      gcc_assert (!outside_finally_tree (lab, tf->try_finally_expr));
    }
}
#else
#define verify_norecord_switch_expr(state, switch_expr)
#endif

/* Redirect a RETURN_EXPR pointed to by STMT_P to FINLAB.  Place in CONT_P
   whatever is needed to finish the return.  If MOD is non-null, insert it
   before the new branch.  RETURN_VALUE_P is a cache containing a temporary
   variable to be used in manipulating the value returned from the function.  */

static void
do_return_redirection (struct goto_queue_node *q, tree finlab, tree mod,
		       tree *return_value_p)
{
  tree ret_expr = TREE_OPERAND (q->stmt, 0);
  tree x;

  if (ret_expr)
    {
      /* The nasty part about redirecting the return value is that the
	 return value itself is to be computed before the FINALLY block
	 is executed.  e.g.

		int x;
		int foo (void)
		{
		  x = 0;
		  try {
		    return x;
		  } finally {
		    x++;
		  }
		}

	  should return 0, not 1.  Arrange for this to happen by copying
	  computed the return value into a local temporary.  This also
	  allows us to redirect multiple return statements through the
	  same destination block; whether this is a net win or not really
	  depends, I guess, but it does make generation of the switch in
	  lower_try_finally_switch easier.  */

      switch (TREE_CODE (ret_expr))
	{
	case RESULT_DECL:
	  if (!*return_value_p)
	    *return_value_p = ret_expr;
	  else
	    gcc_assert (*return_value_p == ret_expr);
	  q->cont_stmt = q->stmt;
	  break;

	case MODIFY_EXPR:
	  {
	    tree result = TREE_OPERAND (ret_expr, 0);
	    tree new, old = TREE_OPERAND (ret_expr, 1);

	    if (!*return_value_p)
	      {
		if (aggregate_value_p (TREE_TYPE (result),
				      TREE_TYPE (current_function_decl)))
		  /* If this function returns in memory, copy the argument
		    into the return slot now.  Otherwise, we might need to
		    worry about magic return semantics, so we need to use a
		    temporary to hold the value until we're actually ready
		    to return.  */
		  new = result;
		else
		  new = create_tmp_var (TREE_TYPE (old), "rettmp");
		*return_value_p = new;
	      }
	    else
	      new = *return_value_p;

	    x = build2 (MODIFY_EXPR, TREE_TYPE (new), new, old);
	    append_to_statement_list (x, &q->repl_stmt);

	    if (new == result)
	      x = result;
	    else
	      x = build2 (MODIFY_EXPR, TREE_TYPE (result), result, new);
	    q->cont_stmt = build1 (RETURN_EXPR, void_type_node, x);
	  }

	default:
	  gcc_unreachable ();
	}
    }
  else
    {
      /* If we don't return a value, all return statements are the same.  */
      q->cont_stmt = q->stmt;
    }

  if (mod)
    append_to_statement_list (mod, &q->repl_stmt);

  x = build1 (GOTO_EXPR, void_type_node, finlab);
  append_to_statement_list (x, &q->repl_stmt);
}

/* Similar, but easier, for GOTO_EXPR.  */

static void
do_goto_redirection (struct goto_queue_node *q, tree finlab, tree mod)
{
  tree x;

  q->cont_stmt = q->stmt;
  if (mod)
    append_to_statement_list (mod, &q->repl_stmt);

  x = build1 (GOTO_EXPR, void_type_node, finlab);
  append_to_statement_list (x, &q->repl_stmt);
}

/* We want to transform
	try { body; } catch { stuff; }
   to
	body; goto over; lab: stuff; over:

   T is a TRY_FINALLY or TRY_CATCH node.  LAB is the label that
   should be placed before the second operand, or NULL.  OVER is
   an existing label that should be put at the exit, or NULL.  */

static void
frob_into_branch_around (tree *tp, tree lab, tree over)
{
  tree x, op1;

  op1 = TREE_OPERAND (*tp, 1);
  *tp = TREE_OPERAND (*tp, 0);

  if (block_may_fallthru (*tp))
    {
      if (!over)
	over = create_artificial_label ();
      x = build1 (GOTO_EXPR, void_type_node, over);
      append_to_statement_list (x, tp);
    }

  if (lab)
    {
      x = build1 (LABEL_EXPR, void_type_node, lab);
      append_to_statement_list (x, tp);
    }

  append_to_statement_list (op1, tp);

  if (over)
    {
      x = build1 (LABEL_EXPR, void_type_node, over);
      append_to_statement_list (x, tp);
    }
}

/* A subroutine of lower_try_finally.  Duplicate the tree rooted at T.
   Make sure to record all new labels found.  */

static tree
lower_try_finally_dup_block (tree t, struct leh_state *outer_state)
{
  tree region = NULL;

  t = unsave_expr_now (t);

  if (outer_state->tf)
    region = outer_state->tf->try_finally_expr;
  collect_finally_tree (t, region);

  return t;
}

/* A subroutine of lower_try_finally.  Create a fallthru label for
   the given try_finally state.  The only tricky bit here is that
   we have to make sure to record the label in our outer context.  */

static tree
lower_try_finally_fallthru_label (struct leh_tf_state *tf)
{
  tree label = tf->fallthru_label;
  if (!label)
    {
      label = create_artificial_label ();
      tf->fallthru_label = label;
      if (tf->outer->tf)
        record_in_finally_tree (label, tf->outer->tf->try_finally_expr);
    }
  return label;
}

/* A subroutine of lower_try_finally.  If lang_protect_cleanup_actions
   returns non-null, then the language requires that the exception path out
   of a try_finally be treated specially.  To wit: the code within the
   finally block may not itself throw an exception.  We have two choices here.
   First we can duplicate the finally block and wrap it in a must_not_throw
   region.  Second, we can generate code like

	try {
	  finally_block;
	} catch {
	  if (fintmp == eh_edge)
	    protect_cleanup_actions;
	}

   where "fintmp" is the temporary used in the switch statement generation
   alternative considered below.  For the nonce, we always choose the first
   option.

   THIS_STATE may be null if this is a try-cleanup, not a try-finally.  */

static void
honor_protect_cleanup_actions (struct leh_state *outer_state,
			       struct leh_state *this_state,
			       struct leh_tf_state *tf)
{
  tree protect_cleanup_actions, finally, x;
  tree_stmt_iterator i;
  bool finally_may_fallthru;

  /* First check for nothing to do.  */
  if (lang_protect_cleanup_actions)
    protect_cleanup_actions = lang_protect_cleanup_actions ();
  else
    protect_cleanup_actions = NULL;

  finally = TREE_OPERAND (*tf->top_p, 1);

  /* If the EH case of the finally block can fall through, this may be a
     structure of the form
	try {
	  try {
	    throw ...;
	  } cleanup {
	    try {
	      throw ...;
	    } catch (...) {
	    }
	  }
	} catch (...) {
	  yyy;
	}
    E.g. with an inline destructor with an embedded try block.  In this
    case we must save the runtime EH data around the nested exception.

    This complication means that any time the previous runtime data might
    be used (via fallthru from the finally) we handle the eh case here,
    whether or not protect_cleanup_actions is active.  */

  finally_may_fallthru = block_may_fallthru (finally);
  if (!finally_may_fallthru && !protect_cleanup_actions)
    return;

  /* Duplicate the FINALLY block.  Only need to do this for try-finally,
     and not for cleanups.  */
  if (this_state)
    finally = lower_try_finally_dup_block (finally, outer_state);

  /* Resume execution after the exception.  Adding this now lets
     lower_eh_filter not add unnecessary gotos, as it is clear that
     we never fallthru from this copy of the finally block.  */
  if (finally_may_fallthru)
    {
      tree save_eptr, save_filt;

      save_eptr = create_tmp_var (ptr_type_node, "save_eptr");
      /* LLVM LOCAL begin */
#if ENABLE_LLVM
      /* LLVM exceptions use 64 bits for these on 64-bit targets. */
      save_filt = create_tmp_var (long_integer_type_node, "save_filt");
#else
      save_filt = create_tmp_var (integer_type_node, "save_filt");
#endif
      /* LLVM LOCAL end */
      i = tsi_start (finally);
      x = build0 (EXC_PTR_EXPR, ptr_type_node);
      x = build2 (MODIFY_EXPR, void_type_node, save_eptr, x);
      tsi_link_before (&i, x, TSI_CONTINUE_LINKING);
      /* LLVM LOCAL begin */
#if ENABLE_LLVM
      x = build0 (FILTER_EXPR, long_integer_type_node);
#else
      x = build0 (FILTER_EXPR, integer_type_node);
#endif
      /* LLVM LOCAL end */
      x = build2 (MODIFY_EXPR, void_type_node, save_filt, x);
      tsi_link_before (&i, x, TSI_CONTINUE_LINKING);

      i = tsi_last (finally);
      x = build0 (EXC_PTR_EXPR, ptr_type_node);
      x = build2 (MODIFY_EXPR, void_type_node, x, save_eptr);
      tsi_link_after (&i, x, TSI_CONTINUE_LINKING);

      /* LLVM LOCAL begin */
#if ENABLE_LLVM
      x = build0 (FILTER_EXPR, long_integer_type_node);
#else
      x = build0 (FILTER_EXPR, integer_type_node);
#endif
      /* LLVM LOCAL end */
      x = build2 (MODIFY_EXPR, void_type_node, x, save_filt);
      tsi_link_after (&i, x, TSI_CONTINUE_LINKING);

      x = build_resx (get_eh_region_number (tf->region));
      tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
    }

  /* Wrap the block with protect_cleanup_actions as the action.  */
  if (protect_cleanup_actions)
    {
      x = build2 (EH_FILTER_EXPR, void_type_node, NULL, NULL);
      append_to_statement_list (protect_cleanup_actions, &EH_FILTER_FAILURE (x));
      EH_FILTER_MUST_NOT_THROW (x) = 1;
      finally = build2 (TRY_CATCH_EXPR, void_type_node, finally, x);
      lower_eh_filter (outer_state, &finally);
    }
  else
    lower_eh_constructs_1 (outer_state, &finally);

  /* Hook this up to the end of the existing try block.  If we
     previously fell through the end, we'll have to branch around.
     This means adding a new goto, and adding it to the queue.  */

  i = tsi_last (TREE_OPERAND (*tf->top_p, 0));

  if (tf->may_fallthru)
    {
      x = lower_try_finally_fallthru_label (tf);
      x = build1 (GOTO_EXPR, void_type_node, x);
      tsi_link_after (&i, x, TSI_CONTINUE_LINKING);

      if (this_state)
        maybe_record_in_goto_queue (this_state, x);

      tf->may_fallthru = false;
    }

  x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
  tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
  tsi_link_after (&i, finally, TSI_CONTINUE_LINKING);

  /* Having now been handled, EH isn't to be considered with
     the rest of the outgoing edges.  */
  tf->may_throw = false;
}

/* A subroutine of lower_try_finally.  We have determined that there is
   no fallthru edge out of the finally block.  This means that there is
   no outgoing edge corresponding to any incoming edge.  Restructure the
   try_finally node for this special case.  */

static void
lower_try_finally_nofallthru (struct leh_state *state, struct leh_tf_state *tf)
{
  tree x, finally, lab, return_val;
  struct goto_queue_node *q, *qe;

  if (tf->may_throw)
    lab = tf->eh_label;
  else
    lab = create_artificial_label ();

  finally = TREE_OPERAND (*tf->top_p, 1);
  *tf->top_p = TREE_OPERAND (*tf->top_p, 0);

  x = build1 (LABEL_EXPR, void_type_node, lab);
  append_to_statement_list (x, tf->top_p);

  return_val = NULL;
  q = tf->goto_queue;
  qe = q + tf->goto_queue_active;
  for (; q < qe; ++q)
    if (q->index < 0)
      do_return_redirection (q, lab, NULL, &return_val);
    else
      do_goto_redirection (q, lab, NULL);

  replace_goto_queue (tf);

  lower_eh_constructs_1 (state, &finally);
  append_to_statement_list (finally, tf->top_p);
}

/* A subroutine of lower_try_finally.  We have determined that there is
   exactly one destination of the finally block.  Restructure the
   try_finally node for this special case.  */

static void
lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
{
  struct goto_queue_node *q, *qe;
  tree x, finally, finally_label;

  finally = TREE_OPERAND (*tf->top_p, 1);
  *tf->top_p = TREE_OPERAND (*tf->top_p, 0);

  lower_eh_constructs_1 (state, &finally);

  if (tf->may_throw)
    {
      /* Only reachable via the exception edge.  Add the given label to
         the head of the FINALLY block.  Append a RESX at the end.  */

      x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
      append_to_statement_list (x, tf->top_p);

      append_to_statement_list (finally, tf->top_p);

      x = build_resx (get_eh_region_number (tf->region));

      append_to_statement_list (x, tf->top_p);

      return;
    }

  if (tf->may_fallthru)
    {
      /* Only reachable via the fallthru edge.  Do nothing but let
	 the two blocks run together; we'll fall out the bottom.  */
      append_to_statement_list (finally, tf->top_p);
      return;
    }

  finally_label = create_artificial_label ();
  x = build1 (LABEL_EXPR, void_type_node, finally_label);
  append_to_statement_list (x, tf->top_p);

  append_to_statement_list (finally, tf->top_p);

  q = tf->goto_queue;
  qe = q + tf->goto_queue_active;

  if (tf->may_return)
    {
      /* Reachable by return expressions only.  Redirect them.  */
      tree return_val = NULL;
      for (; q < qe; ++q)
	do_return_redirection (q, finally_label, NULL, &return_val);
      replace_goto_queue (tf);
    }
  else
    {
      /* Reachable by goto expressions only.  Redirect them.  */
      for (; q < qe; ++q)
	do_goto_redirection (q, finally_label, NULL);
      replace_goto_queue (tf);

      if (VEC_index (tree, tf->dest_array, 0) == tf->fallthru_label)
	{
	  /* Reachable by goto to fallthru label only.  Redirect it
	     to the new label (already created, sadly), and do not
	     emit the final branch out, or the fallthru label.  */
	  tf->fallthru_label = NULL;
	  return;
	}
    }

  append_to_statement_list (tf->goto_queue[0].cont_stmt, tf->top_p);
  maybe_record_in_goto_queue (state, tf->goto_queue[0].cont_stmt);
}

/* A subroutine of lower_try_finally.  There are multiple edges incoming
   and outgoing from the finally block.  Implement this by duplicating the
   finally block for every destination.  */

static void
lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
{
  tree finally, new_stmt;
  tree x;

  finally = TREE_OPERAND (*tf->top_p, 1);
  *tf->top_p = TREE_OPERAND (*tf->top_p, 0);

  new_stmt = NULL_TREE;

  if (tf->may_fallthru)
    {
      x = lower_try_finally_dup_block (finally, state);
      lower_eh_constructs_1 (state, &x);
      append_to_statement_list (x, &new_stmt);

      x = lower_try_finally_fallthru_label (tf);
      x = build1 (GOTO_EXPR, void_type_node, x);
      append_to_statement_list (x, &new_stmt);
    }

  if (tf->may_throw)
    {
      x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
      append_to_statement_list (x, &new_stmt);

      x = lower_try_finally_dup_block (finally, state);
      lower_eh_constructs_1 (state, &x);
      append_to_statement_list (x, &new_stmt);

      x = build_resx (get_eh_region_number (tf->region));
      append_to_statement_list (x, &new_stmt);
    }

  if (tf->goto_queue)
    {
      struct goto_queue_node *q, *qe;
      tree return_val = NULL;
      int return_index, index;
      struct labels_s
      {
	struct goto_queue_node *q;
	tree label;
      } *labels;

      return_index = VEC_length (tree, tf->dest_array);
      labels = XCNEWVEC (struct labels_s, return_index + 1);

      q = tf->goto_queue;
      qe = q + tf->goto_queue_active;
      for (; q < qe; q++)
	{
	  index = q->index < 0 ? return_index : q->index;

	  if (!labels[index].q)
	    labels[index].q = q;
	}

      for (index = 0; index < return_index + 1; index++)
	{
	  tree lab;

	  q = labels[index].q;
	  if (! q)
	    continue;

	  lab = labels[index].label = create_artificial_label ();

	  if (index == return_index)
	    do_return_redirection (q, lab, NULL, &return_val);
	  else
	    do_goto_redirection (q, lab, NULL);

	  x = build1 (LABEL_EXPR, void_type_node, lab);
	  append_to_statement_list (x, &new_stmt);

	  x = lower_try_finally_dup_block (finally, state);
	  lower_eh_constructs_1 (state, &x);
	  append_to_statement_list (x, &new_stmt);

	  append_to_statement_list (q->cont_stmt, &new_stmt);
	  maybe_record_in_goto_queue (state, q->cont_stmt);
	}

      for (q = tf->goto_queue; q < qe; q++)
	{
	  tree lab;

	  index = q->index < 0 ? return_index : q->index;

	  if (labels[index].q == q)
	    continue;

	  lab = labels[index].label;

	  if (index == return_index)
	    do_return_redirection (q, lab, NULL, &return_val);
	  else
	    do_goto_redirection (q, lab, NULL);
	}
	
      replace_goto_queue (tf);
      free (labels);
    }

  /* Need to link new stmts after running replace_goto_queue due
     to not wanting to process the same goto stmts twice.  */
  append_to_statement_list (new_stmt, tf->top_p);
}

/* A subroutine of lower_try_finally.  There are multiple edges incoming
   and outgoing from the finally block.  Implement this by instrumenting
   each incoming edge and creating a switch statement at the end of the
   finally block that branches to the appropriate destination.  */

static void
lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
{
  struct goto_queue_node *q, *qe;
  tree return_val = NULL;
  tree finally, finally_tmp, finally_label;
  int return_index, eh_index, fallthru_index;
  int nlabels, ndests, j, last_case_index;
  tree case_label_vec, switch_stmt, last_case, switch_body;
  tree x;

  /* Mash the TRY block to the head of the chain.  */
  finally = TREE_OPERAND (*tf->top_p, 1);
  *tf->top_p = TREE_OPERAND (*tf->top_p, 0);

  /* Lower the finally block itself.  */
  lower_eh_constructs_1 (state, &finally);

  /* Prepare for switch statement generation.  */
  nlabels = VEC_length (tree, tf->dest_array);
  return_index = nlabels;
  eh_index = return_index + tf->may_return;
  fallthru_index = eh_index + tf->may_throw;
  ndests = fallthru_index + tf->may_fallthru;

  finally_tmp = create_tmp_var (integer_type_node, "finally_tmp");
  finally_label = create_artificial_label ();

  case_label_vec = make_tree_vec (ndests);
  switch_stmt = build3 (SWITCH_EXPR, integer_type_node, finally_tmp,
		        NULL_TREE, case_label_vec);
  switch_body = NULL;
  last_case = NULL;
  last_case_index = 0;

  /* Begin inserting code for getting to the finally block.  Things
     are done in this order to correspond to the sequence the code is
     layed out.  */

  if (tf->may_fallthru)
    {
      x = build2 (MODIFY_EXPR, void_type_node, finally_tmp,
		  build_int_cst (NULL_TREE, fallthru_index));
      append_to_statement_list (x, tf->top_p);

      if (tf->may_throw)
	{
	  x = build1 (GOTO_EXPR, void_type_node, finally_label);
	  append_to_statement_list (x, tf->top_p);
	}


      last_case = build3 (CASE_LABEL_EXPR, void_type_node,
			  build_int_cst (NULL_TREE, fallthru_index), NULL,
			  create_artificial_label ());
      TREE_VEC_ELT (case_label_vec, last_case_index) = last_case;
      last_case_index++;

      x = build1 (LABEL_EXPR, void_type_node, CASE_LABEL (last_case));
      append_to_statement_list (x, &switch_body);

      x = lower_try_finally_fallthru_label (tf);
      x = build1 (GOTO_EXPR, void_type_node, x);
      append_to_statement_list (x, &switch_body);
    }

  if (tf->may_throw)
    {
      x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
      append_to_statement_list (x, tf->top_p);

      x = build2 (MODIFY_EXPR, void_type_node, finally_tmp,
		  build_int_cst (NULL_TREE, eh_index));
      append_to_statement_list (x, tf->top_p);

      last_case = build3 (CASE_LABEL_EXPR, void_type_node,
			  build_int_cst (NULL_TREE, eh_index), NULL,
			  create_artificial_label ());
      TREE_VEC_ELT (case_label_vec, last_case_index) = last_case;
      last_case_index++;

      x = build1 (LABEL_EXPR, void_type_node, CASE_LABEL (last_case));
      append_to_statement_list (x, &switch_body);
      x = build_resx (get_eh_region_number (tf->region));
      append_to_statement_list (x, &switch_body);
    }

  x = build1 (LABEL_EXPR, void_type_node, finally_label);
  append_to_statement_list (x, tf->top_p);

  append_to_statement_list (finally, tf->top_p);

  /* Redirect each incoming goto edge.  */
  q = tf->goto_queue;
  qe = q + tf->goto_queue_active;
  j = last_case_index + tf->may_return;
  for (; q < qe; ++q)
    {
      tree mod;
      int switch_id, case_index;

      if (q->index < 0)
	{
	  mod = build2 (MODIFY_EXPR, void_type_node, finally_tmp,
		        build_int_cst (NULL_TREE, return_index));
	  do_return_redirection (q, finally_label, mod, &return_val);
	  switch_id = return_index;
	}
      else
	{
	  mod = build2 (MODIFY_EXPR, void_type_node, finally_tmp,
		        build_int_cst (NULL_TREE, q->index));
	  do_goto_redirection (q, finally_label, mod);
	  switch_id = q->index;
	}

      case_index = j + q->index;
      if (!TREE_VEC_ELT (case_label_vec, case_index))
	TREE_VEC_ELT (case_label_vec, case_index)
	  = build3 (CASE_LABEL_EXPR, void_type_node,
		    build_int_cst (NULL_TREE, switch_id), NULL,
		    /* We store the cont_stmt in the
		       CASE_LABEL, so that we can recover it
		       in the loop below.  We don't create
		       the new label while walking the
		       goto_queue because pointers don't
		       offer a stable order.  */
		    q->cont_stmt);
    }
  for (j = last_case_index; j < last_case_index + nlabels; j++)
    {
      tree label;
      tree cont_stmt;

      last_case = TREE_VEC_ELT (case_label_vec, j);

      gcc_assert (last_case);

      cont_stmt = CASE_LABEL (last_case);

      label = create_artificial_label ();
      CASE_LABEL (last_case) = label;

      x = build1 (LABEL_EXPR, void_type_node, label);
      append_to_statement_list (x, &switch_body);
      append_to_statement_list (cont_stmt, &switch_body);
      maybe_record_in_goto_queue (state, cont_stmt);
    }
  replace_goto_queue (tf);

  /* Make sure that the last case is the default label, as one is required.
     Then sort the labels, which is also required in GIMPLE.  */
  CASE_LOW (last_case) = NULL;
  sort_case_labels (case_label_vec);

  /* Need to link switch_stmt after running replace_goto_queue due
     to not wanting to process the same goto stmts twice.  */
  append_to_statement_list (switch_stmt, tf->top_p);
  append_to_statement_list (switch_body, tf->top_p);
}

/* Decide whether or not we are going to duplicate the finally block.
   There are several considerations.

   First, if this is Java, then the finally block contains code
   written by the user.  It has line numbers associated with it,
   so duplicating the block means it's difficult to set a breakpoint.
   Since controlling code generation via -g is verboten, we simply
   never duplicate code without optimization.

   Second, we'd like to prevent egregious code growth.  One way to
   do this is to estimate the size of the finally block, multiply
   that by the number of copies we'd need to make, and compare against
   the estimate of the size of the switch machinery we'd have to add.  */

static bool
decide_copy_try_finally (int ndests, tree finally)
{
  int f_estimate, sw_estimate;

  /* LLVM LOCAL begin - let LLVM make this decision.  */
#ifdef ENABLE_LLVM
  if (1)
#else
  if (!optimize)
#endif
  /* LLVM LOCAL end */
    return false;

  /* Finally estimate N times, plus N gotos.  */
  f_estimate = estimate_num_insns (finally);
  f_estimate = (f_estimate + 1) * ndests;

  /* Switch statement (cost 10), N variable assignments, N gotos.  */
  sw_estimate = 10 + 2 * ndests;

  /* Optimize for size clearly wants our best guess.  */
  if (optimize_size)
    return f_estimate < sw_estimate;

  /* ??? These numbers are completely made up so far.  */
  if (optimize > 1)
    return f_estimate < 100 || f_estimate < sw_estimate * 2;
  else
    return f_estimate < 40 || f_estimate * 2 < sw_estimate * 3;
}

/* A subroutine of lower_eh_constructs_1.  Lower a TRY_FINALLY_EXPR nodes
   to a sequence of labels and blocks, plus the exception region trees
   that record all the magic.  This is complicated by the need to
   arrange for the FINALLY block to be executed on all exits.  */

static void
lower_try_finally (struct leh_state *state, tree *tp)
{
  struct leh_tf_state this_tf;
  struct leh_state this_state;
  int ndests;

  /* Process the try block.  */

  memset (&this_tf, 0, sizeof (this_tf));
  this_tf.try_finally_expr = *tp;
  this_tf.top_p = tp;
  this_tf.outer = state;
  if (using_eh_for_cleanups_p)
    this_tf.region
      = gen_eh_region_cleanup (state->cur_region, state->prev_try);
  else
    this_tf.region = NULL;

  this_state.cur_region = this_tf.region;
  this_state.prev_try = state->prev_try;
  this_state.tf = &this_tf;

  lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));

  /* Determine if the try block is escaped through the bottom.  */
  this_tf.may_fallthru = block_may_fallthru (TREE_OPERAND (*tp, 0));

  /* Determine if any exceptions are possible within the try block.  */
  if (using_eh_for_cleanups_p)
    this_tf.may_throw = get_eh_region_may_contain_throw (this_tf.region);
  if (this_tf.may_throw)
    {
      this_tf.eh_label = create_artificial_label ();
      set_eh_region_tree_label (this_tf.region, this_tf.eh_label);
      honor_protect_cleanup_actions (state, &this_state, &this_tf);
    }

  /* Sort the goto queue for efficient searching later.  */
  if (this_tf.goto_queue_active > 1)
    qsort (this_tf.goto_queue, this_tf.goto_queue_active,
	   sizeof (struct goto_queue_node), goto_queue_cmp);

  /* Determine how many edges (still) reach the finally block.  Or rather,
     how many destinations are reached by the finally block.  Use this to
     determine how we process the finally block itself.  */

  ndests = VEC_length (tree, this_tf.dest_array);
  ndests += this_tf.may_fallthru;
  ndests += this_tf.may_return;
  ndests += this_tf.may_throw;

  /* If the FINALLY block is not reachable, dike it out.  */
  if (ndests == 0)
    *tp = TREE_OPERAND (*tp, 0);

  /* If the finally block doesn't fall through, then any destination
     we might try to impose there isn't reached either.  There may be
     some minor amount of cleanup and redirection still needed.  */
  else if (!block_may_fallthru (TREE_OPERAND (*tp, 1)))
    lower_try_finally_nofallthru (state, &this_tf);

  /* We can easily special-case redirection to a single destination.  */
  else if (ndests == 1)
    lower_try_finally_onedest (state, &this_tf);

  else if (decide_copy_try_finally (ndests, TREE_OPERAND (*tp, 1)))
    lower_try_finally_copy (state, &this_tf);
  else
    lower_try_finally_switch (state, &this_tf);

  /* If someone requested we add a label at the end of the transformed
     block, do so.  */
  if (this_tf.fallthru_label)
    {
      tree x = build1 (LABEL_EXPR, void_type_node, this_tf.fallthru_label);
      append_to_statement_list (x, tp);
    }

  VEC_free (tree, heap, this_tf.dest_array);
  if (this_tf.goto_queue)
    free (this_tf.goto_queue);
}

/* A subroutine of lower_eh_constructs_1.  Lower a TRY_CATCH_EXPR with a
   list of CATCH_EXPR nodes to a sequence of labels and blocks, plus the
   exception region trees that record all the magic.  */

static void
lower_catch (struct leh_state *state, tree *tp)
{
  struct eh_region *try_region;
  struct leh_state this_state;
  tree_stmt_iterator i;
  tree out_label;

  try_region = gen_eh_region_try (state->cur_region);
  this_state.cur_region = try_region;
  this_state.prev_try = try_region;
  this_state.tf = state->tf;

  lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));

  if (!get_eh_region_may_contain_throw (try_region))
    {
      *tp = TREE_OPERAND (*tp, 0);
      return;
    }

  out_label = NULL;
  for (i = tsi_start (TREE_OPERAND (*tp, 1)); !tsi_end_p (i); )
    {
      struct eh_region *catch_region;
      tree catch, x, eh_label;

      catch = tsi_stmt (i);
      catch_region = gen_eh_region_catch (try_region, CATCH_TYPES (catch));

      this_state.cur_region = catch_region;
      this_state.prev_try = state->prev_try;
      lower_eh_constructs_1 (&this_state, &CATCH_BODY (catch));

      eh_label = create_artificial_label ();
      set_eh_region_tree_label (catch_region, eh_label);

      x = build1 (LABEL_EXPR, void_type_node, eh_label);
      tsi_link_before (&i, x, TSI_SAME_STMT);

      if (block_may_fallthru (CATCH_BODY (catch)))
	{
	  if (!out_label)
	    out_label = create_artificial_label ();

	  x = build1 (GOTO_EXPR, void_type_node, out_label);
	  append_to_statement_list (x, &CATCH_BODY (catch));
	}

      tsi_link_before (&i, CATCH_BODY (catch), TSI_SAME_STMT);
      tsi_delink (&i);
    }

  frob_into_branch_around (tp, NULL, out_label);
}

/* A subroutine of lower_eh_constructs_1.  Lower a TRY_CATCH_EXPR with a
   EH_FILTER_EXPR to a sequence of labels and blocks, plus the exception
   region trees that record all the magic.  */

static void
lower_eh_filter (struct leh_state *state, tree *tp)
{
  struct leh_state this_state;
  struct eh_region *this_region;
  tree inner = expr_first (TREE_OPERAND (*tp, 1));
  tree eh_label;

  if (EH_FILTER_MUST_NOT_THROW (inner))
    this_region = gen_eh_region_must_not_throw (state->cur_region);
  else
    this_region = gen_eh_region_allowed (state->cur_region,
					 EH_FILTER_TYPES (inner));
  this_state = *state;
  this_state.cur_region = this_region;
  /* For must not throw regions any cleanup regions inside it
     can't reach outer catch regions.  */
  if (EH_FILTER_MUST_NOT_THROW (inner))
    this_state.prev_try = NULL;

  lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));

  if (!get_eh_region_may_contain_throw (this_region))
    {
      *tp = TREE_OPERAND (*tp, 0);
      return;
    }

  lower_eh_constructs_1 (state, &EH_FILTER_FAILURE (inner));
  TREE_OPERAND (*tp, 1) = EH_FILTER_FAILURE (inner);

  eh_label = create_artificial_label ();
  set_eh_region_tree_label (this_region, eh_label);

  frob_into_branch_around (tp, eh_label, NULL);
}

/* Implement a cleanup expression.  This is similar to try-finally,
   except that we only execute the cleanup block for exception edges.  */

static void
lower_cleanup (struct leh_state *state, tree *tp)
{
  struct leh_state this_state;
  struct eh_region *this_region;
  struct leh_tf_state fake_tf;

  /* If not using eh, then exception-only cleanups are no-ops.  */
  if (!flag_exceptions)
    {
      *tp = TREE_OPERAND (*tp, 0);
      lower_eh_constructs_1 (state, tp);
      return;
    }

  this_region = gen_eh_region_cleanup (state->cur_region, state->prev_try);
  this_state = *state;
  this_state.cur_region = this_region;

  lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));

  if (!get_eh_region_may_contain_throw (this_region))
    {
      *tp = TREE_OPERAND (*tp, 0);
      return;
    }

  /* Build enough of a try-finally state so that we can reuse
     honor_protect_cleanup_actions.  */
  memset (&fake_tf, 0, sizeof (fake_tf));
  fake_tf.top_p = tp;
  fake_tf.outer = state;
  fake_tf.region = this_region;
  fake_tf.may_fallthru = block_may_fallthru (TREE_OPERAND (*tp, 0));
  fake_tf.may_throw = true;

  fake_tf.eh_label = create_artificial_label ();
  set_eh_region_tree_label (this_region, fake_tf.eh_label);

  honor_protect_cleanup_actions (state, NULL, &fake_tf);

  if (fake_tf.may_throw)
    {
      /* In this case honor_protect_cleanup_actions had nothing to do,
	 and we should process this normally.  */
      lower_eh_constructs_1 (state, &TREE_OPERAND (*tp, 1));
      frob_into_branch_around (tp, fake_tf.eh_label, fake_tf.fallthru_label);
    }
  else
    {
      /* In this case honor_protect_cleanup_actions did nearly all of
	 the work.  All we have left is to append the fallthru_label.  */

      *tp = TREE_OPERAND (*tp, 0);
      if (fake_tf.fallthru_label)
	{
	  tree x = build1 (LABEL_EXPR, void_type_node, fake_tf.fallthru_label);
	  append_to_statement_list (x, tp);
	}
    }
}

/* Main loop for lowering eh constructs.  */

static void
lower_eh_constructs_1 (struct leh_state *state, tree *tp)
{
  tree_stmt_iterator i;
  tree t = *tp;

  switch (TREE_CODE (t))
    {
    case COND_EXPR:
      lower_eh_constructs_1 (state, &COND_EXPR_THEN (t));
      lower_eh_constructs_1 (state, &COND_EXPR_ELSE (t));
      break;

    case CALL_EXPR:
      /* Look for things that can throw exceptions, and record them.  */
      if (state->cur_region && tree_could_throw_p (t))
	{
	  record_stmt_eh_region (state->cur_region, t);
	  note_eh_region_may_contain_throw (state->cur_region);
	}
      break;

    case MODIFY_EXPR:
      /* Look for things that can throw exceptions, and record them.  */
      if (state->cur_region && tree_could_throw_p (t))
	{
	  record_stmt_eh_region (state->cur_region, t);
	  note_eh_region_may_contain_throw (state->cur_region);
	}
      break;

    case GOTO_EXPR:
    case RETURN_EXPR:
      maybe_record_in_goto_queue (state, t);
      break;
    case SWITCH_EXPR:
      verify_norecord_switch_expr (state, t);
      break;

    case TRY_FINALLY_EXPR:
      lower_try_finally (state, tp);
      break;

    case TRY_CATCH_EXPR:
      i = tsi_start (TREE_OPERAND (t, 1));
      switch (TREE_CODE (tsi_stmt (i)))
	{
	case CATCH_EXPR:
	  lower_catch (state, tp);
	  break;
	case EH_FILTER_EXPR:
	  lower_eh_filter (state, tp);
	  break;
	default:
	  lower_cleanup (state, tp);
	  break;
	}
      break;

    case STATEMENT_LIST:
      for (i = tsi_start (t); !tsi_end_p (i); )
	{
	  lower_eh_constructs_1 (state, tsi_stmt_ptr (i));
	  t = tsi_stmt (i);
	  if (TREE_CODE (t) == STATEMENT_LIST)
	    {
	      tsi_link_before (&i, t, TSI_SAME_STMT);
	      tsi_delink (&i);
	    }
	  else
	    tsi_next (&i);
	}
      break;

    default:
      /* A type, a decl, or some kind of statement that we're not
	 interested in.  Don't walk them.  */
      break;
    }
}

static unsigned int
lower_eh_constructs (void)
{
  struct leh_state null_state;
  tree *tp = &DECL_SAVED_TREE (current_function_decl);

  finally_tree = htab_create (31, struct_ptr_hash, struct_ptr_eq, free);

  collect_finally_tree (*tp, NULL);

  memset (&null_state, 0, sizeof (null_state));
  lower_eh_constructs_1 (&null_state, tp);

  htab_delete (finally_tree);

  collect_eh_region_array ();
  return 0;
}

struct tree_opt_pass pass_lower_eh =
{
  "eh",					/* name */
  NULL,					/* gate */
  lower_eh_constructs,			/* execute */
  NULL,					/* sub */
  NULL,					/* next */
  0,					/* static_pass_number */
  TV_TREE_EH,				/* tv_id */
  PROP_gimple_lcf,			/* properties_required */
  PROP_gimple_leh,			/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
  TODO_dump_func,			/* todo_flags_finish */
  0					/* letter */
};


/* Construct EH edges for STMT.  */

static void
make_eh_edge (struct eh_region *region, void *data)
{
  tree stmt, lab;
  basic_block src, dst;

  stmt = (tree) data;
  lab = get_eh_region_tree_label (region);

  src = bb_for_stmt (stmt);
  dst = label_to_block (lab);

  make_edge (src, dst, EDGE_ABNORMAL | EDGE_EH);
}

void
make_eh_edges (tree stmt)
{
  int region_nr;
  bool is_resx;

  if (TREE_CODE (stmt) == RESX_EXPR)
    {
      region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
      is_resx = true;
    }
  else
    {
      region_nr = lookup_stmt_eh_region (stmt);
      if (region_nr < 0)
	return;
      is_resx = false;
    }

  foreach_reachable_handler (region_nr, is_resx, make_eh_edge, stmt);
}

static bool mark_eh_edge_found_error;

/* Mark edge make_eh_edge would create for given region by setting it aux
   field, output error if something goes wrong.  */
static void
mark_eh_edge (struct eh_region *region, void *data)
{
  tree stmt, lab;
  basic_block src, dst;
  edge e;

  stmt = (tree) data;
  lab = get_eh_region_tree_label (region);

  src = bb_for_stmt (stmt);
  dst = label_to_block (lab);

  e = find_edge (src, dst);
  if (!e)
    {
      error ("EH edge %i->%i is missing", src->index, dst->index);
      mark_eh_edge_found_error = true;
    }
  else if (!(e->flags & EDGE_EH))
    {
      error ("EH edge %i->%i miss EH flag", src->index, dst->index);
      mark_eh_edge_found_error = true;
    }
  else if (e->aux)
    {
      /* ??? might not be mistake.  */
      error ("EH edge %i->%i has duplicated regions", src->index, dst->index);
      mark_eh_edge_found_error = true;
    }
  else
    e->aux = (void *)1;
}

/* Verify that BB containing stmt as last stmt has precisely the edges
   make_eh_edges would create.  */
bool
verify_eh_edges (tree stmt)
{
  int region_nr;
  bool is_resx;
  basic_block bb = bb_for_stmt (stmt);
  edge_iterator ei;
  edge e;

  FOR_EACH_EDGE (e, ei, bb->succs)
    gcc_assert (!e->aux);
  mark_eh_edge_found_error = false;
  if (TREE_CODE (stmt) == RESX_EXPR)
    {
      region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
      is_resx = true;
    }
  else
    {
      region_nr = lookup_stmt_eh_region (stmt);
      if (region_nr < 0)
	{
	  FOR_EACH_EDGE (e, ei, bb->succs)
	    if (e->flags & EDGE_EH)
	      {
		error ("BB %i can not throw but has EH edges", bb->index);
		return true;
	      }
	   return false;
	}
      if (!tree_could_throw_p (stmt))
	{
	  error ("BB %i last statement has incorrectly set region", bb->index);
	  return true;
	}
      is_resx = false;
    }

  foreach_reachable_handler (region_nr, is_resx, mark_eh_edge, stmt);
  FOR_EACH_EDGE (e, ei, bb->succs)
    {
      if ((e->flags & EDGE_EH) && !e->aux)
	{
	  error ("unnecessary EH edge %i->%i", bb->index, e->dest->index);
	  mark_eh_edge_found_error = true;
	  return true;
	}
      e->aux = NULL;
    }
  return mark_eh_edge_found_error;
}


/* Return true if the expr can trap, as in dereferencing an invalid pointer
   location or floating point arithmetic.  C.f. the rtl version, may_trap_p.
   This routine expects only GIMPLE lhs or rhs input.  */

bool
tree_could_trap_p (tree expr)
{
  enum tree_code code = TREE_CODE (expr);
  bool honor_nans = false;
  bool honor_snans = false;
  bool fp_operation = false;
  bool honor_trapv = false;
  tree t, base;

  if (TREE_CODE_CLASS (code) == tcc_comparison
      || TREE_CODE_CLASS (code) == tcc_unary
      || TREE_CODE_CLASS (code) == tcc_binary)
    {
      t = TREE_TYPE (expr);
      fp_operation = FLOAT_TYPE_P (t);
      if (fp_operation)
	{
	  honor_nans = flag_trapping_math && !flag_finite_math_only;
	  honor_snans = flag_signaling_nans != 0;
	}
      else if (INTEGRAL_TYPE_P (t) && TYPE_OVERFLOW_TRAPS (t))
	honor_trapv = true;
    }

 restart:
  switch (code)
    {
    case TARGET_MEM_REF:
      /* For TARGET_MEM_REFs use the information based on the original
	 reference.  */
      expr = TMR_ORIGINAL (expr);
      code = TREE_CODE (expr);
      goto restart;

    case COMPONENT_REF:
    case REALPART_EXPR:
    case IMAGPART_EXPR:
    case BIT_FIELD_REF:
    case VIEW_CONVERT_EXPR:
    case WITH_SIZE_EXPR:
      expr = TREE_OPERAND (expr, 0);
      code = TREE_CODE (expr);
      goto restart;

    case ARRAY_RANGE_REF:
      base = TREE_OPERAND (expr, 0);
      if (tree_could_trap_p (base))
	return true;

      if (TREE_THIS_NOTRAP (expr))
	return false;

      return !range_in_array_bounds_p (expr);

    case ARRAY_REF:
      base = TREE_OPERAND (expr, 0);
      if (tree_could_trap_p (base))
	return true;

      if (TREE_THIS_NOTRAP (expr))
	return false;

      return !in_array_bounds_p (expr);

    case INDIRECT_REF:
    case ALIGN_INDIRECT_REF:
    case MISALIGNED_INDIRECT_REF:
      return !TREE_THIS_NOTRAP (expr);

    case ASM_EXPR:
      return TREE_THIS_VOLATILE (expr);

    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case EXACT_DIV_EXPR:
    case CEIL_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case TRUNC_MOD_EXPR:
    case RDIV_EXPR:
      if (honor_snans || honor_trapv)
	return true;
      if (fp_operation)
	return flag_trapping_math;
      t = TREE_OPERAND (expr, 1);
      if (!TREE_CONSTANT (t) || integer_zerop (t))
        return true;
      return false;

    case LT_EXPR:
    case LE_EXPR:
    case GT_EXPR:
    case GE_EXPR:
    case LTGT_EXPR:
      /* Some floating point comparisons may trap.  */
      return honor_nans;

    case EQ_EXPR:
    case NE_EXPR:
    case UNORDERED_EXPR:
    case ORDERED_EXPR:
    case UNLT_EXPR:
    case UNLE_EXPR:
    case UNGT_EXPR:
    case UNGE_EXPR:
    case UNEQ_EXPR:
      return honor_snans;

    case CONVERT_EXPR:
    case FIX_TRUNC_EXPR:
    case FIX_CEIL_EXPR:
    case FIX_FLOOR_EXPR:
    case FIX_ROUND_EXPR:
      /* Conversion of floating point might trap.  */
      return honor_nans;

    case NEGATE_EXPR:
    case ABS_EXPR:
    case CONJ_EXPR:
      /* These operations don't trap with floating point.  */
      if (honor_trapv)
	return true;
      return false;

    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
      /* Any floating arithmetic may trap.  */
      if (fp_operation && flag_trapping_math)
	return true;
      if (honor_trapv)
	return true;
      return false;

    case CALL_EXPR:
      t = get_callee_fndecl (expr);
      /* Assume that calls to weak functions may trap.  */
      if (!t || !DECL_P (t) || DECL_WEAK (t))
	return true;
      return false;

      /* APPLE LOCAL begin weak variables 6822086 */
    case VAR_DECL:
      /* Assume that weak variables may trap.  */
      if (DECL_WEAK (expr))
	return true;
      return false;
      /* APPLE LOCAL end weak variables 6822086 */

    default:
      /* Any floating arithmetic may trap.  */
      if (fp_operation && flag_trapping_math)
	return true;
      return false;
    }
}

bool
tree_could_throw_p (tree t)
{
  if (!flag_exceptions)
    return false;
  if (TREE_CODE (t) == MODIFY_EXPR)
    {
      if (flag_non_call_exceptions
	  && tree_could_trap_p (TREE_OPERAND (t, 0)))
	return true;
      t = TREE_OPERAND (t, 1);
    }

  if (TREE_CODE (t) == WITH_SIZE_EXPR)
    t = TREE_OPERAND (t, 0);
  if (TREE_CODE (t) == CALL_EXPR)
    return (call_expr_flags (t) & ECF_NOTHROW) == 0;
  if (flag_non_call_exceptions)
    return tree_could_trap_p (t);
  return false;
}

bool
tree_can_throw_internal (tree stmt)
{
  int region_nr;
  bool is_resx = false;

  if (TREE_CODE (stmt) == RESX_EXPR)
    region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)), is_resx = true;
  else
    region_nr = lookup_stmt_eh_region (stmt);
  if (region_nr < 0)
    return false;
  return can_throw_internal_1 (region_nr, is_resx);
}

bool
tree_can_throw_external (tree stmt)
{
  int region_nr;
  bool is_resx = false;

  if (TREE_CODE (stmt) == RESX_EXPR)
    region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)), is_resx = true;
  else
    region_nr = lookup_stmt_eh_region (stmt);
  if (region_nr < 0)
    return tree_could_throw_p (stmt);
  else
    return can_throw_external_1 (region_nr, is_resx);
}

/* Given a statement OLD_STMT and a new statement NEW_STMT that has replaced
   OLD_STMT in the function, remove OLD_STMT from the EH table and put NEW_STMT
   in the table if it should be in there.  Return TRUE if a replacement was
   done that my require an EH edge purge.  */

bool 
maybe_clean_or_replace_eh_stmt (tree old_stmt, tree new_stmt) 
{
  int region_nr = lookup_stmt_eh_region (old_stmt);

  if (region_nr >= 0)
    {
      bool new_stmt_could_throw = tree_could_throw_p (new_stmt);

      if (new_stmt == old_stmt && new_stmt_could_throw)
	return false;

      remove_stmt_from_eh_region (old_stmt);
      if (new_stmt_could_throw)
	{
	  add_stmt_to_eh_region (new_stmt, region_nr);
	  return false;
	}
      else
	return true;
    }

  return false;
}

#ifdef ENABLE_CHECKING
static int
verify_eh_throw_stmt_node (void **slot, void *data ATTRIBUTE_UNUSED)
{
  struct throw_stmt_node *node = (struct throw_stmt_node *)*slot;

  gcc_assert (node->stmt->common.ann == NULL);
  return 1;
}

void
verify_eh_throw_table_statements (void)
{
  if (!get_eh_throw_stmt_table (cfun))
    return;
  htab_traverse (get_eh_throw_stmt_table (cfun),
		 verify_eh_throw_stmt_node,
		 NULL);
}

#endif
