Subject: Re: [PATCH] powerpc: merge include/asm/cputable.h

From: Arnd Bergmann <[email-masked]>
Date: Fri, 16 Sep 2005 05:11:38 +0200

On Freedag 16 September 2005 04:22, Kumar Gala wrote:

> > #define CPU_FTR_POSSIBLE CPU_FTR_PSERIES_POSSIBLE |  
> > CPU_FTR_PMAC_POSSIBLE \
> >          | CPU_FTR_...
> > #define CPU_FTR_ALWAYS CPU_FTR_POSSIBLE & CPU_FTR_PSERIES_ALWAYS \
> >         & CPU_FTR_PMAC_ALWAYS & CPU_FTR_ ...
> 
> Yes, something like that.  Why do we need the CPU_FTR_ALWAYS.  It  
> seems that CPU_FTR_POSSIBLE is sufficient.  I may just not understand  
> the purpose of CPU_FTR_ALWAYS.
>
> > One point to consider is that we traditionally use #ifdef in the
> > source for many places that could simply use cpu_has_feature(). E.g.
> > most instances of #ifdef CONFIG_ALTIVEC could be replaced by
> > cpu_has_feature(CPU_FTR_ALTIVEC) without additional run-time overhead.
> 
> These should stay as CONFIG options because to reduce the code size  
> of the kernel which is important to embedded people.

The whole point of the logic is to reduce code size, because gcc
is smart enough to remove all dead code then.
Consider again the definition of

| static inline int have_feature(unsigned long feature)
| {
|      return (FEATURE_ALWAYS & feature) ||
|             (FEATURE_POSSIBLE & runtime_feature & feature);
| }

If the feature is part of FEATURE_ALWAYS, this will be optimized to

|      return 1 || FEATURE_POSSIBLE & runtime_feature & feature;

and subsequently

|      return 1;

If it is not part of FEATURE_POSSIBLE, it it equivalent to

|      return 0 || (0 & runtime_feature & feature);

which becomes

|      return 0;

Any code inside of

|      if (0) { /* ... */ }

is only checked for syntax by gcc but will not end up in the object code.
For the 'if(1)' case, the code gets smaller as well, because the runtime
flag does not have to be dereferenced.

For some places, we might prefer to replace '#ifdef CONFIG_FOO' not with
have_feature(FOO), but rather with feature_possible(FOO), given a definition
of 

static inline int have_feature(unsigned int feature)
{
	return !!(FEATURE_POSSIBLE & feature);
}

which always get evaluated at compile time.

	Arnd <><