diff options
author | robc <robc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-08 13:52:42 +0000 |
---|---|---|
committer | robc <robc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-08 13:52:42 +0000 |
commit | ec0fa5135c41c01378cd977c6c0dd620b8a940fd (patch) | |
tree | dcb7083fc910095eb2aebe069e3d37af32897742 /gcc/tree-object-size.c | |
parent | 24838d3fed690e66437b90c4ff5944976dcfee6d (diff) | |
download | gcc-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.c | 38 |
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; |