aboutsummaryrefslogtreecommitdiff
path: root/gcc/explow.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/explow.c')
-rw-r--r--gcc/explow.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/gcc/explow.c b/gcc/explow.c
index 7a770ee897c..97435a703b9 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "insn-config.h"
#include "ggc.h"
#include "recog.h"
+#include "langhooks.h"
static rtx break_out_memory_refs PARAMS ((rtx));
static void emit_stack_probe PARAMS ((rtx));
@@ -285,20 +286,33 @@ rtx
expr_size (exp)
tree exp;
{
- tree size;
-
- if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
- && DECL_SIZE_UNIT (exp) != 0)
- size = DECL_SIZE_UNIT (exp);
- else
- size = size_in_bytes (TREE_TYPE (exp));
+ tree size = (*lang_hooks.expr_size) (exp);
if (TREE_CODE (size) != INTEGER_CST
&& contains_placeholder_p (size))
size = build (WITH_RECORD_EXPR, sizetype, size, exp);
return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
+}
+
+/* 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. */
+
+HOST_WIDE_INT
+int_expr_size (exp)
+ tree exp;
+{
+ tree t = (*lang_hooks.expr_size) (exp);
+
+ if (t == 0
+ || TREE_CODE (t) != INTEGER_CST
+ || TREE_OVERFLOW (t)
+ || TREE_INT_CST_HIGH (t) != 0
+ /* If the result would appear negative, it's too big to represent. */
+ || (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
+ return -1;
+ return TREE_INT_CST_LOW (t);
}
/* Return a copy of X in which all memory references