--- gcc/params.def.jj	2012-11-23 10:01:50.000000000 +0100
+++ gcc/params.def	2012-12-12 16:26:21.063473958 +0100
@@ -869,6 +869,14 @@ DEFPARAM (PARAM_MAX_VARTRACK_EXPR_DEPTH,
 	  "Max. recursion depth for expanding var tracking expressions",
 	  12, 0, 0)
 
+/* Set maximum length of value location list for which var tracking
+   should add reverse operations.  */
+
+DEFPARAM (PARAM_MAX_VARTRACK_REVERSE_OP_SIZE,
+	  "max-vartrack-reverse-op-size",
+	  "Max. size of loc list for which reverse ops should be added",
+	  50, 0, 0)
+
 /* Set minimum insn uid for non-debug insns.  */
 
 DEFPARAM (PARAM_MIN_NONDEBUG_INSN_UID,
--- gcc/var-tracking.c.jj	2012-12-12 15:57:29.000000000 +0100
+++ gcc/var-tracking.c	2012-12-12 16:28:27.089745791 +0100
@@ -5545,6 +5545,7 @@ reverse_op (rtx val, const_rtx expr, rtx
   cselib_val *v;
   struct elt_loc_list *l;
   enum rtx_code code;
+  int count;
 
   if (GET_CODE (expr) != SET)
     return;
@@ -5586,10 +5587,13 @@ reverse_op (rtx val, const_rtx expr, rtx
   /* Adding a reverse op isn't useful if V already has an always valid
      location.  Ignore ENTRY_VALUE, while it is always constant, we should
      prefer non-ENTRY_VALUE locations whenever possible.  */
-  for (l = v->locs; l; l = l->next)
+  for (l = v->locs, count = 0; l; l = l->next, count++)
     if (CONSTANT_P (l->loc)
 	&& (GET_CODE (l->loc) != CONST || !references_value_p (l->loc, 0)))
       return;
+    /* Avoid creating too large locs lists.  */
+    else if (count == PARAM_VALUE (PARAM_MAX_VARTRACK_REVERSE_OP_SIZE))
+      return;
 
   switch (GET_CODE (src))
     {
