Re: locating unsigned type for non-standard precision

2012-04-26 Thread Richard Guenther
On Wed, Apr 25, 2012 at 7:34 PM, Georg-Johann Lay  wrote:
> Georg-Johann Lay wrote:
>> Richard Guenther wrote:
>>> On Tue, Apr 24, 2012 at 7:24 PM, Georg-Johann Lay  wrote:
 Richard Guenther wrote:

>> I've run into another issue supporting a 20-bit integer for which I'd
>> appreciate a hint.  With this code:
>>
>>   typedef long int __attribute__((__a20__)) int20_t;
>>   int20_t xi;
>>   int20_t addit () { xi += 0x54321L; }
>>
>> xi ends up in mode PSImode, which is a MODE_PARTIAL_INT with 20 bits of
>> precision and 32-bit width.
>>
>> convert() notices that, because the constant in the add expression is
>> SImode, there's an SImode add being truncated to a PSImode result, and
>> pushes the truncation down into the operands.
>>
>> The problem is this ends up in convert_to_integer, which detects that the
>> signed operation might overflow so calls unsigned_type_for() to get the
>> unsigned variant.
>>
>> Unfortunately, this ends up in c_common_type_for_size(), which knows 
>> nothing
>> about PSImode, and returns an unsigned type with 32 bits of precision 
>> when
>> asked for one with 20 bits of precision.
> That's expected - this function returns a type that is suitable for 
> holding all
> values, not a type that has necessarily matching precision.  If the caller
> wants such type it needs to verify what the function returned.  Which 
> seems
> to me to be the correct fix for this (premature) optimization in
> convert_to_integer.
>
> Richard.
>
>>   The expression is rewritten with
>> the 32-bit constant integer recast to the 32-bit unsigned type (instead
>> of the 20-bit one it might have used), and infinite recursion results.
 This is already filed as

 http://gcc.gnu.org/PR51527

 It works with 4.8 trunk but crashes with 4.7.
 Did not yet track what changes made it work with 4.8, though.
 Unfortunately, noone remembers :-(

 http://gcc.gnu.org/ml/gcc/2012-03/msg00440.html
>>> I have done changes in this area, trying to remove the type_for_size 
>>> langhook.
>>>
>>> Richard.
>>
>> One apparent change is tree.c:signed_or_unsigned_type_for
>>
>> that changed from 4.7:
>>
>> tree
>> signed_or_unsigned_type_for (int unsignedp, tree type)
>> {
>>   tree t = type;
>>   if (POINTER_TYPE_P (type))
>>     {
>>       /* If the pointer points to the normal address space, use the
>>        size_type_node.  Otherwise use an appropriate size for the pointer
>>        based on the named address space it points to.  */
>>       if (!TYPE_ADDR_SPACE (TREE_TYPE (t)))
>>       t = size_type_node;
>>       else
>>       return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp);
>>     }
>>
>>   if (!INTEGRAL_TYPE_P (t) || TYPE_UNSIGNED (t) == unsignedp)
>>     return t;
>>
>>   return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp);
>> }
>>
>> to 4.8:
>>
>> tree
>> signed_or_unsigned_type_for (int unsignedp, tree type)
>> {
>>   if (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type) == unsignedp)
>>     return type;
>>
>>   if (!INTEGRAL_TYPE_P (type)
>>       && !POINTER_TYPE_P (type))
>>     return NULL_TREE;
>>
>>   return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp);
>> }
>>
>> at 2012-03-12
>>
>> http://gcc.gnu.org/viewcvs?view=revision&revision=185226
>>
>> Is this appropriate to backport?

No, it's not.

>> Or is the preferred solution to override lang_hooks.types.type_for_size in 
>> the
>> backend, if applicable?

Neither.  It is a "lang"-hook, not a target-hook after all.

I already told you what the right fix is - the callers of
type_for_size have to cater
for the returned type to be of different precision.  Btw, I already see it does

/* But now perhaps TYPEX is as wide as INPREC.
   In that case, do nothing special here.
   (Otherwise would recurse infinitely in convert.  */
if (TYPE_PRECISION (typex) != inprec)

Richard.

