summaryrefslogtreecommitdiff
path: root/gcc/tree-object-size.c
diff options
context:
space:
mode:
authorrobc <robc@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-08 13:52:42 +0000
committerrobc <robc@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-08 13:52:42 +0000
commitec0fa5135c41c01378cd977c6c0dd620b8a940fd (patch)
treedcb7083fc910095eb2aebe069e3d37af32897742 /gcc/tree-object-size.c
parent24838d3fed690e66437b90c4ff5944976dcfee6d (diff)
downloadgcc-ec0fa5135c41c01378cd977c6c0dd620b8a940fd.tar.gz
Better handling of COND_EXPRs in rhs
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120581 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-object-size.c')
-rw-r--r--gcc/tree-object-size.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index 7ae87d67539..a93464b22fa 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -50,6 +50,7 @@ static void expr_object_size (struct object_size_info *, tree, tree);
static bool merge_object_sizes (struct object_size_info *, tree, tree,
unsigned HOST_WIDE_INT);
static bool plus_expr_object_size (struct object_size_info *, tree, tree);
+static bool cond_expr_object_size (struct object_size_info *, tree, tree);
static unsigned int compute_object_sizes (void);
static void init_offset_limit (void);
static void check_for_plus_in_loops (struct object_size_info *, tree);
@@ -621,6 +622,40 @@ plus_expr_object_size (struct object_size_info *osi, tree var, tree value)
}
+/* Compute object_sizes for PTR, defined to VALUE, which is
+ a COND_EXPR. Return true if the object size might need reexamination
+ later. */
+
+static bool
+cond_expr_object_size (struct object_size_info *osi, tree var, tree value)
+{
+ tree then_, else_;
+ int object_size_type = osi->object_size_type;
+ unsigned int varno = SSA_NAME_VERSION (var);
+ bool reexamine = false;
+
+ gcc_assert (TREE_CODE (value) == COND_EXPR);
+
+ if (object_sizes[object_size_type][varno] == unknown[object_size_type])
+ return false;
+
+ then_ = COND_EXPR_THEN (value);
+ else_ = COND_EXPR_ELSE (value);
+
+ if (TREE_CODE (then_) == SSA_NAME)
+ reexamine |= merge_object_sizes (osi, var, then_, 0);
+ else
+ expr_object_size (osi, var, then_);
+
+ if (TREE_CODE (else_) == SSA_NAME)
+ reexamine |= merge_object_sizes (osi, var, else_, 0);
+ else
+ expr_object_size (osi, var, else_);
+
+ return reexamine;
+}
+
+
/* Compute object sizes for VAR.
For ADDR_EXPR an object size is the number of remaining bytes
to the end of the object (where what is considered an object depends on
@@ -711,6 +746,9 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
else if (TREE_CODE (rhs) == PLUS_EXPR)
reexamine = plus_expr_object_size (osi, var, rhs);
+ else if (TREE_CODE (rhs) == COND_EXPR)
+ reexamine = cond_expr_object_size (osi, var, rhs);
+
else
expr_object_size (osi, var, rhs);
break;