RE: GCC version bikeshedding

2014-07-21 Thread Paulo Matos


> -Original Message-
> From: gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] On Behalf
> Of Andi Kleen
> Sent: 20 July 2014 22:29
> To: Paulo Matos
> Cc: gcc@gcc.gnu.org
> Subject: Re: GCC version bikeshedding
> 
> Paulo Matos  writes:
> >
> > That's what I understood as well. Someone mentioned to leave the
> patch
> > level number to the distros to use which sounded like a good idea.
> 
> Sounds like a bad idea, as then there would be non unique gcc
> versions.
> redhat gcc 5.0.2 potentially being completely different from suse gcc
> 5.0.2
> 

I understand your concern but I am not convinced it's bad. The main reason for 
this is that we wouldn't distribute GCCs x.y.z with z != 0 so if you would see 
5.0.3 in the wild then you could only conclude it's 5.0 with a few patches from 
some vendor. As I type this I am starting to think how frustrating this might 
become. However, isn't it the case that nowadays you can have different gcc 
4.9.1-2 distributed from different distros? The default gcc in my linode shows: 
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

So, I can't see why in the future you couldn't have:
Gcc version 5.1 (Ubuntu/Linaro 5.1.3)

This is only if the release managers want to assign the patch level number to 
distros. I don't think there was a decision on this.

Paulo Matos


[GSoC] Question about the implementation of vec.h

2014-07-21 Thread Roman Gareev
Dear gcc contributors,

could you please answer a few questions about the implementation of
vec.h? Should we always use “create” to initialize, for example,
vec or is it possible to do it using “safe_grow_cleared”
or a similar function? There is "vec_safe_grow_cleared", which works
with vec. Is there a way to use it with
vec?

I would be very grateful for your comments.

--
   Cheers, Roman Gareev.


Re: GCC version bikeshedding

2014-07-21 Thread Andreas Schwab
Andi Kleen  writes:

> Sounds like a bad idea, as then there would be non unique gcc versions.
> redhat gcc 5.0.2 potentially being completely different from suse gcc
> 5.0.2

How is that different from now?

Andreas.

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


[GSoC] generation of Gimple code from isl_ast_node_block

2014-07-21 Thread Roman Gareev
I've attached the patch, which contains generation of Gimple code from
isl_ast_node_block.

However, I've found out a problem. The following example:

int k = 50;
static int __attribute__((noinline))
foo ()
{
  int i, res;
  for (i = 0, res = 0; i < k; i++)
res += i;

  return res;
}

extern void abort ();

int
main (void)
{
  int res = foo ();


  if (res != 1225)
abort ();

  return 0;
}.

produces the following code, which executes without error:

ISL AST generated by ISL:
{
  for (int c1 = 0; c1 < k.0; c1 += 1)
S_4(c1);
  S_6();
}

Gimple code:
loop_0 (header = 0, latch = 1, niter = )
{
  bb_2 (preds = {bb_0 }, succs = {bb_3 bb_8 })
  {
:
# VUSE <.MEM_3(D)>
k.0_9 = k;
if (k.0_9 > 0)
  goto ;
else
  goto ;

  }
  bb_3 (preds = {bb_2 }, succs = {bb_4 bb_7 })
  {
:
# .MEM_8 = VDEF <.MEM_3(D)>
phi_out_of_ssa.5[0] = 0;
_20 = k.0_9 > 0;
if (_20 != 0)
  goto ;
else
  goto ;

  }
  bb_4 (preds = {bb_3 }, succs = {bb_5 })
  {
:
_21 = (signed long) k.0_9;
_22 = _21 + -1;

  }
  bb_7 (preds = {bb_5 bb_3 }, succs = {bb_8 })
  {
:
# .MEM_30 = PHI <.MEM_29(5), .MEM_8(3)>
# VUSE <.MEM_30>
res_32 = Close_Phi.6[0];
# .MEM_33 = VDEF <.MEM_30>
Cross_BB_scalar_dependence.7[0] = res_32;
# VUSE <.MEM_33>
res_17 = Cross_BB_scalar_dependence.7[0];
_16 = res_17;

  }
  bb_8 (preds = {bb_7 bb_2 }, succs = {bb_1 })
  {
:
# res_12 = PHI <_16(7), 0(2)>
# .MEM_2 = PHI <.MEM_33(7), .MEM_3(D)(2)>
# VUSE <.MEM_2>
return res_12;

  }
  loop_2 (header = 5, latch = 6, niter = (unsigned long) ((signed
long) k.0_9 + -1), upper_bound = 9223372036854775806)
  {
bb_5 (preds = {bb_4 bb_6 }, succs = {bb_6 bb_7 })
{
  :
  # graphite_IV.8_23 = PHI <0(4), graphite_IV.8_24(6)>
  # .MEM_31 = PHI <.MEM_8(4), .MEM_29(6)>
  # VUSE <.MEM_31>
  res_25 = phi_out_of_ssa.5[0];
  _27 = (int) graphite_IV.8_23;
  res_26 = res_25 + _27;
  # .MEM_28 = VDEF <.MEM_31>
  Close_Phi.6[0] = res_26;
  # .MEM_29 = VDEF <.MEM_28>
  phi_out_of_ssa.5[0] = res_26;
  graphite_IV.8_24 = graphite_IV.8_23 + 1;
  if (graphite_IV.8_23 < _22)
goto ;
  else
goto ;

}
bb_6 (preds = {bb_5 }, succs = {bb_5 })
{
  :
  goto ;

}
  }
}

