PHI Instruction&&PHI Node

PHI指令

PHI指令是一种在编译器中使用的指令,用于在控制流程图中实现条件分支和循环等结构。PHI指令通常在基本块的起始位置出现,用于选择控制流程图中的路径。

在控制流程图中,PHI指令通常用于选择从不同分支中返回的值。例如,如果一个函数中有一个if-else语句,其中每个分支都返回不同的值,那么PHI指令可以用于选择哪个值应该被返回。

PHI指令通常用于静态单赋值形式(SSA)编译器中,其中每个变量只被赋值一次。在SSA中,PHI指令用于将来自不同分支的变量值合并为一个值,从而保证程序的正确性。

entry:
  %cond = icmp eq i32 %a, 0
  br i1 %cond, label %ifblock, label %elseblock

ifblock:
  %x = add i32 %a, 1
  br label %mergeblock

elseblock:
  %y = sub i32 %a, 1
  br label %mergeblock

mergeblock:
  %result = phi i32 [ %x, %ifblock ], [ %y, %elseblock ]
  ret i32 %result

在这个例子中,我们有一个接受整数参数“%a”的函数。 该函数从“entry”块开始,我们在此处使用条件分支(“icmp eq i32 %a, 0”)来确定“%a”是否等于零。 如果是,我们跳转到 ifblock 块,我们将 1 添加到 %a 。 否则,我们跳转到 elseblock 块,在那里我们从 %a 中减去 1。

在 `ifblock` 和 `elseblock` 块之后,我们跳转到 `mergeblock` 块,我们使用 PHI 指令根据所采用的分支选择要返回的值。 在这种情况下,我们合并 `%x`(在 `ifblock` 块中添加到 `%a` 的值)和 `%y`(在 `elseblock` 块中从 `%a` 减去的值)得到 最终结果“%result”。 最后,我们返回 %result 。

请注意,PHI 指令将值块对列表作为参数,其中每一对对应于一个可能导致当前块的分支。 在此示例中,我们使用“[ %x, %ifblock ]”和“[ %y, %elseblock ]”作为“mergeblock”的值块对。

PHI Node

在编译器中,PHI Node 是一种用于表示控制流程图中的条件分支或循环结构的节点。它通常出现在基本块的起始位置,并且用于选择控制流程图中的路径。

在控制流程图中,PHI Node 通常用于选择从不同分支中返回的值。例如,在一个函数中有一个if-else语句,其中每个分支都返回不同的值,那么PHI Node 可以用于选择哪个值应该被返回。

PHI Node 是基本块中的一种特殊指令,它可以有多个输入,并且每个输入都与基本块的前继节点相关联。在基本块中,PHI Node 的输出是一个合并了来自不同前继节点的值的变量。这个变量将在基本块的其余部分中使用。

PHI Node 通常用于静态单赋值形式(SSA)编译器中,其中每个变量只被赋值一次。在SSA中,PHI Node 用于将来自不同前继节点的变量值合并为一个值,从而保证程序的正确性。

entry:
  %cond = icmp eq i32 %a, 0
  br i1 %cond, label %ifblock, label %elseblock

ifblock:
  %x = add i32 %a, 1
  br label %mergeblock

elseblock:
  %y = sub i32 %a, 1
  br label %mergeblock

mergeblock:
  %result = phi i32 [ %x, %ifblock ], [ %y, %elseblock ]
  ret i32 %result

在这个例子中,我们有一个循环递增 `%a` 的值直到它达到 10。我们从 `entry` 块开始,我们在堆栈上为整数 `%a` 分配空间并将其初始化为 0 .

然后我们跳转到 `loop` 块,我们从 `%a` 加载 `%i` 并检查它是否小于 10。如果是,我们跳转到 `body` 块,在这里我们将 1 加到 ` %i 并将结果存储到 %a 中。 然后我们跳回 `loop` 块继续循环。

当 %i 不再小于 10 时,我们跳转到 exit 块,我们将 %a 的最终值加载到 %result 并返回它。 但是,由于在循环期间在 body 块中更新了 %a,我们需要使用 PHI 节点来确定 %a 的正确值以加载到 exit 块中。

PHI 节点如下所示:

%a.phi = phi i32 [ 0, %entry ], [ %j, %body ]

该 PHI 节点将值块对列表作为参数,其中每一对对应于一个可能通向当前块的分支。 在这种情况下,我们使用 `[ 0, %entry ]` 和 `[ %j, %body ]` 作为 `exit` 块的值块对。

PHI 节点告诉编译器在循环尚未开始时使用在 entry 块中初始化为 0 的 %a 的值,并使用 %j 的值( % 当循环至少运行一次时,i` 加上 1) 来自 `body` 块。 这确保我们获得 %a 的正确最终值以在循环结束时返回。

你可能感兴趣的:(笔记,LLVM,llvm)