> Now I have this piece of code that works for 4.7.
>
> I don't like it much, but if there are no plans to otherwise fix PR51527,
> I'd make a patch and propose it as target-specific work-around.
>
> /* Some auxiliary stuff for the AVR-specific built-in 24-bit scalar integer
>   types __int24 and __uint24 to be used in `avr_init_builtins'.  */
>
> static GTY(()) tree avr_int24_type;
> static GTY(()) tree avr_uint24_type;
>
>
> /* Implement `LANG_HOOKS_TYPE_FOR_SIZE'.  */
> /* To avoid infinite recursion in `convert_to_integer' as
>   reported in PR c/51527.  */
>
> static tree (*avr_default_type_for_size)(unsigned int, int);
>
> static tree
> avr_type_for_size (unsigned int bits, int unsignedp)
> {
>  if (bits == 24)
>    return unsignedp ? avr_uint24_type : avr_int24_type;
>
>  return avr_default_type_for_size (bits, unsignedp);
> }
>
>
> static void
> avr_init_builtin_int24 (void)
> {

Re: Question on scan_one_insn in IRA about load parameters from stack slot.

2012-04-26 Thread Bin.Cheng
On Wed, Apr 25, 2012 at 10:46 PM, Vladimir Makarov  wrote:
> On 04/24/2012 11:56 PM, Bin.Cheng wrote:
>>
>> Hi,
>> In scan_one_insn, gcc checks whether an insn loads a parameter from
>> its stack slot, and then
>> record the fact by decrease the memory cost.
>>
>> What I do not understand is the check condition like below checks the
>> REG_EQUIV note, rather than
>> checking memory access using stack pointer directly.
>>
>>   if (set != 0&&  REG_P (SET_DEST (set))&&  MEM_P (SET_SRC (set))
>>
>>       &&  (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != NULL_RTX
>>       &&  ((MEM_P (XEXP (note, 0)))
>>          || (CONSTANT_P (XEXP (note, 0))
>>        &&  targetm.legitimate_constant_p (GET_MODE (SET_DEST (set)),
>>                                                XEXP (note, 0))
>>        &&  REG_N_SETS (REGNO (SET_DEST (set))) == 1)))
>>
>> So what's the connection between REG_EQUIV and stack slot for
>> parameters? I noticed from
>> below dumps of IRA pass, seems the annotated insn is not load
>> parameter from stack, but it is
>> treated as the check condition. Why?
>>
>> Dump of IRA:
>>
>> (insn 121 118 122 6 (set (reg/f:SI 252 [ l_curve ])
>>         (mem/f/c:SI (reg/f:SI 230) [7 l_curve+0 S4 A32]))
>> bezier01/bmark_lite.c:246 186 {*thumb1_movsi_insn}
>>      (expr_list:REG_EQUIV (mem/f/c:SI (reg/f:SI 230) [7 l_curve+0 S4 A32])
>>         (expr_list:REG_EQUAL (mem/f/c:SI (symbol_ref:SI ("l_curve")
>> [flags 0x80]) [7 l_curve+0 S4 A32])
>>             (nil
>>
>>
>> I am not sure if I missed something important, please help. Thanks very
>> much.
>>
> Reload uses equivalent memory (not an allocated stack slot) if the pseudo
> did not get a hard registers.  Therefore the equivalent insns for the pseudo
> (they can be more than one) are not necessary and removed and that decreases
> memory cost.  Many cases contain loading parameters from the stack.  But
> there are a lot of other cases too.
>

Thanks for explaining.

If I understood well, This part of code decreases mem_cost of allocno,
making them prefer memory, rather than register if possible.
This behavior achieves same effect as register re-materialization, right?

I do observe a case in which 11 pseudo allocnos are put in memory
due to this check condition. That hurts reload pass and generates bad
codes. So is it possible to introduce more accurate condition or even
some heuristic information here?

Thanks.

-- 
Best Regards.


Re: Failed access check

2012-04-26 Thread Peter A. Felvegi

On 04/23/2012 08:20 PM, Jonathan Wakely wrote:

On 23 April 2012 18:48, Ian Lance Taylor wrote:

"Peter A. Felvegi"  writes:


Should I file a bug report?

Yes, please.  Thanks.

Please check it's not http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24926 first

Hello,

it seems to be the same issue, quite dated, though.

Regards, Peter



Re: locating unsigned type for non-standard precision

2012-04-26 Thread Georg-Johann Lay
Richard Guenther wrote:
> Georg-Johann Lay wrote:
>> Georg-Johann Lay wrote:
>>> Richard Guenther wrote:
 Georg-Johann Lay wrote:
> [...]
>
> http://gcc.gnu.org/PR51527
>
> It works with 4.8 trunk but crashes with 4.7.
> Did not yet track what changes made it work with 4.8, though.
> Unfortunately, noone remembers :-(
>
> http://gcc.gnu.org/ml/gcc/2012-03/msg00440.html
 I have done changes in this area, trying to remove the type_for_size 
 langhook.

 Richard.
>>> One apparent change is tree.c:signed_or_unsigned_type_for
>>>
>>> that changed [...] at 2012-03-12
>>>
>>> http://gcc.gnu.org/viewcvs?view=revision&revision=185226
>>>
>>> Is this appropriate to backport?
> 
> No, it's not.
> 
>>> Or is the preferred solution to override lang_hooks.types.type_for_size in 
>>> the
>>> backend, if applicable?
> 
> Neither.  It is a "lang"-hook, not a target-hook after all.
> 
> I already told you what the right fix is - the callers of
> type_for_size have to cater
> for the returned type to be of different precision.  Btw, I already see it 
> does
> 
> /* But now perhaps TYPEX is as wide as INPREC.
>In that case, do nothing special here.
>(Otherwise would recurse infinitely in convert.  */
> if (TYPE_PRECISION (typex) != inprec)
> 
> Richard

Would you help me with the code? It's almost impossible to understand the
convert stuff for a noob. I tried TARGET_CONVERT_TO_TYPE

static tree
avr_convert_to_type (tree type, tree expr)
{
  tree xtype = TREE_TYPE (expr);

  /* convert enters infinite recursion for __int24 -> unsigned long
 convertsions.  */

  if (/* From __int24 ... */
  TREE_CODE (xtype) == INTEGER_TYPE
  && TYPE_PRECISION (xtype) == 24
  && !TYPE_UNSIGNED (xtype)
  /* ... to unsigned long.  */
  && TREE_CODE (type) == INTEGER_TYPE
  && TYPE_PRECISION (type) > 24
  && TYPE_UNSIGNED (type))
{
  /* Perform an intermediate conversion:
 __int24 -> long -> unsigned long  */

  /* Signed variant of type */
  tree stype = lang_hooks.types.type_for_mode (TYPE_MODE (type), 0);

  expr = convert (stype, expr);
  //  expr = build1 (CONVERT_EXPR, stype, expr);
  expr = build1 (NOP_EXPR, type, expr);

  return expr;
}

  return NULL_TREE;
}

#undef  TARGET_CONVERT_TO_TYPE
#define TARGET_CONVERT_TO_TYPE avr_convert_to_type


but with no avail. The explicit, intermediate conversion from __int24 to long
does not prevent the infinite recursion.

Johann



Re: locating unsigned type for non-standard precision

2012-04-26 Thread Richard Guenther
On Thu, Apr 26, 2012 at 3:12 PM, Georg-Johann Lay  wrote:
> Richard Guenther wrote:
>> Georg-Johann Lay wrote:
>>> Georg-Johann Lay wrote:
 Richard Guenther wrote:
> Georg-Johann Lay wrote:
>> [...]
>>
>> http://gcc.gnu.org/PR51527
>>
>> It works with 4.8 trunk but crashes with 4.7.
>> Did not yet track what changes made it work with 4.8, though.
>> Unfortunately, noone remembers :-(
>>
>> http://gcc.gnu.org/ml/gcc/2012-03/msg00440.html
> I have done changes in this area, trying to remove the type_for_size 
> langhook.
>
> Richard.
 One apparent change is tree.c:signed_or_unsigned_type_for

 that changed [...] at 2012-03-12

 http://gcc.gnu.org/viewcvs?view=revision&revision=185226

 Is this appropriate to backport?
>>
>> No, it's not.
>>
 Or is the preferred solution to override lang_hooks.types.type_for_size in 
 the
 backend, if applicable?
>>
>> Neither.  It is a "lang"-hook, not a target-hook after all.
>>
>> I already told you what the right fix is - the callers of
>> type_for_size have to cater
>> for the returned type to be of different precision.  Btw, I already see it 
>> does
>>
>>                 /* But now perhaps TYPEX is as wide as INPREC.
>>                    In that case, do nothing special here.
>>                    (Otherwise would recurse infinitely in convert.  */
>>                 if (TYPE_PRECISION (typex) != inprec)
>>
>> Richard
>
> Would you help me with the code? It's almost impossible to understand the
> convert stuff for a noob. I tried TARGET_CONVERT_TO_TYPE
>
> static tree
> avr_convert_to_type (tree type, tree expr)
> {
>  tree xtype = TREE_TYPE (expr);
>
>  /* convert enters infinite recursion for __int24 -> unsigned long
>     convertsions.  */
>
>  if (/* From __int24 ... */
>      TREE_CODE (xtype) == INTEGER_TYPE
>      && TYPE_PRECISION (xtype) == 24
>      && !TYPE_UNSIGNED (xtype)
>      /* ... to unsigned long.  */
>      && TREE_CODE (type) == INTEGER_TYPE
>      && TYPE_PRECISION (type) > 24
>      && TYPE_UNSIGNED (type))
>    {
>      /* Perform an intermediate conversion:
>         __int24 -> long -> unsigned long  */
>
>      /* Signed variant of type */
>      tree stype = lang_hooks.types.type_for_mode (TYPE_MODE (type), 0);
>
>      expr = convert (stype, expr);
>      //      expr = build1 (CONVERT_EXPR, stype, expr);
>      expr = build1 (NOP_EXPR, type, expr);
>
>      return expr;
>    }
>
>  return NULL_TREE;
> }
>
> #undef  TARGET_CONVERT_TO_TYPE
> #define TARGET_CONVERT_TO_TYPE avr_convert_to_type
>
>
> but with no avail. The explicit, intermediate conversion from __int24 to long
> does not prevent the infinite recursion.

I think the fix would be sth like

Index: gcc/convert.c
===
--- gcc/convert.c   (revision 186871)
+++ gcc/convert.c   (working copy)
@@ -769,6 +769,7 @@ convert_to_integer (tree type, tree expr
   (Otherwise would recurse infinitely in convert.  */
if (TYPE_PRECISION (typex) != inprec)
  {
+   tree otypex = typex;
/* Don't do unsigned arithmetic where signed was wanted,
   or vice versa.
   Exception: if both of the original operands were
@@ -806,10 +807,11 @@ convert_to_integer (tree type, tree expr
  typex = unsigned_type_for (typex);
else
  typex = signed_type_for (typex);
-   return convert (type,
-   fold_build2 (ex_form, typex,
-convert (typex, arg0),
-convert (typex, arg1)));
+   if (TYPE_PRECISION (otypex) == TYPE_PRECISION (typex))
+ return convert (type,
+ fold_build2 (ex_form, typex,
+  convert (typex, arg0),
+  convert (typex, arg1)));
  }
  }
  }


> Johann
>


Re: Failed access check

2012-04-26 Thread Jonathan Wakely
2012/4/26 Peter A. Felvegi:
> On 04/23/2012 08:20 PM, Jonathan Wakely wrote:
>>
>> Please check it's not http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24926
>> first
>
> Hello,
>
> it seems to be the same issue, quite dated, though.

Yes, we have a number of long-standing bugs to do with
access-checking, mostly related to templates.  I'm hoping they'll
eventually get dealt with when G++ supports access-checking in SFINAE
contexts, because those bugs could be exploited in "interesting" new
ways that would change the bug classifications from "accepts-invalid"
to "wrong-code" or "rejects-valid"


[cxx-conversion] Merge from trunk

2012-04-26 Thread Diego Novillo


This merge brings cxx-conversion up to rev 186847.

I added an xfail manifest file for x86_64-unknown-linux-gnu.  When 
testing patches, please use 
contrib/testsuite-management/validate_failures.py to check for new failures.


Tested on x86_64.


Diego.


GCC47 movmem breaks RA, GCC46 RA is fine

2012-04-26 Thread Paulo J. Matos

Hi,

I am facing a problem with the GCC47 register allocation and my 
movmemqi. GCC46 dealt very well with the problem but GCC47 keeps 
throwing at me register spill failures.


My backend has very few registers. 3 chip registers in total (class 
CHIP_REGS), one of them (XL) is used for memory references (class 
ADDR_REGS) and the other two (AL, AH) are for normal use (DATA_REGS), so 
CHIP_REGS = ADDR_REGS U DATA_REGS.


There are a couple of other memory mapped registers, but all loads and 
stores go through CHIP_REGS.


My chip has a block copy instruction which needs source address in XL, 
destination address in AH and count in AL. My movmemqi is similar to 
movmemsi in rx.


(define_expand "movmemqi"
  [(use (match_operand:BLK 0 "memory_operand"))
   (use (match_operand:BLK 1 "memory_operand"))
   (use (match_operand:QI 2 "general_operand"))
   (use (match_operand:QI 3 "general_operand"))]
  ""
{
rtx dst_addr = XEXP(operands[0], 0);
rtx src_addr = XEXP(operands[1], 0);
rtx dst_reg = gen_rtx_REG(QImode, RAH);
rtx src_reg = gen_rtx_REG(QImode, RXL);
rtx cnt_reg = gen_rtx_REG(QImode, RAL);

emit_move_insn(cnt_reg, operands[2]);

if(GET_CODE(dst_addr) == PLUS)
{
emit_move_insn(dst_reg, XEXP(dst_addr, 0));
emit_insn(gen_addqi3(dst_reg, dst_reg, XEXP(dst_addr, 1)));
}
else
emit_move_insn(dst_reg, dst_addr);

if(GET_CODE(src_addr) == PLUS)
{
emit_move_insn(src_reg, XEXP(src_addr, 0));
emit_insn(gen_addqi3(src_reg, src_reg, XEXP(src_addr, 1)));
}
else
emit_move_insn(src_reg, src_addr);

emit_insn(gen_bc2());

DONE;
})

(define_insn "bc2"
  [(set (reg:QI RAL) (const_int 0))
   (set (mem:BLK (reg:QI RAH)) (mem:BLK (reg:QI RXL)))
   (set (reg:QI RXL) (plus:QI (reg:QI RXL) (reg:QI RAL)))
   (set (reg:QI RAH) (plus:QI (reg:QI RAH) (reg:QI RAL)))]
  ""
  "bc2")

The parallel in bc2 setups what the bc2 chip instruction modifies. 
Copies block in XL to AH, Moves XL to point to the end of the source 
block, AH to point to the end of the destination block and sets AL to 0.


The C code
int **
t25 (int *d, int **s)
{
  memcpy (d, *s, 16);
  return s;
}

turns into the following after asmcons (-Os passed in):
(note 5 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(insn 2 5 3 2 (parallel [
(set (reg/v/f:QI 22 [ d ])
(reg:QI 1 AL [ d ]))
(clobber (reg:CC 13 CC))
]) memcpy.i:3 6 {*movqi}
 (expr_list:REG_DEAD (reg:QI 1 AL [ d ])
(expr_list:REG_UNUSED (reg:CC 13 CC)
(nil

(insn 3 2 4 2 (parallel [
(set (reg/v/f:QI 23 [ s ])
(reg:QI 0 AH [ s ]))
(clobber (reg:CC 13 CC))
]) memcpy.i:3 6 {*movqi}
 (expr_list:REG_DEAD (reg:QI 0 AH [ s ])
(expr_list:REG_UNUSED (reg:CC 13 CC)
(nil

(note 4 3 7 2 NOTE_INSN_FUNCTION_BEG)

(insn 7 4 8 2 (parallel [
(set (reg/f:QI 24 [ *s_1(D) ])
(mem/f:QI (reg/v/f:QI 23 [ s ]) [2 *s_1(D)+0 S1 A16]))
(clobber (reg:CC 13 CC))
]) memcpy.i:4 6 {*movqi}
 (expr_list:REG_UNUSED (reg:CC 13 CC)
(nil)))

(insn 8 7 9 2 (parallel [
(set (reg:QI 1 AL)
(const_int 16 [0x10]))
(clobber (reg:CC 13 CC))
]) memcpy.i:4 6 {*movqi}
 (expr_list:REG_UNUSED (reg:CC 13 CC)
(nil)))

(insn 9 8 10 2 (parallel [
(set (reg:QI 0 AH)
(reg/v/f:QI 22 [ d ]))
(clobber (reg:CC 13 CC))
]) memcpy.i:4 6 {*movqi}
 (expr_list:REG_DEAD (reg/v/f:QI 22 [ d ])
(expr_list:REG_UNUSED (reg:CC 13 CC)
(nil

(insn 10 9 11 2 (parallel [
(set (reg:QI 3 X)
(reg/f:QI 24 [ *s_1(D) ]))
(clobber (reg:CC 13 CC))
]) memcpy.i:4 6 {*movqi}
 (expr_list:REG_DEAD (reg/f:QI 24 [ *s_1(D) ])
(expr_list:REG_UNUSED (reg:CC 13 CC)
(nil

(insn 11 10 16 2 (parallel [
(set (reg:QI 1 AL)
(const_int 0 [0]))
(set (mem:BLK (reg:QI 0 AH) [0 A16])
(mem:BLK (reg:QI 3 X) [0 A16]))
(set (reg:QI 3 X)
(plus:QI (reg:QI 3 X)
(reg:QI 1 AL)))
(set (reg:QI 0 AH)
(plus:QI (reg:QI 0 AH)
(reg:QI 1 AL)))
]) memcpy.i:4 21 {bc2}
 (expr_list:REG_UNUSED (reg:QI 3 X)
(expr_list:REG_UNUSED (reg:QI 1 AL)
(expr_list:REG_UNUSED (reg:QI 0 AH)
(nil)

(insn 16 11 19 2 (parallel [
(set (reg/i:QI 1 AL)
(reg/v/f:QI 23 [ s ]))
(clobber (reg:CC 13 CC))
]) memcpy.i:6 6 {*movqi}
 (expr_list:REG_DEAD (reg/v/f:QI 23 [ s ])
(expr_list:REG_UNUSED (reg:CC 13 CC)
(nil

(insn 19 16 0 2 (use (reg/i:QI 1 AL)) memcpy.i:6 -1
 (nil))

Pass ira starts by reporting:
;; Function t25 (t25, funcdef_no=0, decl_uid=1309, cgraph_uid=0)

s

cgraph_nodes_queue replacement?

2012-04-26 Thread Iyer, Balaji V
Hello Everyone,
I just recently pulled the trunk and I noticed that cgraph_nodes_queue 
is taken out. Is it renamed (or #defined) to something else? I am using it for 
some code in my Cilk plus branch. So what is the appropriate replacement for 
the following code? 

for (n = cgraph_nodes_queue; n ; n = n->next_needed)

Any help is greatly appreciated!

Thanks,

Balaji V. Iyer.


Re: cgraph_nodes_queue replacement?

2012-04-26 Thread Jan Hubicka
> Hello Everyone,
>   I just recently pulled the trunk and I noticed that cgraph_nodes_queue 
> is taken out. Is it renamed (or #defined) to something else? I am using it 
> for some code in my Cilk plus branch. So what is the appropriate replacement 
> for the following code? 
> 
>   for (n = cgraph_nodes_queue; n ; n = n->next_needed)
> 
> Any help is greatly appreciated!
You want
 FOR_EACH_FUNCION (node) or one of the alternatives.

Honza
> 
> Thanks,
> 
> Balaji V. Iyer.


gcc-4.5-20120426 is now available

2012-04-26 Thread gccadmin
Snapshot gcc-4.5-20120426 is now available on
  ftp://gcc.gnu.org/pub/gcc/snapshots/4.5-20120426/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 4.5 SVN branch
with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-4_5-branch 
revision 186885

You'll find:

 gcc-4.5-20120426.tar.bz2 Complete GCC

  MD5=463ab7ffcfc17e7c0fd8cd4f1d99c832
  SHA1=3e11436452da168ed127e0fce4db820cada27dca

Diffs from 4.5-20120419 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-4.5
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.