【问题标题】:LLVM insert if/else into existing basic blockLLVM 将 if/else 插入现有的基本块
【发布时间】:2016-10-28 21:06:48
【问题描述】:

我想在运行时检查某些指令的值。因此,我创建了一个比较指令和一个分支指令,它们分支到“then”基本块或“else”基本块。但是,我不确定如何在条件分支之后插入创建的基本块,以及现有基本块的拆分如何工作。

Instruction* someInst;
IRBuilder<> B(someInst);

Value* condition = B.CreateICmp(CmpInst::ICMP_UGT, someInst, someValue);

BasicBlock* thenBB = BasicBlock::Create(*ctx, "then");
BasicBlock* elseBB = BasicBlock::Create(*ctx, "else");

B.CreateCondBr(condition, thenBB, elseBB);

B.SetInsertPoint(thenBB);
//insert stuff

B.SetInsertPoint(elseBB);
//insert stuff

如何在现有基本块的中间插入 if/else?

【问题讨论】:

    标签: llvm llvm-ir llvm-c++-api


    【解决方案1】:

    简短回答:您可能可以使用llvm::SplitBlockAndInsertIfThenElse。不要忘记您的 PHI 节点。

    根据维基百科,basic block

    是一个直线代码序列,除了入口没有分支,除了出口没有分支。

    因此,if-then-else 涉及多个块:

    1. 包含条件的块,
    2. then 块
    3. else 块
    4. (可选)then 和 else 块之后的块(如果 then 和 else 不返回或分支到别处)。

    要插入 if-then-else,必须将原始基本块拆分为 (1) 和 (4)。条件检查和条件分支进入(1),(2)和(3)以分支到(4)结束。 SplitBlockAndInsertIfThenElse 函数 (docs) 将在简单的情况下为您执行此操作。如果您有更复杂的要求 - 例如 then 或包含自己的控制流 - 您可能需要自己进行拆分。

    如果您的 then 或 else 块修改变量,您将需要一个 PHI 节点。 Kaleidoscope tutorial 解释了为什么需要 PHI 节点以及如何使用它们。教程参考了Single Static Assignment维基百科的文章,很有用的背景。

    【讨论】:

    • SplitBlockAndInsertIfThenElse 在所有情况下都足够了。它返回指向两个新块的终止符的指针,您可以将它们用作插入点来插入您想要的任何指令,包括您可能想要的任何控制流。
    • 我误会了吗?
    • SplitBlockAndInsertIfThenElse 创建的 then 和 else 块有一个终止分支指令。一个有效的基本块在终止分支之前不能包含分支指令(即控制流),还是我误解了?
    • 您可以拆分 then 和 else 块,就像拆分初始块一样。
    【解决方案2】:

    您可以使用一个名为llvm::SplitBlockAndInsertIfThenElse 的辅助函数。你需要#include "llvm/Transforms/Utils/BasicBlockUtils.h"

    【讨论】:

      猜你喜欢
      • 2022-01-03
      • 1970-01-01
      • 2013-08-10
      • 2020-06-16
      • 2011-07-17
      • 1970-01-01
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      相关资源
      最近更新 更多