It is similar to the original code:

loop_0 (header = 0, latch = 1, niter = )
{
  bb_2 (preds = {bb_0 }, succs = {bb_3 bb_8 })
  {
:
# VUSE <.MEM_3(D)>
k.0_9 = k;
if (k.0_9 > 0)
  goto ;
else
  goto ;

  }
  bb_3 (preds = {bb_2 }, succs = {bb_5 })
  {
:
# .MEM_8 = VDEF <.MEM_3(D)>
phi_out_of_ssa.5[0] = 0;
goto ;

  }
  bb_4 (preds = {bb_7 }, succs = {bb_8 })
  {
:
# .MEM_19 = PHI <.MEM_18(7)>
# VUSE <.MEM_19>
res_17 = Cross_BB_scalar_dependence.7[0];
_16 = res_17;
goto ;

  }
  bb_7 (preds = {bb_5 }, succs = {bb_4 })
  {
:
# VUSE <.MEM_13>
res_4 = Close_Phi.6[0];
# .MEM_18 = VDEF <.MEM_13>
Cross_BB_scalar_dependence.7[0] = res_4;
goto ;

  }
  bb_8 (preds = {bb_4 bb_2 }, succs = {bb_1 })
  {
:
# res_12 = PHI <_16(4), 0(2)>
# .MEM_2 = PHI <.MEM_19(4), .MEM_3(D)(2)>
# VUSE <.MEM_2>
return res_12;

  }
  loop_1 (header = 5, latch = 6, niter = , upper_bound = 2147483646)
  {
bb_5 (preds = {bb_3 bb_6 }, succs = {bb_6 bb_7 })
{
  :
  # i_10 = PHI <0(3), i_6(6)>
  # .MEM_1 = PHI <.MEM_8(3), .MEM_13(6)>
  # VUSE <.MEM_1>
  res_11 = phi_out_of_ssa.5[0];
  res_5 = res_11 + i_10;
  # .MEM_7 = VDEF <.MEM_1>
  Close_Phi.6[0] = res_5;
  # .MEM_13 = VDEF <.MEM_7>
  phi_out_of_ssa.5[0] = res_5;
  i_6 = i_10 + 1;
  if (i_6 < k.0_9)
goto ;
  else
goto ;

}
bb_6 (preds = {bb_5 }, succs = {bb_5 })
{
  :
  goto ;

}
  }
}

If we change the name of variable k to n:

int n = 50;
static int __attribute__((noinline))
foo ()
{
  int i, res;
  for (i = 0, res = 0; i < n; i++)
res += i;

  return res;
}

extern void abort ();

int
main (void)
{
  int res = foo ();


  if (res != 1225)
abort ();

  return 0;
}

the following code will be produced, which gives wrong result

ISL AST generated by ISL:
{
  S_6();
  for (int c1 = 0; c1 < n.0; c1 += 1)
S_4(c1);
}

