Gcc的内建函数 __builtin_constant_p

本文介绍GCC的内建函数__builtin_constant_p,用于判断表达式是否为编译时常数,优化代码编译过程。通过此函数,开发者可以在参数为常数时编译出更优化的代码。

Gcc的内建函数 __builtin_constant_p 用于判断一个值是否为编译时常数,如果参数EXP 的值是常数,函数返回 1,否则返回 0。例如: 
++++ include/asm-i386/bitops.h 
249: #define test_bit(nr,addr) / 
250: (__builtin_constant_p(nr) ? / 
251: constant_test_bit((nr),(addr)) : / 
252: variable_test_bit((nr),(addr))) 
  很多计算或操作在参数为常数时有更优化的实现,在 GNU C 中用上面的方法可以根据参数是否为常数,只编译常数版本或非常数版本,这样既不失通用性,又能在参数是常数时编译出最优化的代码

转自:http://blog.youkuaiyun.com/lights_joy/archive/2008/05/08/2415410.aspx

 

I believe that this asks the compiler whether its argument evaluates 
to a constant value. For instance, __builtin_constant_p(1234) has a 
value of 1, whereas __builtin_constant_p(x), where `x` is a variable, 
has a value of 0.This is sometimes useful when writing highly-optimized code.

<think>我们被要求介绍C++中常用的__builtin内建函数。这些内建函数是编译器(如GCC、Clang)提供的,用于执行一些底层操作或优化。以下是一些常用的__builtin函数及其用途: 1. `__builtin_return_address(level)` - 用途:获取当前函数或其调用者的返回地址。参数`level`表示调用栈的层级,0表示当前函数的返回地址,1表示调用当前函数的函数的返回地址,以此类推。 - 示例:如引用[1]所示,在函数中调用`__builtin_return_address(0)`可以获取当前函数的返回地址。 2. `__builtin_expect(exp, c)` - 用途:指示编译器条件表达式`exp`的预期值,以帮助分支预测优化。通常用于告诉编译器某个条件为真的可能性很大(`c`为1)或很小(`c`为0)。 - 示例:`if (__builtin_expect(x > 0, 1)) { ... }` 表示x>0的可能性很大。 3. `__builtin_popcount(x)` - 用途:计算整数`x`的二进制表示中1的个数(即汉明重量)。 - 示例:`int count = __builtin_popcount(0xF); // 返回4` 4. `__builtin_clz(x)` - 用途:计算整数`x`的二进制表示中前导0的个数(Count Leading Zeros)。注意`x`不能为0。 - 示例:`int leading_zeros = __builtin_clz(1); // 对于32位整数,返回31` 5. `__builtin_ctz(x)` - 用途:计算整数`x`的二进制表示中末尾0的个数(Count Trailing Zeros)。注意`x`不能为0。 - 示例:`int trailing_zeros = __builtin_ctz(0x8); // 返回3` 6. `__builtin_ffs(x)` - 用途:返回整数`x`的二进制表示中最低位的1的位置(从1开始计数,如果x为0则返回0)。 - 示例:`__builtin_ffs(0x8) // 返回4` 7. `__builtin_parity(x)` - 用途:返回整数`x`的二进制表示中1的个数的奇偶性(1的个数为奇数则返回1,偶数则返回0)。 - 示例:`__builtin_parity(0xF) // 返回0(因为4个1,偶数)` 8. `__builtin_prefetch(const void *addr, ...)` - 用途:预取数据到缓存。可以指定是读还是写,以及数据的时间局部性(临时性)。 - 示例:`__builtin_prefetch(p, 0, 3);` 其中第一个参数是地址,第二个参数0表示读(1为写),第三个参数表示局部性(0-3,3表示最弱局部性)。 9. `__builtin_unreachable()` - 用途:告诉编译器某个位置不可能被执行到,用于优化代码生成。 - 示例:在`switch`语句的`default`分支中,如果确定不可能执行到,可以加上`__builtin_unreachable()`。 10. `__builtin_trap()` - 用途:生成一个陷阱指令,使程序异常终止。通常用于不可恢复的错误。 - 示例:`if (error) __builtin_trap();` 11. `__builtin_constant_p(exp)` - 用途:判断表达式`exp`在编译时是否为常量,如果是则返回1,否则返回0。 - 示例:`if (__builtin_constant_p(x)) { ... }` 12. `__builtin_frame_address(level)` - 用途:获取指定层级函数的栈帧地址。类似于`__builtin_return_address`,但获取的是栈帧地址。 - 示例:`void* frame = __builtin_frame_address(0); // 当前函数的栈帧地址` 这些函数通常用于底层编程、性能优化或系统编程。需要注意的是,这些函数是编译器特定的,因此在使用时应注意可移植性。如果使用GCC或Clang,则通常可用。 另外,引用[4]提到了Cache的工作流程,而`__builtin_prefetch`就是用来主动控制缓存预取的函数,可以帮助减少Cache未命中的情况。 §§相关问题§§ 1. `__builtin_return_address`函数在调试中有哪些实际应用? 2. 如何利用`__builtin_expect`来优化程序性能? 3. 在C++中,除了`__builtin`函数,还有哪些编译器特定的扩展功能?</think>### C++常用`__builtin`内建函数详解 `__builtin`是GCC/Clang编译器提供的内建函数集合,用于执行底层操作、优化性能或访问硬件特性。以下是常用函数及其用途: #### 1. 栈帧与地址操作 - **`__builtin_return_address(level)`** 获取调用栈中指定层级的返回地址。`level=0`表示当前函数,`level=1`表示调用者函数。 示例(引用[1]): ```c void f() { int *p = __builtin_return_address(0); // 获取f()的返回地址 printf("f return address: %p\n", p); } ``` 用途:调试栈回溯、安全检测。 - **`__builtin_frame_address(level)`** 获取指定层级的栈帧指针(frame pointer)。 示例:`void* fp = __builtin_frame_address(0);` 用途:手动栈展开、内存分析。 #### 2. 位运算优化 - **`__builtin_popcount(x)`** 计算整数二进制中`1`的个数(汉明重量)。 示例:`int ones = __builtin_popcount(0b1011); // 返回3` 用途:位图处理、加密算法。 - **`__builtin_clz(x)`** 计算前导零(Leading Zeros)的数量。 示例:`__builtin_clz(1) // 32位系统返回31` 用途:位扫描、优先级队列。 - **`__builtin_ctz(x)`** 计算后缀零(Trailing Zeros)的数量。 示例:`__builtin_ctz(8) // 返回3(0b1000)` 用途:内存对齐、位图索引。 #### 3. 分支预测优化 - **`__builtin_expect(exp, c)`** 提示编译器条件`exp`的预期值(`c`通常为0或1),优化分支预测。 示例: ```c if (__builtin_expect(x > 0, 1)) { // 编译器优先优化此分支 } ``` 用途:性能关键路径优化(引用[4]缓存机制相关)。 #### 4. 内存与缓存控制 - **`__builtin_prefetch(ptr, rw, locality)`** 主动预取数据到缓存(`rw=0`读,`rw=1`写;`locality=0~3`表示时间局部性)。 示例:`__builtin_prefetch(arr+i, 0, 3);` 用途:减少Cache Miss(引用[4])。 #### 5. 数学运算 - **`__builtin_ffs(x)`** 返回最低位`1`的位置(从1开始计数)。 示例:`__builtin_ffs(0b10100) // 返回3` 用途:位掩码处理。 - **`__builtin_parity(x)`** 计算奇偶校验位(1的个数模2)。 示例:`__builtin_parity(7) // 7=0b111,返回1` 用途:错误检测编码。 #### 6. 编译器指令 - **`__builtin_unreachable()`** 标记不可达代码,优化生成代码。 示例: ```c if (error) { abort(); __builtin_unreachable(); // 提示编译器后续代码不可达 } ``` 用途:消除冗余分支警告。 - **`__builtin_constant_p(exp)`** 判断表达式是否为编译期常量。 示例: ```c if (__builtin_constant_p(x)) { // 编译期优化路径 } ``` 用途:编译期条件优化。 --- ### 注意事项 1. **编译器依赖**:`__builtin`是GCC/Clang扩展,非标准C++,需注意可移植性。 2. **性能权衡**:如`__builtin_prefetch`滥用可能降低缓存效率。 3. **调试兼容性**:栈操作函数可能受编译器优化影响(如`-fomit-frame-pointer`)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值