aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-object-size.c
diff options
context:
space:
mode:
authorRoberto Costa <roberto.costa@st.com>2007-01-08 13:52:42 +0000
committerRoberto Costa <robc@gcc.gnu.org>2007-01-08 13:52:42 +0000
commitf255541fb7bdd1b1da1a8c661967021164fa515b (patch)
treedcb7083fc910095eb2aebe069e3d37af32897742 /gcc/tree-object-size.c
parentfeb8476ac4b9534b99b222ff42ea40900fd7bfe3 (diff)
downloadgcc-f255541fb7bdd1b1da1a8c661967021164fa515b.zip
gcc-f255541fb7bdd1b1da1a8c661967021164fa515b.tar.gz
gcc-f255541fb7bdd1b1da1a8c661967021164fa515b.tar.bz2
Better handling of COND_EXPRs in rhs
From-SVN: r120581
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 7ae87d6..a93464b 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;