mirror of git://gcc.gnu.org/git/gcc.git
re PR rtl-optimization/55717 (ICE in form_sum, at reload.c:5400)
PR debug/55717 * rtlhooks-def.h (RTL_HOOKS_GEN_LOWPART_NO_EMIT): Define to gen_lowpart_if_possible. (gen_lowpart_no_emit_general): Remove prototype. * rtlhooks.c (gen_lowpart_no_emit_general): Removed. * simplify-rtx.c (simplify_unary_operation_1, simplify_binary_operation_1): Continue simplifying if rtl_hooks.gen_lowpart_no_emit returns NULL_RTX. * dwarf2out.c (mem_loc_descriptor) <case TRUNCATE>: Handle truncation like lowpart SUBREG. * testsuite/g++.dg/opt/pr55717.C: New test. From-SVN: r194575
This commit is contained in:
parent
07146f23bc
commit
76bd29f63c
|
|
@ -1,3 +1,16 @@
|
||||||
|
2012-12-18 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR debug/55717
|
||||||
|
* rtlhooks-def.h (RTL_HOOKS_GEN_LOWPART_NO_EMIT): Define to
|
||||||
|
gen_lowpart_if_possible.
|
||||||
|
(gen_lowpart_no_emit_general): Remove prototype.
|
||||||
|
* rtlhooks.c (gen_lowpart_no_emit_general): Removed.
|
||||||
|
* simplify-rtx.c (simplify_unary_operation_1,
|
||||||
|
simplify_binary_operation_1): Continue simplifying if
|
||||||
|
rtl_hooks.gen_lowpart_no_emit returns NULL_RTX.
|
||||||
|
* dwarf2out.c (mem_loc_descriptor) <case TRUNCATE>: Handle
|
||||||
|
truncation like lowpart SUBREG.
|
||||||
|
|
||||||
2012-12-17 Gerald Pfeifer <gerald@pfeifer.com>
|
2012-12-17 Gerald Pfeifer <gerald@pfeifer.com>
|
||||||
|
|
||||||
* doc/contrib.texi (Contributors): Update Kaveh Ghazi's entry;
|
* doc/contrib.texi (Contributors): Update Kaveh Ghazi's entry;
|
||||||
|
|
|
||||||
|
|
@ -11840,6 +11840,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
|
||||||
dw_loc_descr_ref mem_loc_result = NULL;
|
dw_loc_descr_ref mem_loc_result = NULL;
|
||||||
enum dwarf_location_atom op;
|
enum dwarf_location_atom op;
|
||||||
dw_loc_descr_ref op0, op1;
|
dw_loc_descr_ref op0, op1;
|
||||||
|
rtx inner = NULL_RTX;
|
||||||
|
|
||||||
if (mode == VOIDmode)
|
if (mode == VOIDmode)
|
||||||
mode = GET_MODE (rtl);
|
mode = GET_MODE (rtl);
|
||||||
|
|
@ -11869,35 +11870,39 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
|
||||||
contains the given subreg. */
|
contains the given subreg. */
|
||||||
if (!subreg_lowpart_p (rtl))
|
if (!subreg_lowpart_p (rtl))
|
||||||
break;
|
break;
|
||||||
|
inner = SUBREG_REG (rtl);
|
||||||
|
case TRUNCATE:
|
||||||
|
if (inner == NULL_RTX)
|
||||||
|
inner = XEXP (rtl, 0);
|
||||||
if (GET_MODE_CLASS (mode) == MODE_INT
|
if (GET_MODE_CLASS (mode) == MODE_INT
|
||||||
&& GET_MODE_CLASS (GET_MODE (SUBREG_REG (rtl))) == MODE_INT
|
&& GET_MODE_CLASS (GET_MODE (inner)) == MODE_INT
|
||||||
&& (GET_MODE_SIZE (mode) <= DWARF2_ADDR_SIZE
|
&& (GET_MODE_SIZE (mode) <= DWARF2_ADDR_SIZE
|
||||||
#ifdef POINTERS_EXTEND_UNSIGNED
|
#ifdef POINTERS_EXTEND_UNSIGNED
|
||||||
|| (mode == Pmode && mem_mode != VOIDmode)
|
|| (mode == Pmode && mem_mode != VOIDmode)
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (rtl))) <= DWARF2_ADDR_SIZE)
|
&& GET_MODE_SIZE (GET_MODE (inner)) <= DWARF2_ADDR_SIZE)
|
||||||
{
|
{
|
||||||
mem_loc_result = mem_loc_descriptor (SUBREG_REG (rtl),
|
mem_loc_result = mem_loc_descriptor (inner,
|
||||||
GET_MODE (SUBREG_REG (rtl)),
|
GET_MODE (inner),
|
||||||
mem_mode, initialized);
|
mem_mode, initialized);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dwarf_strict)
|
if (dwarf_strict)
|
||||||
break;
|
break;
|
||||||
if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (rtl))))
|
if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (inner)))
|
||||||
break;
|
break;
|
||||||
if (GET_MODE_SIZE (mode) != GET_MODE_SIZE (GET_MODE (SUBREG_REG (rtl)))
|
if (GET_MODE_SIZE (mode) != GET_MODE_SIZE (GET_MODE (inner))
|
||||||
&& (GET_MODE_CLASS (mode) != MODE_INT
|
&& (GET_MODE_CLASS (mode) != MODE_INT
|
||||||
|| GET_MODE_CLASS (GET_MODE (SUBREG_REG (rtl))) != MODE_INT))
|
|| GET_MODE_CLASS (GET_MODE (inner)) != MODE_INT))
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dw_die_ref type_die;
|
dw_die_ref type_die;
|
||||||
dw_loc_descr_ref cvt;
|
dw_loc_descr_ref cvt;
|
||||||
|
|
||||||
mem_loc_result = mem_loc_descriptor (SUBREG_REG (rtl),
|
mem_loc_result = mem_loc_descriptor (inner,
|
||||||
GET_MODE (SUBREG_REG (rtl)),
|
GET_MODE (inner),
|
||||||
mem_mode, initialized);
|
mem_mode, initialized);
|
||||||
if (mem_loc_result == NULL)
|
if (mem_loc_result == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
@ -11909,7 +11914,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (GET_MODE_SIZE (mode)
|
if (GET_MODE_SIZE (mode)
|
||||||
!= GET_MODE_SIZE (GET_MODE (SUBREG_REG (rtl))))
|
!= GET_MODE_SIZE (GET_MODE (inner)))
|
||||||
cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
|
cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
|
||||||
else
|
else
|
||||||
cvt = new_loc_descr (DW_OP_GNU_reinterpret, 0, 0);
|
cvt = new_loc_descr (DW_OP_GNU_reinterpret, 0, 0);
|
||||||
|
|
@ -12666,7 +12671,6 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMPARE:
|
case COMPARE:
|
||||||
case TRUNCATE:
|
|
||||||
/* In theory, we could implement the above. */
|
/* In theory, we could implement the above. */
|
||||||
/* DWARF cannot represent the unsigned compare operations
|
/* DWARF cannot represent the unsigned compare operations
|
||||||
natively. */
|
natively. */
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* Default macros to initialize an rtl_hooks data structure.
|
/* Default macros to initialize an rtl_hooks data structure.
|
||||||
Copyright 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
|
Copyright 2004, 2005, 2007, 2008, 2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GCC.
|
This file is part of GCC.
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "rtl.h"
|
#include "rtl.h"
|
||||||
|
|
||||||
#define RTL_HOOKS_GEN_LOWPART gen_lowpart_general
|
#define RTL_HOOKS_GEN_LOWPART gen_lowpart_general
|
||||||
#define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_no_emit_general
|
#define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_if_possible
|
||||||
#define RTL_HOOKS_REG_NONZERO_REG_BITS reg_nonzero_bits_general
|
#define RTL_HOOKS_REG_NONZERO_REG_BITS reg_nonzero_bits_general
|
||||||
#define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES reg_num_sign_bit_copies_general
|
#define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES reg_num_sign_bit_copies_general
|
||||||
#define RTL_HOOKS_REG_TRUNCATED_TO_MODE reg_truncated_to_mode_general
|
#define RTL_HOOKS_REG_TRUNCATED_TO_MODE reg_truncated_to_mode_general
|
||||||
|
|
@ -38,7 +38,6 @@ along with GCC; see the file COPYING3. If not see
|
||||||
}
|
}
|
||||||
|
|
||||||
extern rtx gen_lowpart_general (enum machine_mode, rtx);
|
extern rtx gen_lowpart_general (enum machine_mode, rtx);
|
||||||
extern rtx gen_lowpart_no_emit_general (enum machine_mode, rtx);
|
|
||||||
extern rtx reg_nonzero_bits_general (const_rtx, enum machine_mode, const_rtx,
|
extern rtx reg_nonzero_bits_general (const_rtx, enum machine_mode, const_rtx,
|
||||||
enum machine_mode,
|
enum machine_mode,
|
||||||
unsigned HOST_WIDE_INT,
|
unsigned HOST_WIDE_INT,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
/* Generic hooks for the RTL middle-end.
|
/* Generic hooks for the RTL middle-end.
|
||||||
Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
|
Copyright (C) 2004, 2005, 2007, 2008, 2009, 2011, 2012
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GCC.
|
This file is part of GCC.
|
||||||
|
|
||||||
|
|
@ -79,18 +80,6 @@ gen_lowpart_general (enum machine_mode mode, rtx x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Similar to gen_lowpart, but cannot emit any instruction via
|
|
||||||
copy_to_reg or force_reg. Mainly used in simplify-rtx.c. */
|
|
||||||
rtx
|
|
||||||
gen_lowpart_no_emit_general (enum machine_mode mode, rtx x)
|
|
||||||
{
|
|
||||||
rtx result = gen_lowpart_if_possible (mode, x);
|
|
||||||
if (result)
|
|
||||||
return result;
|
|
||||||
else
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtx
|
rtx
|
||||||
reg_num_sign_bit_copies_general (const_rtx x ATTRIBUTE_UNUSED,
|
reg_num_sign_bit_copies_general (const_rtx x ATTRIBUTE_UNUSED,
|
||||||
enum machine_mode mode ATTRIBUTE_UNUSED,
|
enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||||
|
|
|
||||||
|
|
@ -873,7 +873,9 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
|
||||||
simplify_gen_unary (NOT, inner_mode, const1_rtx,
|
simplify_gen_unary (NOT, inner_mode, const1_rtx,
|
||||||
inner_mode),
|
inner_mode),
|
||||||
XEXP (SUBREG_REG (op), 1));
|
XEXP (SUBREG_REG (op), 1));
|
||||||
return rtl_hooks.gen_lowpart_no_emit (mode, x);
|
temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
|
||||||
|
if (temp)
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply De Morgan's laws to reduce number of patterns for machines
|
/* Apply De Morgan's laws to reduce number of patterns for machines
|
||||||
|
|
@ -1029,7 +1031,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
|
||||||
if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
|
if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
|
||||||
{
|
{
|
||||||
if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
|
if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
|
||||||
return rtl_hooks.gen_lowpart_no_emit (mode, op);
|
{
|
||||||
|
temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
|
||||||
|
if (temp)
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
/* We can't handle truncation to a partial integer mode here
|
/* We can't handle truncation to a partial integer mode here
|
||||||
because we don't know the real bitsize of the partial
|
because we don't know the real bitsize of the partial
|
||||||
integer mode. */
|
integer mode. */
|
||||||
|
|
@ -1048,7 +1054,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
|
||||||
if (GET_MODE_NUNITS (mode) == 1
|
if (GET_MODE_NUNITS (mode) == 1
|
||||||
&& (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
|
&& (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
|
||||||
|| truncated_to_mode (mode, op)))
|
|| truncated_to_mode (mode, op)))
|
||||||
return rtl_hooks.gen_lowpart_no_emit (mode, op);
|
{
|
||||||
|
temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
|
||||||
|
if (temp)
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
/* A truncate of a comparison can be replaced with a subreg if
|
/* A truncate of a comparison can be replaced with a subreg if
|
||||||
STORE_FLAG_VALUE permits. This is like the previous test,
|
STORE_FLAG_VALUE permits. This is like the previous test,
|
||||||
|
|
@ -1057,7 +1067,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
|
||||||
if (HWI_COMPUTABLE_MODE_P (mode)
|
if (HWI_COMPUTABLE_MODE_P (mode)
|
||||||
&& COMPARISON_P (op)
|
&& COMPARISON_P (op)
|
||||||
&& (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
|
&& (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
|
||||||
return rtl_hooks.gen_lowpart_no_emit (mode, op);
|
{
|
||||||
|
temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
|
||||||
|
if (temp)
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
/* A truncate of a memory is just loading the low part of the memory
|
/* A truncate of a memory is just loading the low part of the memory
|
||||||
if we are not changing the meaning of the address. */
|
if we are not changing the meaning of the address. */
|
||||||
|
|
@ -1065,7 +1079,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
|
||||||
&& !VECTOR_MODE_P (mode)
|
&& !VECTOR_MODE_P (mode)
|
||||||
&& !MEM_VOLATILE_P (op)
|
&& !MEM_VOLATILE_P (op)
|
||||||
&& !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
|
&& !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
|
||||||
return rtl_hooks.gen_lowpart_no_emit (mode, op);
|
{
|
||||||
|
temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
|
||||||
|
if (temp)
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1298,7 +1316,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
|
||||||
&& SUBREG_PROMOTED_VAR_P (op)
|
&& SUBREG_PROMOTED_VAR_P (op)
|
||||||
&& ! SUBREG_PROMOTED_UNSIGNED_P (op)
|
&& ! SUBREG_PROMOTED_UNSIGNED_P (op)
|
||||||
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
|
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
|
||||||
return rtl_hooks.gen_lowpart_no_emit (mode, op);
|
{
|
||||||
|
temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
|
||||||
|
if (temp)
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
/* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
|
/* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
|
||||||
(sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
|
(sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
|
||||||
|
|
@ -1330,9 +1352,10 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
|
||||||
{
|
{
|
||||||
rtx inner =
|
rtx inner =
|
||||||
rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
|
rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
|
||||||
return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
|
if (inner)
|
||||||
? SIGN_EXTEND : ZERO_EXTEND,
|
return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
|
||||||
mode, inner, tmode);
|
? SIGN_EXTEND : ZERO_EXTEND,
|
||||||
|
mode, inner, tmode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1360,7 +1383,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
|
||||||
&& SUBREG_PROMOTED_VAR_P (op)
|
&& SUBREG_PROMOTED_VAR_P (op)
|
||||||
&& SUBREG_PROMOTED_UNSIGNED_P (op) > 0
|
&& SUBREG_PROMOTED_UNSIGNED_P (op) > 0
|
||||||
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
|
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
|
||||||
return rtl_hooks.gen_lowpart_no_emit (mode, op);
|
{
|
||||||
|
temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
|
||||||
|
if (temp)
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
/* Extending a widening multiplication should be canonicalized to
|
/* Extending a widening multiplication should be canonicalized to
|
||||||
a wider widening multiplication. */
|
a wider widening multiplication. */
|
||||||
|
|
@ -1425,7 +1452,8 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
|
||||||
{
|
{
|
||||||
rtx inner =
|
rtx inner =
|
||||||
rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
|
rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
|
||||||
return simplify_gen_unary (ZERO_EXTEND, mode, inner, tmode);
|
if (inner)
|
||||||
|
return simplify_gen_unary (ZERO_EXTEND, mode, inner, tmode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3095,7 +3123,11 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
|
||||||
}
|
}
|
||||||
/* x/1 is x. */
|
/* x/1 is x. */
|
||||||
if (trueop1 == CONST1_RTX (mode))
|
if (trueop1 == CONST1_RTX (mode))
|
||||||
return rtl_hooks.gen_lowpart_no_emit (mode, op0);
|
{
|
||||||
|
tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
|
||||||
|
if (tem)
|
||||||
|
return tem;
|
||||||
|
}
|
||||||
/* Convert divide by power of two into shift. */
|
/* Convert divide by power of two into shift. */
|
||||||
if (CONST_INT_P (trueop1)
|
if (CONST_INT_P (trueop1)
|
||||||
&& (val = exact_log2 (UINTVAL (trueop1))) > 0)
|
&& (val = exact_log2 (UINTVAL (trueop1))) > 0)
|
||||||
|
|
@ -3154,12 +3186,17 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
|
||||||
}
|
}
|
||||||
/* x/1 is x. */
|
/* x/1 is x. */
|
||||||
if (trueop1 == CONST1_RTX (mode))
|
if (trueop1 == CONST1_RTX (mode))
|
||||||
return rtl_hooks.gen_lowpart_no_emit (mode, op0);
|
{
|
||||||
|
tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
|
||||||
|
if (tem)
|
||||||
|
return tem;
|
||||||
|
}
|
||||||
/* x/-1 is -x. */
|
/* x/-1 is -x. */
|
||||||
if (trueop1 == constm1_rtx)
|
if (trueop1 == constm1_rtx)
|
||||||
{
|
{
|
||||||
rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
|
rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
|
||||||
return simplify_gen_unary (NEG, mode, x, mode);
|
if (x)
|
||||||
|
return simplify_gen_unary (NEG, mode, x, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2012-12-18 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR debug/55717
|
||||||
|
* testsuite/g++.dg/opt/pr55717.C: New test.
|
||||||
|
|
||||||
2012-12-17 Andrew Stubbs <ams@codesourcery.com>
|
2012-12-17 Andrew Stubbs <ams@codesourcery.com>
|
||||||
Ulrich Weigand <ulrich.weigand@linaro.org>
|
Ulrich Weigand <ulrich.weigand@linaro.org>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
// PR debug/55717
|
||||||
|
// { dg-do compile }
|
||||||
|
// { dg-options "-O -g" }
|
||||||
|
|
||||||
|
struct DebugOnly {};
|
||||||
|
template <class T>
|
||||||
|
struct StripConst { typedef T result; };
|
||||||
|
class TempAllocPolicy {};
|
||||||
|
template <class T>
|
||||||
|
class HashTableEntry
|
||||||
|
{
|
||||||
|
unsigned keyHash;
|
||||||
|
template <class, class, class>
|
||||||
|
friend class HashTable;
|
||||||
|
T t;
|
||||||
|
void setLive (unsigned hn) { keyHash = hn; }
|
||||||
|
};
|
||||||
|
template <class T, class HashPolicy, class>
|
||||||
|
struct HashTable
|
||||||
|
{
|
||||||
|
typedef typename HashPolicy::KeyType Key;
|
||||||
|
typedef typename HashPolicy::Lookup Lookup;
|
||||||
|
typedef HashTableEntry <T> Entry;
|
||||||
|
struct Range
|
||||||
|
{
|
||||||
|
Range () {}
|
||||||
|
Entry *cur, end;
|
||||||
|
bool empty () { return false; }
|
||||||
|
T front () { return T (); }
|
||||||
|
};
|
||||||
|
struct Enum : public Range
|
||||||
|
{
|
||||||
|
HashTable table;
|
||||||
|
bool removed;
|
||||||
|
template <class Map>
|
||||||
|
Enum (Map map) : Range (map.all ()), table (map.impl), removed () {}
|
||||||
|
void rekeyFront (Lookup l, Key)
|
||||||
|
{
|
||||||
|
T t = this->cur->t;
|
||||||
|
table.putNewInfallible (l, t);
|
||||||
|
}
|
||||||
|
void rekeyFront (Key k)
|
||||||
|
{
|
||||||
|
rekeyFront (k, k);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
unsigned entryCount;
|
||||||
|
unsigned sCollisionBit;
|
||||||
|
unsigned prepareHash (Lookup l)
|
||||||
|
{
|
||||||
|
unsigned keyHash (HashPolicy::hash (l));
|
||||||
|
return keyHash & sCollisionBit;
|
||||||
|
}
|
||||||
|
static Entry *entryp;
|
||||||
|
Entry *findFreeEntry (unsigned) { return entryp; }
|
||||||
|
void putNewInfallible (Lookup l, T)
|
||||||
|
{
|
||||||
|
unsigned keyHash = prepareHash (l);
|
||||||
|
Entry *entry = findFreeEntry (keyHash);
|
||||||
|
entry->setLive (keyHash);
|
||||||
|
entryCount++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <class Key>
|
||||||
|
struct HashMapEntry { Key key; };
|
||||||
|
template <class Key, class Value, class HashPolicy = DebugOnly, class AllocPolicy = TempAllocPolicy>
|
||||||
|
struct HashMap
|
||||||
|
{
|
||||||
|
typedef HashMapEntry <Key> Entry;
|
||||||
|
struct MapHashPolicy : HashPolicy
|
||||||
|
{
|
||||||
|
typedef Key KeyType;
|
||||||
|
};
|
||||||
|
typedef HashTable <Entry, MapHashPolicy, AllocPolicy> Impl;
|
||||||
|
Impl impl;
|
||||||
|
typedef typename Impl::Range Range;
|
||||||
|
Range all () { return Range (); }
|
||||||
|
typedef typename Impl::Enum Enum;
|
||||||
|
};
|
||||||
|
class FreeOp;
|
||||||
|
struct AllocationSiteKey;
|
||||||
|
typedef HashMap <AllocationSiteKey, DebugOnly, AllocationSiteKey, TempAllocPolicy> AllocationSiteTable;
|
||||||
|
struct TypeCompartment
|
||||||
|
{
|
||||||
|
AllocationSiteTable *allocationSiteTable;
|
||||||
|
void sweep (FreeOp *);
|
||||||
|
};
|
||||||
|
struct JSScript { unsigned *code; };
|
||||||
|
bool IsScriptMarked (JSScript **);
|
||||||
|
struct AllocationSiteKey
|
||||||
|
{
|
||||||
|
JSScript *script;
|
||||||
|
unsigned offset : 24;
|
||||||
|
int kind;
|
||||||
|
typedef AllocationSiteKey Lookup;
|
||||||
|
static unsigned hash (AllocationSiteKey key) { return (long (key.script->code + key.offset)) ^ key.kind; }
|
||||||
|
};
|
||||||
|
void
|
||||||
|
TypeCompartment::sweep (FreeOp *)
|
||||||
|
{
|
||||||
|
for (AllocationSiteTable::Enum e (*allocationSiteTable); !e.empty ();)
|
||||||
|
{
|
||||||
|
AllocationSiteKey key = e.front ().key;
|
||||||
|
IsScriptMarked (&key.script);
|
||||||
|
e.rekeyFront (key);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue