Next: Machine Modes, Previous: Special Accessors, Up: RTL
RTL表达式包含几个标记(位域),用于特定类型的表达式。通常它们使用下列的宏来访问,并被扩展为左值。
CONSTANT_POOL_ADDRESS_P (
x)
symbol_ref
中,如果其引用了当前函数的常量池中的一部分,则非零。对于大多数目标机器,这些地址在.rodata
段中,与函数完全分离,但是对于有些目标机器,这些地址是靠近函数起始处。不管哪种情况,GCC都假设这些地址可以被直接寻址,或者通过基址寄存器。其被存储在unchanging
域,打印输出为‘/u’。
RTL_CONST_CALL_P (
x)
call_insn
中,表明该insn表示一个对const函数的调用。存储在unchanging
域,打印输出为‘/u’。
RTL_PURE_CALL_P (
x)
call_insn
中,表明该insn表示一个对pure函数的调用。存储在return_val
域,打印输出为‘/i’。
RTL_CONST_OR_PURE_CALL_P (
x)
call_insn
中,如果RTL_CONST_CALL_P
或者RTL_PURE_CALL_P
为真,则其为真。
RTL_LOOPING_CONST_OR_PURE_CALL_P (
x)
call_insn
中,表明该insn表示一个对const或者pure函数,可能是无限循环的调用。存储在call
域,打印输出为‘/c’。只有当RTL_CONST_CALL_P
或者RTL_PURE_CALL_P
为真时,其才为真。
INSN_ANNULLED_BRANCH_P (
x)
jump_insn
,call_insn
或者insn
中,表明该分支跳转被取消。参见下面关于sequence
的讨论。存储在unchanging
域,打印输出为‘/u’。
INSN_DELETED_P (
x)
insn
, call_insn
, jump_insn
, code_label
, barrier
或note
中,如果该insn被删除掉,则非零。存储在volatil
域,打印输出为‘/v’。
INSN_FROM_TARGET_P (
x)
insn
,jump_insn
或者call_insn
中,在分支延迟槽中,表明该insn是来自分支跳转的目标。如果分支insn设置了INSN_ANNULLED_BRANCH_P
,则该insn只有当进行分支跳转的时候,才被执行。对于被取消的分支,如果是清除了INSN_FROM_TARGET_P
,则insn只有当没有进行分支跳转的时候,才被执行。当INSN_ANNULLED_BRANCH_P
没有被设置,该insn将总是被执行。存储在in_struct
域,打印输出为‘/s’。
LABEL_PRESERVE_P (
x)
code_label
或者note
中,表明被代码或者数据引用的该标号,对于给定的函数RTL不可见。通过非局部goto引用的标号,将设置该位。存储在in_struct
域中,打印输出为‘/s’。
LABEL_REF_NONLOCAL_P (
x)
label_ref
和reg_label
表达式中,如果其为对一个非局部标号的引用,则非零。存储在volatil
域中,打印输出为‘/v’。
MEM_IN_STRUCT_P (
x)
mem
表达式中,对于引用一整个结构体,联合体,数组,或者是它们的一部分,则非零。如果是引用一个标量变量,或者是标量指针,则为零。如果该标记和MEM_SCALAR_P
都被清除,则我们无法知道该mem
是否在一个结构体中。这两个标记不要被同时设置。存储在in_struct
域中,打印输出为‘/s’。
MEM_KEEP_ALIAS_SET_P (
x)
mem
表达式中,如果为1,则表明当访问一个部件时,应该保持该mem的别名集合不变。例如,当在一个聚合体的不可寻址部件中的时候,将其设为1。存储在jump
域中,打印输出为‘/j’。
MEM_SCALAR_P (
x)
mem
表达式中,如果引用的标量,被已知不是结构体,联合体或者数组的成员,则为非零。如果是这样的引用,或者通过指针的间接引用,即便是指向标量类型,则为零,如果该标记和MEM_IN_STRUCT_P
都被清除,则我们无法知道该mem
是否为一个结构体。这两个标记不要被同时设置。存储在return_val
域中,打印输出为‘/i’。
MEM_VOLATILE_P (
x)
mem
, asm_operands
和asm_input
表达式中,对于volatile内存引用,为非零。存储在volatil
域中,打印输出为‘/v’。
MEM_NOTRAP_P (
x)
mem
中,对于不会产生陷阱的内存引用,为非零。存储在call
域中,打印输出为‘/c’。
MEM_POINTER (
x)
mem
中,如果内存引用存放了一个指针,则非零。存储在frame_related
域中,打印输出为‘/f’。
REG_FUNCTION_VALUE_P (
x)
reg
中,如果其为存放函数返回值的地方,则非零。(这只发生在硬件寄存器中。)存储在return_val
域中,打印输出为‘/i’。
REG_POINTER (
x)
reg
中,如果寄存器存放一个指针,则非零。存储在frame_related
域中,打印输出为‘/f’。
REG_USERVAR_P (
x)
reg
中,如果其对应于用户源代码中出现的一个变量,则非零。对于编译器内部生成的临时对象,则为零。存储在volatil
域中,打印输出为‘/v’。
The same hard register may be used also for collecting the values of
functions called by this one, but REG_FUNCTION_VALUE_P
is zero
in this kind of use.
RTX_FRAME_RELATED_P (
x)
insn
, call_insn
, jump_insn
, barrier
, 或者set
中,如果其为函数序言的一部分,用来设置栈指针,帧指针,或者保存寄存器,则为非零。对于设置用于帧指针的临时寄存器的指令,该标记也应被设置。存储在frame_related
域中,打印输出为‘/f’。
特别的,在一些RISC目标机器上,对于立即数常量的大小有限制,有时不能直接通过栈指针来到达寄存器的保存区域。这种情况下,一个足够接近寄存器保存区域的临时寄存器被使用,并且正则帧地址(Canonical Frame Address)寄存器,即DWARF2的逻辑帧指针寄存器,必须(临时的)被改成该临时寄存器。所以,设置该临时寄存器的指令必须被标记为RTX_FRAME_RELATED_P
。
如果被标记的指令过于复杂(跟据dwarf2out_frame_debug_expr
能否处理,而定义的术语),则你还必须要创建一个REG_FRAME_RELATED_EXPR
注解,并附加在该指令上。该注解应该包含一个该指令执行计算的简单表达式,即dwarf2out_frame_debug_expr
可以处理的。
在带有RTL序言的目标机器上,提供异常处理的支持时,会用到该标记。
MEM_READONLY_P (
x)
mem
中,如果内存是静态分配并且只读的,则非零。
在该上下文中只读,意味着在程序的生命周期中不会被修改,但是不必要是在ROM或者不可写的页中。对于后者,一个常见的例子,是共享库的全局偏移表。该表由运行时加载器初始化,所以内存在技术上是可写的,但是当控制从运行时加载器转移给应用程序时,该内存将不再被修改。
存储在unchanging
域中,打印输出为‘/u’。
SCHED_GROUP_P (
x)
insn
, call_insn
或者jump_insn
中,表明前一个insn必须与该insn一起调度。这用来确保特定的指令组不会被指令调度过程分隔开。例如,在call_insn
之前的use
insn不可以从call_insn
中分开。存储在in_struct
域中,打印输出为‘/s’。
SET_IS_RETURN_P (
x)
set
,如果是针对一个return,则非零。存储在jump
域中,打印输出为‘/j’。
SIBLING_CALL_P (
x)
call_insn
,如果该insn为一个sibling call,则非零。存储在jump
域中,打印输出为‘/j’。
STRING_POOL_ADDRESS_P (
x)
symbol_ref
表达式,如果其为对该函数的字符串常量池的寻址,则非零。存储在frame_related
域中,打印输出为‘/f’。
SUBREG_PROMOTED_UNSIGNED_P (
x)
subreg
对于SUBREG_PROMOTED_VAR_P
为非零,并且被引用的对象为零扩展,则返回一个大于零的值;如果保持为符号扩展,则为零;如果是通过ptr_extend
指令,进行某种其它方式的扩展,则小于零。存储在unchanging
域和volatil
域中,打印输出为‘/u’和‘/v’。该宏只用于获得值,不能用于修改值。使用SUBREG_PROMOTED_UNSIGNED_SET
来修改值。
SUBREG_PROMOTED_UNSIGNED_SET (
x)
subreg
中的unchanging
和volatil
域,来反映零扩展,符号扩展,或其它扩展。如果volatil
为零,然后如果unchanging
为非零,则意味着零扩展,如果为零,则意味着符号扩展。如果volatil
为非零,则通过ptr_extend
指令使用了其它某种扩展。
SUBREG_PROMOTED_VAR_P (
x)
subreg
中,如果当访问一个被提升为符合机器描述宏PROMOTED_MODE
的(参见Storage Layout),宽机器模式的对象时,则非零。这种情况下,subreg
的机器模式为对象被声明的机器模式,SUBREG_REG
的机器模式为存放该对象的寄存器的机器模式。被提升的变量,在每个赋值中,总是被符号扩展或者零扩展成宽机器模式。存储在in_struct
域中,打印输出为‘/s’。
SYMBOL_REF_USED (
x)
symbol_ref
中,表明x已经被使用。这通常只用于确保x只在外部被声明一次。存储在used
中。
SYMBOL_REF_WEAK (
x)
symbol_ref
中,表明x已经被声明为weak。存储在return_val
域中,打印输出为‘/i’。
SYMBOL_REF_FLAG (
x)
symbol_ref
中,用于机器特定目的的标记。存储在volatil
域中,打印输出为‘/v’。
大多对SYMBOL_REF_FLAG
的使用,是历史性的,并且可以通过SYMBOL_REF_FLAGS
来归类。当然,如果目标机器需要多于一个位的存储时,对SYMBOL_REF_FLAGS
的使用是强制的。
PREFETCH_SCHEDULE_BARRIER_P (
x)
call
mem
中,1表示该内存引用不会有陷阱。
在call
中,1表示该pure或者const调用,可能为无限循环。
在RTL转储中,该标记被表示为‘/c’。
frame_related
insn
或者set
表达式中,1表示其为函数序言的一部分,设置栈寄存器,设置帧寄存器,保存寄存器,或者设置一个用于帧寄存器的临时寄存器。
在reg
表达式中,1表示该寄存器存放一个指针。
在mem
表达式中,1表示该内存引用存放一个指针。
在symbol_ref
表达式中,1表示该引用是对函数的字符串常量池的寻址。
在RTL转储中,该标记被表示为‘/f’。
in_struct
mem
表达式中,如果所引用的内存数据为整个结构体或者数组,或者一部分,其为1;如果为(或者可能为)一个标量变量。则为0。通过C指针的引用,为0,因为指针可以指向一个标量变量。该信息允许编译器来确定别名的可能情况。
在reg
表达式中,如果寄存器整个生命期都包含在某个循环的测试表达式中,则为1。
在subreg
表达式中,1表示subreg
在访问一个从更宽的机器模式进行提升的对象。
在label_ref
表达式中,1表示被引用的标号位于包含发现label_ref
的insn的最内层循环的外面。
在code_label
表达式中,如果标号不能被删除,则为1。这用于其为非局部goto的目标的标号。对于已经被删除的这样的标号,使用类型为NOTE_INSN_DELETED_LABEL
的note
来替换。
在insn
中,在死代码消除阶段,1表示该insn为死代码。
在insn
或者jump_insn
中,在针对分支延迟槽中insn的reorg阶段,1表示该insn来自分支跳转的目标。
在insn
中,在指令调度阶段,1表示该insn必须与之前的insn一起进行调度。
在RTL转储中,该标记被表示为‘/s’。
return_val
reg
表达式中,1表示寄存器包含了当且函数的返回值。对于在寄存器中传递参数的机器上,同一个寄存器编号也可以被用作参数,但是这种情况下,该标记不被设置。
在mem
中,1表示内存引用为一个已知不为结构体,联合体,数组的成员的标量。
在symbol_ref
表达式中,1表示被引用的符号为weak。
在call
表达式中,1表示调用是pure。
在RTL转储中,该标记被表示为‘/i’。
jump
mem
表达式中,1表示当访问一个部件时,应该保持该mem的别名集不变。
在set
中,1表示其为一个return。
在call_insn
中,1表示其为一个sibling call。
在RTL转储中,该标记被表示为‘/j’。
unchanging
reg
和mem
表达式中,1表示表达式的值不会改变。
在subreg
表达式中,如果subreg
引用了机器模式已经被提升为一个宽模式的无符号对象,则为1。
在分支指令延迟槽中的insn
或jump_insn
中,1表示将使用一个被取消的分支。
在symbol_ref
表达式中,1表示该符号对函数的常量池进行寻址。
在call_insn
中,1表示该指令为对const函数的调用。
在RTL转储中,该标记被表示为‘/u’。
used
对于reg
,其被叶子寄存器重编号代码直接使用(不通过访问宏),来确保每个寄存器只被重编号一次。
在symbol_ref
中,其表示该符号的外部声明已经被书写了。
volatil
mem
, asm_operands
或者asm_input
表达式中,如果内存引用是volatile的,则为1。volatile的内存引用不可以被删除,重排或者合并。
在symbol_ref
表达式中,其用于机器特定的目的。
在reg
表达式中,如果值为用户级的变量,则为1。0表示为内部的编译器临时对象。
在insn
中,1表示该insn已经被删除。
在label_ref
和reg_label
表达式中,1表示对非局部标号的引用。
In prefetch
expressions, 1 means that the containing insn is a
scheduling barrier.
在RTL转储中,该标记被表示为‘/v’。