GCC官方文档13 SSA

以下按照一段原文+一段翻译的方式给出。原文在前,用标签的形式实现;翻译在后,为正文。

13.2 SSA操作符

Almost every GIMPLE statement will contain a reference to a variable or memory location. Since statements come in different shapes and sizes, their operands are going to be located at various spots inside the statement’s tree. To facilitate access to the statement’s operands, they are organized into lists associated inside each statement’s annotation. Each element in an operand list is a pointer to a VAR_DECL, PARM_DECL or SSA_NAME tree node. This provides a very convenient way of examining and replacing operands.

几乎每个GIMPLE语句都会包含对变量或内存位置的引用。由于语句有不同的形状和大小,它们的操作数将位于语句树中的不同位置。为了方便访问语句的操作数,它们被组织到每个语句注释中关联的列表中。操作数列表中的每个元素都是指向VAR_DECLPARM_DECLSSA_NAME树节点的指针。这为检查和替换操作数提供了一种非常方便的方法。

Data flow analysis and optimization is done on all tree nodes representing variables. Any node for which SSA_VAR_P returns nonzero is considered when scanning statement operands. However, not all SSA_VAR_P variables are processed in the same way. For the purposes of optimization, we need to distinguish between references to local scalar variables and references to globals, statics, structures, arrays, aliased variables, etc. The reason is simple, the compiler can gather complete data flow information for a local scalar. On the other hand, a global variable may be modified by a function call, it may not be possible to keep track of all the elements of an array or the fields of a structure, etc.

所有表示变量的树节点,都要进行数据流分析和优化。当扫描语句操作数时,将考虑SSA_VAR_P返回非零的任何节点。但是,并不是所有SSA_VAR_P变量都以相同的方式处理。为了优化,我们需要区分对局部标量变量的引用和对全局、静态、结构、数组、别名变量等的引用。原因很简单,编译器可以为一个局部标量收集完整的数据流信息。另一方面,全局变量可能被函数调用修改,也存在无法跟踪数组的所有元素或结构的字段等的可能。

The operand scanner gathers two kinds of operands: real and virtual. An operand for which is_gimple_reg returns true is considered real, otherwise it is a virtual operand. We also distinguish between uses and definitions. An operand is used if its value is loaded by the statement (e.g., the operand at the RHS of an assignment). If the statement assigns a new value to the operand, the operand is considered a definition (e.g., the operand at the LHS of an assignment).

操作数扫描器收集两种操作数:实操作数和虚操作数。is_gimple_reg返回true的操作数被认为是真实的,否则它是虚操作数。我们还区分了用法和定义。如果操作数的值是由语句加载的(例如,赋值操作的RHS处的操作数),则称这个操作数被使用,记作“used”。如果语句给操作数赋了一个新值,则该操作数被视为一个定义(例如,赋值操作的LHS处的操作数),也就是“defined”。

Virtual and real operands also have very different data flow properties. Real operands are unambiguous references to the full object that they represent. For instance, given

虚实操作数也有十分不同的数据流属性。实操作数是对于他们表示的完整对象的明确引用。比如,给出以下代码:

{
  int a, b;
  a = b
}

Since a and b are non-aliased locals, the statement a = b will have one real definition and one real use because variable a is completely modified with the contents of variable b. Real definition are also known as killing definitions. Similarly, the use of b reads all its bits.

由于a和b是没有别名的局部变量,由于变量a被变量b的内容完全修改了,所以语句a=b将有一个真实的定义(定义a),以及一个真实的引用(定义b)。真实的定义也被称为注销式定义(盖因它注销了这个变量之前的值)。相似地,对变量b的引用也需要读取它的每一位。

In contrast, virtual operands are used with variables that can have a partial or ambiguous reference. This includes structures, arrays, globals, and aliased variables. In these cases, we have two types of definitions. For globals, structures, and arrays, we can determine from a statement whether a variable of these types has a killing definition. If the variable does, then the statement is marked as having a must definition of that variable. However, if a statement is only defining a part of the variable (i.e. a field in a structure), or if we know that a statement might define the variable but we cannot say for sure, then we mark that statement as having a may definition. For instance, given

作为对比,虚操作符用在变量有局部或者不明确的引用时。这种“不明确的引用”,可能包括结构体、列表、全局变量以及有别名的变量。在这些情况下,我们有两类定义。对于全局变量、结构体和列表,我们可以从一个语句中得知,某个属于这些类型的变量是否有注销式定义。如果有,那么就标记这个语句为“有注销式定义”。然而,如果一个语句只是定义了变量的一部分(比如结构体的某一个属性);或者如果我们知道语句有可能定义某变量,但也可能不定义这个变量,那么我们就要将这个语句标记为“存在可能的定义”。比如下述代码:

{
  int a, b, *p;

  if ()
    p = &a;
  else
    p = &b;
  *p = 5;
  return *p;
}

The assignment *p = 5 may be a definition of a or b. If we cannot determine statically where p is pointing to at the time of the store operation, we create virtual definitions to mark that statement as a potential definition site for a and b. Memory loads are similarly marked with virtual use operands. Virtual operands are shown in tree dumps right before the statement that contains them. To request a tree dump with virtual operands, use the -vops option to -fdump-tree:

赋值语句*p=5可能是a或者b的定义。如果无法用静态分析手段在存储操作时确定p具体指向的到底是哪个变量,就创建一个虚定义,标记这个语句为“ab可能的定义位置”。内存的加载也相似地被打了虚操作符的标记。

虚操作符将在树的保存(tree dump)操作中写入输出的ssa文件,显示在文件中包含虚操作的语句之前。要获得这种带有虚操作符的分析结果,可以在-fdump-tree操作中加上-vops选项。

(译者注,完整语句是这样的:gcc -c -fdump-tree-ssa-vops file.c

输出结果:

{
  int a, b, *p;

  if ()
    p = &a;
  else
    p = &b;
  # a = VDEF <a>
  # b = VDEF <b>
  *p = 5;

  # VUSE <a>
  # VUSE <b>
  return *p;
}

Notice that VDEF operands have two copies of the referenced variable. This indicates that this is not a killing definition of that variable. In this case we refer to it as a may definition or aliased store. The presence of the second copy of the variable in the VDEF operand will become important when the function is converted into SSA form. This will be used to link all the non-killing definitions to prevent optimizations from making incorrect assumptions about them.

注意,VDEF操作数有引用变量的两个副本。这表明这不是该变量的终止定义(注销性定义)。在这种情况下,我们将其成为“可能”定义或别名存储。当函数被转换成SSA形式时,在VDEF操作数中存在变量的第二副本将变得很重要。这将用于链接所有非注销性定义,以防止优化过程对它们做出错误的假设。

Operands are updated as soon as the statement is finished via a call to update_stmt. If statement elements are changed via SET_USE or SET_DEF, then no further action is required (i.e., those macros take care of updating the statement). If changes are made by manipulating the statement’s tree directly, then a call must be made to update_stmt when complete. Calling one of the bsi_insert routines or bsi_replace performs an implicit call to update_stmt.

一旦语句完成,就会通过调用update_stmt更新操作数。如果通过SET_USE或SET_DEF更改语句元素,则不需要进一步的操作(也就是说,这些宏负责更新语句)。如果通过直接操作语句树进行更改,则必须在完成时调用update_stmt。调用一个bsi_insert例程或bsi_replace将隐式地调用update_stmt。

更多内容,请参阅原链接:https://gcc.gnu.org/onlinedocs/gccint/SSA-Operands.html#SSA-Operands

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值