* Pure function for only some arguments
@ 2021-05-21 15:00 Florian Weimer
2021-05-21 16:54 ` Martin Sebor
0 siblings, 1 reply; 2+ messages in thread
From: Florian Weimer @ 2021-05-21 15:00 UTC (permalink / raw)
To: gcc-help
Is it possible to declare an extern function pure for just some
arguments?
To clarify, let's assume I have a function
extern int *func (int);
and I want it to be pure for func (0), func (1), func (3), but not for
func (2). Is this possible?
Will something like this work?
static inline int *
func (int i)
{
if (i == 2)
{
extern int *func_alias_1 (int) __asm__ ("func");
return func_alias_1 (i);
}
else
{
extern int *func_alias_2 (int) __asm__ ("func") __attribute__ ((pure));
return func_alias_2 (i);
}
}
Thanks,
Florian
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Pure function for only some arguments
2021-05-21 15:00 Pure function for only some arguments Florian Weimer
@ 2021-05-21 16:54 ` Martin Sebor
0 siblings, 0 replies; 2+ messages in thread
From: Martin Sebor @ 2021-05-21 16:54 UTC (permalink / raw)
To: Florian Weimer, gcc-help
On 5/21/21 9:00 AM, Florian Weimer via Gcc-help wrote:
> Is it possible to declare an extern function pure for just some
> arguments?
>
> To clarify, let's assume I have a function
>
> extern int *func (int);
>
> and I want it to be pure for func (0), func (1), func (3), but not for
> func (2). Is this possible?
>
> Will something like this work?
>
> static inline int *
> func (int i)
> {
> if (i == 2)
> {
> extern int *func_alias_1 (int) __asm__ ("func");
> return func_alias_1 (i);
> }
> else
> {
> extern int *func_alias_2 (int) __asm__ ("func") __attribute__ ((pure));
> return func_alias_2 (i);
> }
> }
It's tricky but I'd say it should work provided func() is declared with
attribute always_inline to make sure all calls to the wrapper function
are inlined. Without it, some calls may not be treated as pure, and
some might be recursive. The asm renaming is done very late so it
shouldn't matter for the attribute.
Expanding your test case a bit is a good experiment (the tree dumps
show what happens when):
extern int a[];
static inline int *
func (int i)
{
if (i == 2)
{
extern int *func_alias_1 (int) __asm__ ("func");
return func_alias_1 (i);
}
else
{
extern int *func_alias_2 (int) __asm__ ("func") __attribute__
((pure));
return func_alias_2 (i);
}
}
int* f1 ()
{
int t = a[1];
int *p = func (1); // pure call
if (t != a[1]) // folded to false
__builtin_abort ();
return p;
}
int* f2 ()
{
int t = a[1];
int *p = func (2); // not a pure call
if (t != a[1]) // not folded
__builtin_abort ();
return p;
}
Attribute pure is considered during Gimplification as well during
later stages. The former clears the side-effects bit for a call
so that might mean that some very early optimizations that depend
on the side-effects bit being clear won't happen.
Martin
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-05-21 16:54 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-21 15:00 Pure function for only some arguments Florian Weimer
2021-05-21 16:54 ` Martin Sebor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).