Gimple code:
loop_0 (header = 0, latch = 1, niter = )
{
  bb_2 (preds = {bb_0 }, succs = {bb_3 bb_8 })
  {
:
# VUSE <.MEM_3(D)>
n.0_9 = n;
if (n.0_9 > 0)
  goto ;
else
  goto ;

  }
  bb_3 (preds = {bb_2 }, succs = {bb_4 bb_7 })
  {
:
# .MEM_8 = VDEF <.MEM_3(D)>
phi_out_of_ssa.5[0] = 0;
# VUSE <.MEM_8>
res_20 = Close_Phi.6[0];
# .MEM_21 = VDEF <.MEM_8>
Cross_BB_scalar_dependence.7[0] = res_20;
_22 = n.0_9 > 0;
if (_22 != 0)
  goto ;
else
  goto ;

  }
  bb_4 (preds = {bb_3 }, succs = {bb_5 })
  {
:
_23 = (signed long) n.0_9;
_24 = _23 + -1;

  }
  bb_7 (preds = {bb_5 bb_3 }, succs = {

Re: [GSoC] generation of Gimple code from isl_ast_node_block

2014-07-21 Thread Tobias Grosser

On 21/07/2014 14:23, Roman Gareev wrote:

I've attached the patch, which contains generation of Gimple code from
isl_ast_node_block.

However, I've found out a problem. The following example:

int k = 50;
static int __attribute__((noinline))
foo ()
{
   int i, res;
   for (i = 0, res = 0; i < k; i++)
 res += i;

   return res;
}

extern void abort ();

int
main (void)
{
   int res = foo ();


   if (res != 1225)
 abort ();

   return 0;
}.

produces the following code, which executes without error:

ISL AST generated by ISL:
{
   for (int c1 = 0; c1 < k.0; c1 += 1)
 S_4(c1);
   S_6();
}

Gimple code:
loop_0 (header = 0, latch = 1, niter = )
{
   bb_2 (preds = {bb_0 }, succs = {bb_3 bb_8 })
   {
 :
 # VUSE <.MEM_3(D)>
 k.0_9 = k;
 if (k.0_9 > 0)
   goto ;
 else
   goto ;

   }
   bb_3 (preds = {bb_2 }, succs = {bb_4 bb_7 })
   {
 :
 # .MEM_8 = VDEF <.MEM_3(D)>
 phi_out_of_ssa.5[0] = 0;
 _20 = k.0_9 > 0;
 if (_20 != 0)
   goto ;
 else
   goto ;

   }
   bb_4 (preds = {bb_3 }, succs = {bb_5 })
   {
 :
 _21 = (signed long) k.0_9;
 _22 = _21 + -1;

   }
   bb_7 (preds = {bb_5 bb_3 }, succs = {bb_8 })
   {
 :
 # .MEM_30 = PHI <.MEM_29(5), .MEM_8(3)>
 # VUSE <.MEM_30>
 res_32 = Close_Phi.6[0];
 # .MEM_33 = VDEF <.MEM_30>
 Cross_BB_scalar_dependence.7[0] = res_32;
 # VUSE <.MEM_33>
 res_17 = Cross_BB_scalar_dependence.7[0];
 _16 = res_17;

   }
   bb_8 (preds = {bb_7 bb_2 }, succs = {bb_1 })
   {
 :
 # res_12 = PHI <_16(7), 0(2)>
 # .MEM_2 = PHI <.MEM_33(7), .MEM_3(D)(2)>
 # VUSE <.MEM_2>
 return res_12;

   }
   loop_2 (header = 5, latch = 6, niter = (unsigned long) ((signed
long) k.0_9 + -1), upper_bound = 9223372036854775806)
   {
 bb_5 (preds = {bb_4 bb_6 }, succs = {bb_6 bb_7 })
 {
   :
   # graphite_IV.8_23 = PHI <0(4), graphite_IV.8_24(6)>
   # .MEM_31 = PHI <.MEM_8(4), .MEM_29(6)>
   # VUSE <.MEM_31>
   res_25 = phi_out_of_ssa.5[0];
   _27 = (int) graphite_IV.8_23;
   res_26 = res_25 + _27;
   # .MEM_28 = VDEF <.MEM_31>
   Close_Phi.6[0] = res_26;
   # .MEM_29 = VDEF <.MEM_28>
   phi_out_of_ssa.5[0] = res_26;
   graphite_IV.8_24 = graphite_IV.8_23 + 1;
   if (graphite_IV.8_23 < _22)
 goto ;
   else
 goto ;

 }
 bb_6 (preds = {bb_5 }, succs = {bb_5 })
 {
   :
   goto ;

 }
   }
}

It is similar to the original code:

loop_0 (header = 0, latch = 1, niter = )
{
   bb_2 (preds = {bb_0 }, succs = {bb_3 bb_8 })
   {
 :
 # VUSE <.MEM_3(D)>
 k.0_9 = k;
 if (k.0_9 > 0)
   goto ;
 else
   goto ;

   }
   bb_3 (preds = {bb_2 }, succs = {bb_5 })
   {
 :
 # .MEM_8 = VDEF <.MEM_3(D)>
 phi_out_of_ssa.5[0] = 0;
 goto ;

   }
   bb_4 (preds = {bb_7 }, succs = {bb_8 })
   {
 :
 # .MEM_19 = PHI <.MEM_18(7)>
 # VUSE <.MEM_19>
 res_17 = Cross_BB_scalar_dependence.7[0];
 _16 = res_17;
 goto ;

   }
   bb_7 (preds = {bb_5 }, succs = {bb_4 })
   {
 :
 # VUSE <.MEM_13>
 res_4 = Close_Phi.6[0];
 # .MEM_18 = VDEF <.MEM_13>
 Cross_BB_scalar_dependence.7[0] = res_4;
 goto ;

   }
   bb_8 (preds = {bb_4 bb_2 }, succs = {bb_1 })
   {
 :
 # res_12 = PHI <_16(4), 0(2)>
 # .MEM_2 = PHI <.MEM_19(4), .MEM_3(D)(2)>
 # VUSE <.MEM_2>
 return res_12;

   }
   loop_1 (header = 5, latch = 6, niter = , upper_bound = 2147483646)
   {
 bb_5 (preds = {bb_3 bb_6 }, succs = {bb_6 bb_7 })
 {
   :
   # i_10 = PHI <0(3), i_6(6)>
   # .MEM_1 = PHI <.MEM_8(3), .MEM_13(6)>
   # VUSE <.MEM_1>
   res_11 = phi_out_of_ssa.5[0];
   res_5 = res_11 + i_10;
   # .MEM_7 = VDEF <.MEM_1>
   Close_Phi.6[0] = res_5;
   # .MEM_13 = VDEF <.MEM_7>
   phi_out_of_ssa.5[0] = res_5;
   i_6 = i_10 + 1;
   if (i_6 < k.0_9)
 goto ;
   else
 goto ;

 }
 bb_6 (preds = {bb_5 }, succs = {bb_5 })
 {
   :
   goto ;

 }
   }
}

If we change the name of variable k to n:

int n = 50;
static int __attribute__((noinline))
foo ()
{
   int i, res;
   for (i = 0, res = 0; i < n; i++)
 res += i;

   return res;
}

extern void abort ();

int
main (void)
{
   int res = foo ();


   if (res != 1225)
 abort ();

   return 0;
}

the following code will be produced, which gives wrong result

ISL AST generated by ISL:
{
   S_6();
   for (int c1 = 0; c1 < n.0; c1 += 1)
 S_4(c1);
}


It seems S_6 is now scheduled before S_4 which is surprising, as
dependences from S_4 to S_6 should prevent us from generating a schedule 
that yields such a result. What is the schedule that you give to the isl 
ast generator?


Cheers,
Tobias

P.S.: The patch looks good by itself, but needs some test cases. As you 
have them in this email, we can just add them after we understood this bug.


Re: [GSoC] generation of Gimple code from isl_ast_node_block

2014-07-21 Thread Roman Gareev
> It seems S_6 is now scheduled before S_4 which is surprising, as
> dependences from S_4 to S_6 should prevent us from generating a schedule
> that yields such a result. What is the schedule that you give to the isl ast
> generator?

The schedule generated by the code, which uses variable k (It executes
without errors):

[k.0] -> { S_6[] -> [1] : exists (e0 = [(-1 + k.0)/4294967296]:
4294967296e0 <= -1 + k.0 and 4294967296e0 >= -2147483647 + k.0);
S_4[i0] -> [0, i0, 0] : exists (e0 = [(-1 + k.0)/4294967296]: i0 >= 0
and 4294967296e0 <= -1 + k.0 and 4294967296e0 >= -4294967296 + k.0 and
4294967296e0 <= -1 + k.0 - i0 and i0 <= 2147483646) }

The schedule generated by the code, which uses variable n:

[n.0] -> { S_6[] -> [1] : exists (e0 = [(-1 + n.0)/4294967296]:
4294967296e0 <= -1 + n.0 and 4294967296e0 >= -2147483647 + n.0);
S_4[i0] -> [0, i0, 0] : exists (e0 = [(-1 + n.0)/4294967296]: i0 >= 0
and 4294967296e0 <= -1 + n.0 and 4294967296e0 >= -4294967296 + n.0 and
4294967296e0 <= -1 + n.0 - i0 and i0 <= 2147483646) }

--
   Cheers, Roman Gareev.


Re: [GSoC] Question about the implementation of vec.h

2014-07-21 Thread Diego Novillo
On Mon, Jul 21, 2014 at 5:22 AM, Roman Gareev  wrote:
> Dear gcc contributors,
>
> could you please answer a few questions about the implementation of
> vec.h? Should we always use “create” to initialize, for example,
> vec or is it possible to do it using “safe_grow_cleared”
> or a similar function? There is "vec_safe_grow_cleared", which works
> with vec. Is there a way to use it with
> vec?

Yes, you need to use .create() to initialize vec instances.


Diego.


Re: [GSoC] generation of Gimple code from isl_ast_node_block

2014-07-21 Thread Tobias Grosser

On 21/07/2014 14:55, Roman Gareev wrote:

It seems S_6 is now scheduled before S_4 which is surprising, as
dependences from S_4 to S_6 should prevent us from generating a schedule
that yields such a result. What is the schedule that you give to the isl ast
generator?


The schedule generated by the code, which uses variable k (It executes
without errors):

[k.0] -> { S_6[] -> [1] : exists (e0 = [(-1 + k.0)/4294967296]:
4294967296e0 <= -1 + k.0 and 4294967296e0 >= -2147483647 + k.0);
S_4[i0] -> [0, i0, 0] : exists (e0 = [(-1 + k.0)/4294967296]: i0 >= 0
and 4294967296e0 <= -1 + k.0 and 4294967296e0 >= -4294967296 + k.0 and
4294967296e0 <= -1 + k.0 - i0 and i0 <= 2147483646) }

The schedule generated by the code, which uses variable n:

[n.0] -> { S_6[] -> [1] : exists (e0 = [(-1 + n.0)/4294967296]:
4294967296e0 <= -1 + n.0 and 4294967296e0 >= -2147483647 + n.0);
S_4[i0] -> [0, i0, 0] : exists (e0 = [(-1 + n.0)/4294967296]: i0 >= 0
and 4294967296e0 <= -1 + n.0 and 4294967296e0 >= -4294967296 + n.0 and
4294967296e0 <= -1 + n.0 - i0 and i0 <= 2147483646) }


Perfect. The problem is that S_6 has a one-dimensional schedule [1] and 
S_4 has a three dimensional schedule [0,i0,0]. For schedules with 
different dimensionality, the isl AST generator can not define an order 
and just randomly chooses an order. The solution to this problem is to 
extend all schedules to the maximal number of schedule dimensions (using 
'0's for the remaining values).


Search for the function extend_scattering() (its implementation is 
unnecessarily verbose and could possibly simplified by using 
isl_*_equate or isl_*fix*).


Cheers,
Tobias


Re: GCC version bikeshedding

2014-07-21 Thread Alec Teal

On 20/07/14 22:28, Andi Kleen wrote:

Paulo Matos  writes:

That's what I understood as well. Someone mentioned to leave the patch
level number to the distros to use which sounded like a good idea.

Sounds like a bad idea, as then there would be non unique gcc versions.
redhat gcc 5.0.2 potentially being completely different from suse gcc
5.0.2
Agreed (no experience, but I wouldn't want to live in a world where what 
Andi

describes is the case!)


-Andi
What is "Bikeshedding"? I've not heard this term before and a quick 
search showed

some weird things, and this very thread!

Alec



Re: GCC version bikeshedding

2014-07-21 Thread Diego Novillo
On Mon, Jul 21, 2014 at 10:30 AM, Alec Teal  wrote:

> Agreed (no experience, but I wouldn't want to live in a world where what
> Andi
> describes is the case!)

We already live in that world. This would not change that. I quite
like the proposal.

> What is "Bikeshedding"? I've not heard this term before and a quick search
> showed
> some weird things, and this very thread!

Derived from Parkinson's Law of Triviality
(http://en.wikipedia.org/wiki/Parkinson's_law_of_triviality). Boils
down to giving more weight to trivial aspects of a discussion.


Diego.


[Copyright transfer] What to do for copyright transfer to FSF for contracted changes?

2014-07-21 Thread Andre Vehreschild
Hi,

I am a freelancer contracted to fix some bugs in the fortran compiler. I
understand that I need to transfer the copyright of that effort to the FSF. My
client and me are willing to sign any paperwork needed for that. Unfortunately
my client will be on holiday from Thursday on. 

What do I need to do transfer the copyright of the changes I am contracted to -
which partially are already done and in discussion (see for example "PR 60414:
Patch proposal" on the fortran and gcc-patches list) and for some to come - to
FSF? 

Sorry, for the bother. I did not find anything on the web besides
https://gcc.gnu.org/contribute.html#legal which is somewhat unclear to me being
none-native English speaker.

Regards,
Andre
-- 
Andre Vehreschild 


Re: Some __builtin_round and cast subtleties

2014-07-21 Thread Joseph S. Myers
On Fri, 4 Jul 2014, Kyrill Tkachov wrote:

> These end up taking different codepaths through the compiler () because
> __builtin_lround has to take -fmath-errno into account and does not end up
> getting inlined (generating a call to the library lround).

That suggests this transformation is buggy unless -fno-math-errno is used 
(given the existence of cases where round + cast must not set errno, but 
lround may).  A bug should be filed in Bugzilla for this.

-- 
Joseph S. Myers
jos...@codesourcery.com


[gomp4] Offloading wiki page

2014-07-21 Thread Ilya Verbin
Hi,

I've created a wiki page about offloading.  Any improvements are welcome.

https://gcc.gnu.org/wiki/Offloading

Thanks,
  -- Ilya


Re: GCC version bikeshedding

2014-07-21 Thread Eric Botcazou
> Was this a Cauldron thing?  Could you summarise it for the people who
> weren't there?  I don't strongly object, but it seems like unnecessary
> churn (especially in terms of user expectations).

Yeah, bumping the major version number every year is a bit ridiculous.  Not as 
ridiculous as Firefox, but still.

-- 
Eric Botcazou


gcc 4.9 Very slow

2014-07-21 Thread Ali Abdul Ghani
Hi list
When I compare gcc 4.8 in gcc 4.9
gcc 4.9 Very slow
When I use g++


Question for ARM person re asm_fprintf

2014-07-21 Thread David Wohlferd
I have been looking at asm_fprintf in final.c, and I think there's a 
design flaw.  But since the change affects ARM and since I have no 
access to an ARM system, I need a second opinion.


asm_fprintf allows platforms to add support for new format specifiers by 
using the ASM_FPRINTF_EXTENSIONS macro.  ARM uses this to add support 
for %@ and %r specifiers.  Pretty straight-forward.


However, it isn't enough to add these two items to the case statement in 
asm_fprintf.  Over in c-format.c, there is compile-time checking that is 
done against calls to asm_fprintf to validate the format string.  %@ and 
%r have been added to this checking (see asm_fprintf_char_table), but 
NOT in a platform-specific way.


This means that using %r or %@ will successfully pass the format 
checking on all platforms, but will ICE on non-ARM platforms since there 
are no case statements in asm_fprintf to support them.


Compiling the code in asm_fprintf-1.c (see the patch) with this patch 
correctly reports "unknown conversion type character" for both 'r' and 
'@' in  x86_64-pc-cygwin.  It would be helpful if someone could confirm 
that it still compiles without error under ARM after applying this 
patch.  I'm reluctant to post this to gcc-patches when it has never been 
run.


dw
Index: gcc/c-family/c-format.c
===
--- gcc/c-family/c-format.c	(revision 212900)
+++ gcc/c-family/c-format.c	(working copy)
@@ -637,8 +637,9 @@
   { "I",   0, STD_C89, NOARGUMENTS, "",  "",   NULL },
   { "L",   0, STD_C89, NOARGUMENTS, "",  "",   NULL },
   { "U",   0, STD_C89, NOARGUMENTS, "",  "",   NULL },
-  { "r",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  "", NULL },
-  { "@",   0, STD_C89, NOARGUMENTS, "",  "",   NULL },
+#ifdef ASM_FPRINTF_TABLE
+  ASM_FPRINTF_TABLE
+#endif
   { NULL,  0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
 };
 
Index: gcc/config/arm/arm.h
===
--- gcc/config/arm/arm.h	(revision 212900)
+++ gcc/config/arm/arm.h	(working copy)
@@ -888,6 +888,12 @@
 fputs (reg_names [va_arg (ARGS, int)], FILE);	\
 break;
 
+/* Used in c-format.c to add entries to the table used to validate calls 
+   to asm_fprintf. */
+#define ASM_FPRINTF_TABLE \
+  { "r",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  "", NULL }, \
+  { "@",   0, STD_C89, NOARGUMENTS, "",  "",   NULL },
+
 /* Round X up to the nearest word.  */
 #define ROUND_UP_WORD(X) (((X) + 3) & ~3)
 
Index: gcc/doc/tm.texi
===
--- gcc/doc/tm.texi	(revision 212900)
+++ gcc/doc/tm.texi	(working copy)
@@ -8611,8 +8611,39 @@
 The varargs input pointer is @var{argptr} and the rest of the format
 string, starting the character after the one that is being switched
 upon, is pointed to by @var{format}.
+See also ASM_FPRINTF_TABLE.
+
+Example:
+@smallexample
+#define ASM_FPRINTF_EXTENSIONS(FILE, ARGS, P)		\
+  case '@':		\
+fputs (ASM_COMMENT_START, FILE);			\
+break;		\
+			\
+  case 'r':		\
+fputs (REGISTER_PREFIX, FILE);			\
+fputs (reg_names [va_arg (ARGS, int)], FILE);	\
+break;
+@end smallexample
 @end defmac
 
+@defmac ASM_FPRINTF_TABLE
+When using ASM_FPRINTF_EXTENSIONS, you must also use this macro to define
+table entries for the printf format checking performed in c-format.c. 
+This macro must contain format_char_info entries for each printf format 
+being added.
+
+Example:
+@smallexample
+#define ASM_FPRINTF_TABLE \
+  @{ "r", 0, STD_C89, \
+ @{ T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, \
+  BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN @}, \
+  "", "", NULL @}, \
+  @{ "@",   0, STD_C89, NOARGUMENTS, "",  "",   NULL @},
+@end smallexample
+@end defmac
+
 @defmac ASSEMBLER_DIALECT
 If your target supports multiple dialects of assembler language (such as
 different opcodes), define this macro as a C expression that gives the
Index: gcc/doc/tm.texi.in
===
--- gcc/doc/tm.texi.in	(revision 212900)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -6370,8 +6370,39 @@
 The varargs input pointer is @var{argptr} and the rest of the format
 string, starting the character after the one that is being switched
 upon, is pointed to by @var{format}.
+See also ASM_FPRINTF_TABLE.
+
+Example:
+@smallexample
+#define ASM_FPRINTF_EXTENSIONS(FILE, ARGS, P)		\
+  case '@':		\
+fputs (ASM_COMMENT_START, FILE);			\
+break;		\
+			\
+  case 'r':		\
+fputs (REGISTER_PREFIX, FILE);			\
+fputs (reg_names [va_arg (ARGS, int)], FILE);	\
+break;
+@end smallexample
 @end defmac
 
+@defmac ASM_FPRINTF_TABLE
+When using ASM_FPRINTF_EXTENSIONS, you must also use this macro to define
+ta