re PR target/34641 (ICE in reload_cse_simplify_operands, at postreload.c:395)
2008-01-10 Andreas Krebbel <krebbel1@de.ibm.com> PR middle-end/34641 * reload.c (push_reload): Add assertions. All constants from reg_equiv_constant should have been used for replacing the respective pseudo earlier. (find_reloads_address): Invoke find_reloads_address_part for constant taken from the reg_equiv_constant array. 2008-01-10 Andreas Krebbel <krebbel1@de.ibm.com> PR middle-end/34641 * g++.dg/torture/pr34641.C: New testcase. From-SVN: r131445
This commit is contained in:
parent
71ae85578b
commit
90d12f1f04
|
@ -1,3 +1,12 @@
|
|||
2008-01-10 Andreas Krebbel <krebbel1@de.ibm.com>
|
||||
|
||||
PR middle-end/34641
|
||||
* reload.c (push_reload): Add assertions. All constants from
|
||||
reg_equiv_constant should have been used for replacing the respective
|
||||
pseudo earlier.
|
||||
(find_reloads_address): Invoke find_reloads_address_part for
|
||||
constant taken from the reg_equiv_constant array.
|
||||
|
||||
2008-01-10 Steven Bosscher <stevenb.gcc@gmail.com>
|
||||
|
||||
* tree-ssa-sccvn.h (struct vn_ssa_aux): Make the most accessed
|
||||
|
|
43
gcc/reload.c
43
gcc/reload.c
|
@ -922,29 +922,33 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
|
|||
if (outmode == VOIDmode && out != 0)
|
||||
outmode = GET_MODE (out);
|
||||
|
||||
/* If IN is a pseudo register everywhere-equivalent to a constant, and
|
||||
it is not in a hard register, reload straight from the constant,
|
||||
since we want to get rid of such pseudo registers.
|
||||
Often this is done earlier, but not always in find_reloads_address. */
|
||||
/* If find_reloads and friends until now missed to replace a pseudo
|
||||
with a constant of reg_equiv_constant something went wrong
|
||||
beforehand.
|
||||
Note that it can't simply be done here if we missed it earlier
|
||||
since the constant might need to be pushed into the literal pool
|
||||
and the resulting memref would probably need further
|
||||
reloading. */
|
||||
if (in != 0 && REG_P (in))
|
||||
{
|
||||
int regno = REGNO (in);
|
||||
|
||||
if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
|
||||
&& reg_equiv_constant[regno] != 0)
|
||||
in = reg_equiv_constant[regno];
|
||||
gcc_assert (regno < FIRST_PSEUDO_REGISTER
|
||||
|| reg_renumber[regno] >= 0
|
||||
|| reg_equiv_constant[regno] == NULL_RTX);
|
||||
}
|
||||
|
||||
/* Likewise for OUT. Of course, OUT will never be equivalent to
|
||||
an actual constant, but it might be equivalent to a memory location
|
||||
(in the case of a parameter). */
|
||||
/* reg_equiv_constant only contains constants which are obviously
|
||||
not appropriate as destination. So if we would need to replace
|
||||
the destination pseudo with a constant we are in real
|
||||
trouble. */
|
||||
if (out != 0 && REG_P (out))
|
||||
{
|
||||
int regno = REGNO (out);
|
||||
|
||||
if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
|
||||
&& reg_equiv_constant[regno] != 0)
|
||||
out = reg_equiv_constant[regno];
|
||||
gcc_assert (regno < FIRST_PSEUDO_REGISTER
|
||||
|| reg_renumber[regno] >= 0
|
||||
|| reg_equiv_constant[regno] == NULL_RTX);
|
||||
}
|
||||
|
||||
/* If we have a read-write operand with an address side-effect,
|
||||
|
@ -4772,15 +4776,12 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|
|||
{
|
||||
regno = REGNO (ad);
|
||||
|
||||
/* If the register is equivalent to an invariant expression, substitute
|
||||
the invariant, and eliminate any eliminable register references. */
|
||||
tem = reg_equiv_constant[regno];
|
||||
if (tem != 0
|
||||
&& (tem = eliminate_regs (tem, mode, insn))
|
||||
&& strict_memory_address_p (mode, tem))
|
||||
if (reg_equiv_constant[regno] != 0)
|
||||
{
|
||||
*loc = ad = tem;
|
||||
return 0;
|
||||
find_reloads_address_part (reg_equiv_constant[regno], loc,
|
||||
base_reg_class (mode, MEM, SCRATCH),
|
||||
GET_MODE (ad), opnum, type, ind_levels);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tem = reg_equiv_memory_loc[regno];
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2008-01-10 Andreas Krebbel <krebbel1@de.ibm.com>
|
||||
|
||||
PR middle-end/34641
|
||||
* g++.dg/torture/pr34641.C: New testcase.
|
||||
|
||||
2008-01-10 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/34651
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
// { dg-require-effective-target fpic }
|
||||
// { dg-options "-fPIC" }
|
||||
// { dg-do compile }
|
||||
|
||||
|
||||
typedef long unsigned int size_t;
|
||||
extern "C" void *
|
||||
malloc (size_t __size)
|
||||
throw () __attribute__ ((__malloc__));
|
||||
namespace std __attribute__ ((__visibility__ ("default")))
|
||||
{
|
||||
using::size_t;
|
||||
}
|
||||
inline void *operator
|
||||
new (std::size_t, void *__p)
|
||||
throw ()
|
||||
{
|
||||
return __p;
|
||||
}
|
||||
template < class _T1, class _T2 > struct pair
|
||||
{
|
||||
_T1 first;
|
||||
_T2 second;
|
||||
pair (const _T1 & __a, const _T2 & __b):first (__a), second (__b)
|
||||
{
|
||||
}
|
||||
template < class _U1, class _U2 >
|
||||
pair (const pair < _U1, _U2 > &__p):first (__p.first), second (__p.second)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template < class _T1, class _T2 >
|
||||
inline pair < _T1, _T2 > make_pair (_T1 __x, _T2 __y)
|
||||
{
|
||||
return pair < _T1, _T2 > (__x, __y);
|
||||
}
|
||||
template < typename _Tp > inline const _Tp &
|
||||
max (const _Tp & __a, const _Tp & __b)
|
||||
{
|
||||
}
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned long int uintptr_t;
|
||||
typedef uint16_t UChar;
|
||||
namespace std __attribute__ ((__visibility__ ("default")))
|
||||
{
|
||||
struct __numeric_limits_base
|
||||
{
|
||||
};
|
||||
template < typename _Tp > struct numeric_limits:public __numeric_limits_base
|
||||
{
|
||||
static _Tp max () throw ()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template < typename T > class VectorBufferBase
|
||||
{
|
||||
public:
|
||||
void allocateBuffer (size_t newCapacity)
|
||||
{
|
||||
if (newCapacity > std::numeric_limits < size_t >::max () / sizeof (T))
|
||||
*(int *) (uintptr_t) 0xbbadbeef = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, size_t inlineCapacity > class VectorBuffer;
|
||||
template < typename T > class VectorBuffer < T, 0 >:private VectorBufferBase <
|
||||
T >
|
||||
{
|
||||
typedef VectorBufferBase < T > Base;
|
||||
using Base::allocateBuffer;
|
||||
};
|
||||
|
||||
template < typename T, size_t inlineCapacity = 0 > class Vector
|
||||
{
|
||||
typedef VectorBuffer < T, inlineCapacity > Impl;
|
||||
public:
|
||||
typedef T *iterator;
|
||||
size_t size () const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
size_t capacity () const
|
||||
{
|
||||
}
|
||||
iterator begin ()
|
||||
{
|
||||
}
|
||||
iterator end ()
|
||||
{
|
||||
return begin () + m_size;
|
||||
}
|
||||
void shrink (size_t size);
|
||||
void reserveCapacity (size_t newCapacity);
|
||||
void clear ()
|
||||
{
|
||||
shrink (0);
|
||||
}
|
||||
template < typename U > void append (const U &);
|
||||
void expandCapacity (size_t newMinCapacity);
|
||||
template < typename U > U * expandCapacity (size_t newMinCapacity, U *);
|
||||
size_t m_size;
|
||||
Impl m_impl;
|
||||
};
|
||||
template < typename T, size_t inlineCapacity >
|
||||
void Vector < T, inlineCapacity >::expandCapacity (size_t newMinCapacity)
|
||||
{
|
||||
reserveCapacity (max
|
||||
(newMinCapacity,
|
||||
max (static_cast < size_t > (16),
|
||||
capacity () + capacity () / 4 + 1)));
|
||||
}
|
||||
|
||||
template < typename T, size_t inlineCapacity >
|
||||
template < typename U >
|
||||
inline U * Vector < T,
|
||||
inlineCapacity >::expandCapacity (size_t newMinCapacity, U * ptr)
|
||||
{
|
||||
expandCapacity (newMinCapacity);
|
||||
}
|
||||
template < typename T, size_t inlineCapacity >
|
||||
void Vector < T, inlineCapacity >::reserveCapacity (size_t newCapacity)
|
||||
{
|
||||
m_impl.allocateBuffer (newCapacity);
|
||||
}
|
||||
template < typename T, size_t inlineCapacity >
|
||||
template < typename U >
|
||||
inline void Vector < T, inlineCapacity >::append (const U & val)
|
||||
{
|
||||
const U *ptr = &val;
|
||||
if (size () == capacity ())
|
||||
ptr = expandCapacity (size () + 1, ptr);
|
||||
new (end ())T (*ptr);
|
||||
}
|
||||
|
||||
class Range;
|
||||
class TextIterator
|
||||
{
|
||||
public:
|
||||
explicit TextIterator (const Range *,
|
||||
bool emitCharactersBetweenAllVisiblePositions =
|
||||
false);
|
||||
bool atEnd () const
|
||||
{
|
||||
}
|
||||
void advance ();
|
||||
int length () const
|
||||
{
|
||||
}
|
||||
};
|
||||
UChar *
|
||||
plainTextToMallocAllocatedBuffer (const Range * r, unsigned &bufferLength)
|
||||
{
|
||||
static const unsigned cMaxSegmentSize = 1 << 16;
|
||||
typedef pair < UChar *, unsigned >TextSegment;
|
||||
Vector < TextSegment > *textSegments = 0;
|
||||
Vector < UChar > textBuffer;
|
||||
for (TextIterator it (r); !it.atEnd (); it.advance ())
|
||||
{
|
||||
if (textBuffer.size ()
|
||||
&& textBuffer.size () + it.length () > cMaxSegmentSize)
|
||||
{
|
||||
UChar *newSegmentBuffer =
|
||||
static_cast <
|
||||
UChar * >(malloc (textBuffer.size () * sizeof (UChar)));
|
||||
if (!textSegments)
|
||||
textSegments = new Vector < TextSegment >;
|
||||
textSegments->
|
||||
append (make_pair (newSegmentBuffer, textBuffer.size ()));
|
||||
textBuffer.clear ();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue