LLVM分支操作目标操作数提取及分支操作数参数用途咨询
Value fval = other ? otherval : zeroVal; rewriter.create<LLVM::CondBrOp>(loc, pred, block1, block2, fval); rewriter.setInsertionPointToEnd(block1); Value trueVal = load(pElem); rewriter.create<LLVM::BrOp>(loc, trueVal, block2); rewriter.setInsertionPointToEnd(block2); lvals.push_back(val); // SmallVector
问题解答
一、根据分支走向提取正确的val
这是SSA形式下典型的汇合块值处理场景,必须用PHI节点来统一不同分支的输入值,步骤如下:
- 在设置
block2的插入点之前,先创建一个PHI节点,类型需与fval、trueVal一致:rewriter.setInsertionPointToStart(block2); auto phi = rewriter.create<LLVM::PHIOp>(loc, fval.getType()); - 给PHI节点添加两个分支的输入值,分别对应各自的前驱块:
- 从
CondBrOp直接跳转的分支,输入值为fval,前驱是CondBrOp所在的基本块(假设当前块为currBlock) - 从
block1跳转的分支,输入值为trueVal,前驱是block1
代码实现:
phi.addIncoming(fval, currBlock); phi.addIncoming(trueVal, block1); - 从
- 最后将
lvals.push_back的参数替换为该PHI节点:lvals.push_back(phi);
当程序流进入block2时,PHI节点会自动根据实际分支走向选取对应的fval或trueVal。
二、LLVM分支操作的目标操作数提取与参数用途
1. 提取目标操作数
针对你用到的两种分支操作:
LLVM::CondBrOp(条件分支):- 调用
getTrueDest()获取条件为真时的目标块,getFalseDest()获取条件为假时的目标块; - 调用
getOperands()获取所有操作数,其中第0位是分支条件,第1、2位是true/false目标块,后续操作数为跳转时传递给目标块的参数。
- 调用
LLVM::BrOp(无条件分支):- 调用
getDest()获取跳转的目标块; getOperands()返回的列表中,最后一位是目标块,前面的均为跳转时传递给目标块的参数。
- 调用
2. 分支操作数的用途
CondBrOp的操作数:- 第0位:布尔类型的分支判断条件,决定程序流走向true或false目标块;
- 第1、2位:两个候选目标基本块,对应条件成立/不成立时的跳转目标;
- 后续操作数:跳转时传递给目标块PHI节点的输入值,需与目标块PHI节点的入参数量、类型完全匹配。
BrOp的操作数:- 最后一位:唯一的目标基本块;
- 前面的操作数:跳转时传递给目标块PHI节点的输入值,用于在SSA形式下为汇合块提供分支专属的数值。
内容的提问来源于stack exchange,提问作者rohitsan
相关产品推荐
相关产品推荐

