Previous: Conditional Expressions, Up: Operands


12.5.4 逻辑运算符

除非它们出现在GIMPLE_COND的条件操作数中,否则逻辑的`and'和`or'操作符将按照下列方式进行简化:a = b && c变成

       T1 = (bool)b;
       if (T1 == true)
         T1 = (bool)c;
       a = T1;

注意该例子中的T1不能为表达式临时对象,因为其具有两个不同的赋值。

12.5.5 操作操作数

所有的gimple操作数都是tree类型的。不过只有特定类型的tree可以被用作操作数元组。函数get_gimple_rhs_class可以进行基本的验证,其给定一个tree代码,返回一个enum,为下列enum gimple_rhs_class类型的值

对于在GIMPLE_BINARY_RHSGIMPLE_UNARY_RHS类别中的tree节点,它们不能被直接存放在元组中。需要首先被平整,分隔到独立的部分。例如,给定GENERIC表达式

     a = b + c

其tree表示为:

     MODIFY_EXPR <VAR_DECL  <a>, PLUS_EXPR <VAR_DECL <b>, VAR_DECL <c>>>

这种情况下,该语句的GIMPLE形式逻辑上等同于它的GENERIC形式,但是在GIMPLE中,赋值语句的右手边PLUS_EXPR,不被表示成一个tree,替代的,PLUS_EXPR的两个操作数子树被拿出来,并平整到GIMPLE元组中,如下:

     GIMPLE_ASSIGN <PLUS_EXPR, VAR_DECL <a>, VAR_DECL <b>, VAR_DECL <c>>

12.5.6 操作数向量分配

操作数向量被存放在三元组结构的底部。这意味着,取决于给定语句的代码,其操作数向量相对于基本结构体的偏移量会不同。使用下列方法来访问元组操作数

— GIMPLE function: unsigned gimple_num_ops (gimple g)

返回语句G中的操作数个数。

— GIMPLE function: tree gimple_op (gimple g, unsigned i)

返回语句G的第I个操作数。

— GIMPLE function: tree *gimple_ops (gimple g)

返回指向语句G的操作数向量的指针。这通过内部称作gimple_ops_offset_[]的表来计算。该表的索引为G的gimple代码。

当编译器被构建时,将gimple.def中定义的每个语句代码,所对应的结构体大小来填充该表。因为操作数向量在结构体的底部,所以对于gimple代码C,其偏移量被计算为sizeof (struct-of C) - sizeof (tree)。

该机制对于使用gimple_op()的每次访问,都增加了一个内存重定向,如果这会变成瓶颈,则编译过程可以选择记住gimple_ops()的结果,并使用它来访问操作数。

12.5.7 操作数有效性

当为gimple语句增加一个新的操作数,将根据每个元组在它操作数向量中可以接受的情况来验证该操作数。这些断言由gimple_<name>_set_...()调用。元组会使用下列断言(注意,该列表并不全):

— GIMPLE function: is_gimple_operand (tree t)

这是条件最宽的断言。其实质上是检查t是否具有GIMPLE_SINGLE_RHSgimple_rhs_class

— GIMPLE function: is_gimple_val (tree t)

返回真,如果t为一个“GIMPLE值”,其为所有非寻址的栈变量(is_gimple_reg返回真的变量)和常量(is_gimple_min_invariant返回真的表达式)。

— GIMPLE function: is_gimple_addressable (tree t)

返回真,如果t为一个符号,或者内存引用,其地址可以被使用。

— GIMPLE function: is_gimple_asm_val (tree t)

类似于is_gimple_val,不过其还接受硬件寄存器。

— GIMPLE function: is_gimple_call_addr (tree t)

返回真,如果t为一个有效的表达式,被作用由GIMPLE_CALL调用的函数。

— GIMPLE function: is_gimple_mem_ref_addr (tree t)
— GIMPLE function: is_gimple_constant (tree t)

返回真,如果t为一个有效的gimple常量。

— GIMPLE function: is_gimple_min_invariant (tree t)

返回真,如果t为一个有效的最小不变量。这与常量不同,其特定的值在编译的时候可能不已知,但是知道其不会改变(例如,函数局部变量的地址)。

— GIMPLE function: is_gimple_min_invariant_address (tree t)

返回真,如果t为一个ADDR_EXPR,其在程序运行时不会改变。

— GIMPLE function: is_gimple_ip_invariant (tree t)
— GIMPLE function: is_gimple_ip_invariant_address (tree t)

12.5.8 Statement validation

12.5.9 语句有效性

— GIMPLE function: is_gimple_assign (gimple g)

返回真,如果g的代码为GIMPLE_ASSIGN

— GIMPLE function: is_gimple_call (gimple g)

返回真,如果g的代码为GIMPLE_CALL

— GIMPLE function: is_gimple_debug (gimple g)
— GIMPLE function: gimple_assign_cast_p (gimple g)

返回真,如果g为一个GIMPLE_ASSIGN并执行一个类型转换操作。

— GIMPLE function: gimple_debug_bind_p (gimple g)