gcc优化特性学习
1. C类型发现
typeof字段可以识别变量类型,实现泛型,下面是一个泛型的例子。
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
2. 范围扩展
gcc可以使用范围,比如在数组初始化的时候会出现一些简单的递增的数据,可以直接使用…来使用gcc推测功能。在switch语句中case中如果范围。
static int sd_major(int major_idx)
{
switch (major_idx) {
case 0:
return SCSI_DISK0_MAJOR;
case 1 ... 7:
return SCSI_DISK1_MAJOR + major_idx - 1;
case 8 ... 15:
return SCSI_DISK8_MAJOR + major_idx - 8;
default:
BUG();
return 0; /* shut up gcc */
}
}
数组的范围拓展
int abc[] = {[0 ... 9] = 0};
int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
3. 判断调用地址
gcc允许调用到函数在堆栈中的返回地址,gcc提供一下函数用来返回函数地址
void * __builtin_return_address( unsigned int level );
level如果是0的话就返回当前函数地址,1的话就返回上层栈帧的地址。
4. 常量检测
gcc提供了用来检测数据是否是常量
int __builtin_constant_p( exp )
5. 函数属性
gcc提供了很多函数的优化。
# define __inline__ __inline__ __attribute__((always_inline))
# define __deprecated __attribute__((deprecated))
# define __attribute_used__ __attribute__((__used__))
# define __attribute_const__ __attribute__((__const__))
# define __must_check __attribute__((warn_unused_result))
- always_inline gcc内联处理指定的函数,无论是否启用了优化。
- deprecated 指出函数已经被废弃,不应该再使用。如果试图使用已经废弃的函数,就会收到警告。还可以对类型和变量应用这个属性,促使开发人员尽可能少使用它们。
- __used__ 告诉编译器无论 GCC 是否发现这个函数的调用实例,都要使用这个函数。这对于从汇编代码中调用 C 函数有帮助。
- __const__ 告诉编译器某个函数是无状态的(也就是说,它使用传递给它的参数生成要返回的结果)。
- warn_unused_result 让编译器检查所有调用者是否都检查函数的结果。这确保调用者适当地检验函数结果,从而能够适当地处理错误。
实例代码
int __deprecated __check_region(struct resource
*parent, unsigned long start, unsigned long n)
static enum unw_register_index __attribute_const__
decode_abreg(unsigned char abreg, int memory)
6. 分支预测提示
gcc中__builtin_expect中使用了两个宏likely 和 unlikely。
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
7. 预抓取
gcc提供了将数据缓存到一级或者二级缓存,gcc提供__builtin_prefetch函数来:
- 数据的地址
- rw 参数,使用它指明预抓取数据是为了执行读操作,还是执行写操作
- locality 参数,使用它指定在使用数据之后数据应该留在缓存中,还是应该清除
void __builtin_prefetch( const void *addr, int rw, int locality );
预抓取函数
#ifndef ARCH_HAS_PREFETCH
#define prefetch(x) __builtin_prefetch(x)
#endif
static inline void prefetch_range(void *addr, size_t len)
{
#ifdef ARCH_HAS_PREFETCH
char *cp;
char *end = addr + len;
for (cp = addr; cp < end; cp += PREFETCH_STRIDE)
prefetch(cp);
#endif
}
8. 变量属性
gcc提供对变量属性的指定,其中一个aligned属性就很重要,专门用来对齐字节。
char __nosavedata swsusp_pg_dir[PAGE_SIZE]
__attribute__ ((aligned (PAGE_SIZE)));
packed 属性是打包一个结构尽可能减少内存
static struct swsusp_header {
char reserved[PAGE_SIZE - 20 - sizeof(swp_entry_t)];
swp_entry_t image;
char orig_sig[10];
char sig[10];
} __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header;
总结
本文主要总结几个常见的gcc特性,用来优化编译结果。