diff options
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 66 |
1 files changed, 65 insertions, 1 deletions
@@ -41,10 +41,19 @@ along with GCC; see the file COPYING3. If not see #include "regs.h" #include "hard-reg-set.h" #include "except.h" -#include "input.h" #include "function.h" #include "insn-config.h" #include "insn-attr.h" +#include "hashtab.h" +#include "statistics.h" +#include "real.h" +#include "fixed-value.h" +#include "expmed.h" +#include "dojump.h" +#include "explow.h" +#include "calls.h" +#include "emit-rtl.h" +#include "stmt.h" /* Include expr.h after insn-config.h so we get HAVE_conditional_move. */ #include "expr.h" #include "insn-codes.h" @@ -173,6 +182,8 @@ static void emit_single_push_insn (machine_mode, rtx, tree); #endif static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx, int); static rtx const_vector_from_tree (tree); +static tree tree_expr_size (const_tree); +static HOST_WIDE_INT int_expr_size (tree); /* This is run to set up which modes can be used @@ -11438,4 +11449,57 @@ get_personality_function (tree decl) return XEXP (DECL_RTL (personality), 0); } +/* Returns a tree for the size of EXP in bytes. */ + +static tree +tree_expr_size (const_tree exp) +{ + if (DECL_P (exp) + && DECL_SIZE_UNIT (exp) != 0) + return DECL_SIZE_UNIT (exp); + else + return size_in_bytes (TREE_TYPE (exp)); +} + +/* Return an rtx for the size in bytes of the value of EXP. */ + +rtx +expr_size (tree exp) +{ + tree size; + + if (TREE_CODE (exp) == WITH_SIZE_EXPR) + size = TREE_OPERAND (exp, 1); + else + { + size = tree_expr_size (exp); + gcc_assert (size); + gcc_assert (size == SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, exp)); + } + + return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), EXPAND_NORMAL); +} + +/* Return a wide integer for the size in bytes of the value of EXP, or -1 + if the size can vary or is larger than an integer. */ + +static HOST_WIDE_INT +int_expr_size (tree exp) +{ + tree size; + + if (TREE_CODE (exp) == WITH_SIZE_EXPR) + size = TREE_OPERAND (exp, 1); + else + { + size = tree_expr_size (exp); + gcc_assert (size); + } + + if (size == 0 || !tree_fits_shwi_p (size)) + return -1; + + return tree_to_shwi (size); +} + #include "gt-expr.h" |