aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index eb4bb9b..89ca129 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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"