summaryrefslogtreecommitdiff
path: root/gcc/var-tracking.c
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-04 12:54:49 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-04 12:54:49 +0000
commitbdff91a14bf8e5d18b1eb47bb529894482065762 (patch)
tree4515b21fe5d3e25b4d5c8f907d3e78834e1e40ac /gcc/var-tracking.c
parent0158370253d4aef042c4d67b2c0278ded58d83fd (diff)
parent8192796762b4781de57ce2a6c104a71dcbd874e3 (diff)
downloadgcc-bdff91a14bf8e5d18b1eb47bb529894482065762.tar.gz
Merge with trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@205668 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/var-tracking.c')
-rw-r--r--gcc/var-tracking.c88
1 files changed, 84 insertions, 4 deletions
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index ca85127917d..b0cf3fb3069 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -93,17 +93,17 @@
#include "tree.h"
#include "varasm.h"
#include "stor-layout.h"
-#include "gimple.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "basic-block.h"
#include "tm_p.h"
#include "hard-reg-set.h"
-#include "basic-block.h"
#include "flags.h"
#include "insn-config.h"
#include "reload.h"
#include "sbitmap.h"
#include "alloc-pool.h"
#include "fibheap.h"
-#include "hash-table.h"
#include "regs.h"
#include "expr.h"
#include "tree-pass.h"
@@ -115,7 +115,6 @@
#include "params.h"
#include "diagnostic.h"
#include "tree-pretty-print.h"
-#include "pointer-set.h"
#include "recog.h"
#include "tm_p.h"
#include "alias.h"
@@ -5089,6 +5088,11 @@ track_expr_p (tree expr, bool need_rtl)
&maxsize);
if (!DECL_P (innerdecl)
|| DECL_IGNORED_P (innerdecl)
+ /* Do not track declarations for parts of tracked parameters
+ since we want to track them as a whole instead. */
+ || (TREE_CODE (innerdecl) == PARM_DECL
+ && DECL_MODE (innerdecl) != BLKmode
+ && TREE_CODE (TREE_TYPE (innerdecl)) != UNION_TYPE)
|| TREE_STATIC (innerdecl)
|| bitsize <= 0
|| bitpos + bitsize > 256
@@ -5943,6 +5947,20 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
if (type != MO_VAL_SET)
goto log_and_return;
+ /* We cannot track values for multiple-part variables, so we track only
+ locations for tracked parameters passed either by invisible reference
+ or directly in multiple locations. */
+ if (track_p
+ && REG_P (loc)
+ && REG_EXPR (loc)
+ && TREE_CODE (REG_EXPR (loc)) == PARM_DECL
+ && DECL_MODE (REG_EXPR (loc)) != BLKmode
+ && ((MEM_P (DECL_INCOMING_RTL (REG_EXPR (loc)))
+ && XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) != arg_pointer_rtx)
+ || (GET_CODE (DECL_INCOMING_RTL (REG_EXPR (loc))) == PARALLEL
+ && XVECLEN (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) > 1)))
+ goto log_and_return;
+
v = find_use_val (oloc, mode, cui);
if (!v)
@@ -9465,6 +9483,32 @@ vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
return true;
}
}
+ else if (GET_CODE (rtl) == PARALLEL)
+ {
+ tree decl = NULL_TREE;
+ HOST_WIDE_INT offset = MAX_VAR_PARTS;
+ int len = XVECLEN (rtl, 0), i;
+
+ for (i = 0; i < len; i++)
+ {
+ rtx reg = XEXP (XVECEXP (rtl, 0, i), 0);
+ if (!REG_P (reg) || !REG_ATTRS (reg))
+ break;
+ if (!decl)
+ decl = REG_EXPR (reg);
+ if (REG_EXPR (reg) != decl)
+ break;
+ if (REG_OFFSET (reg) < offset)
+ offset = REG_OFFSET (reg);
+ }
+
+ if (i == len)
+ {
+ *declp = decl;
+ *offsetp = offset;
+ return true;
+ }
+ }
else if (MEM_P (rtl))
{
if (MEM_ATTRS (rtl))
@@ -9550,6 +9594,28 @@ vt_add_function_parameter (tree parm)
p.outgoing = incoming;
vec_safe_push (windowed_parm_regs, p);
}
+ else if (GET_CODE (incoming) == PARALLEL)
+ {
+ rtx outgoing
+ = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (XVECLEN (incoming, 0)));
+ int i;
+
+ for (i = 0; i < XVECLEN (incoming, 0); i++)
+ {
+ rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
+ parm_reg_t p;
+ p.incoming = reg;
+ reg = gen_rtx_REG_offset (reg, GET_MODE (reg),
+ OUTGOING_REGNO (REGNO (reg)), 0);
+ p.outgoing = reg;
+ XVECEXP (outgoing, 0, i)
+ = gen_rtx_EXPR_LIST (VOIDmode, reg,
+ XEXP (XVECEXP (incoming, 0, i), 1));
+ vec_safe_push (windowed_parm_regs, p);
+ }
+
+ incoming = outgoing;
+ }
else if (MEM_P (incoming)
&& REG_P (XEXP (incoming, 0))
&& HARD_REGISTER_P (XEXP (incoming, 0)))
@@ -9683,6 +9749,20 @@ vt_add_function_parameter (tree parm)
}
}
}
+ else if (GET_CODE (incoming) == PARALLEL && !dv_onepart_p (dv))
+ {
+ int i;
+
+ for (i = 0; i < XVECLEN (incoming, 0); i++)
+ {
+ rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
+ offset = REG_OFFSET (reg);
+ gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
+ attrs_list_insert (&out->regs[REGNO (reg)], dv, offset, reg);
+ set_variable_part (out, reg, dv, offset,
+ VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+ }
+ }
else if (MEM_P (incoming))
{
incoming = var_lowpart (mode, incoming);