【发布时间】:2012-11-07 18:09:52
【问题描述】:
我想在 LLVM 的两个基本块之间插入一个块。例如,如果一个基本块 A 正在跳转到基本块 B,我想在它们之间插入一个基本块 C,以便 A 跳转到 C,C 跳转到 B。我该怎么做?我确实有基本的想法,我需要改变基本块A的终止指令,使得目标B被C替换,但是我该如何继续在其间添加新的基本块C呢?
【问题讨论】:
标签: c++ c compiler-construction llvm
我想在 LLVM 的两个基本块之间插入一个块。例如,如果一个基本块 A 正在跳转到基本块 B,我想在它们之间插入一个基本块 C,以便 A 跳转到 C,C 跳转到 B。我该怎么做?我确实有基本的想法,我需要改变基本块A的终止指令,使得目标B被C替换,但是我该如何继续在其间添加新的基本块C呢?
【问题讨论】:
标签: c++ c compiler-construction llvm
是的,您需要更改(或替换)基本块 A 的终止指令 - 例如,如果它是分支,则可以使用 BranchInst::setSuccessor()。然后创建基本块 C 并确保其终止指令跳转到 B,这将使其介于两者之间。
你需要做的就是改变终结者的目标——你不需要重新排列内存中的块顺序或类似的东西。
但是,您必须注意,您需要担心两个特殊说明 - phi 节点和着陆台。
Phi 节点仅指块的直接前任。这意味着如果在 A 和 B 之间插入 C,则必须通过删除它们或使它们引用 C 而不是 A 来修复 B 中的所有 phi 节点。
如果 B 是一个landingpad 块(包含一个landingpad 指令),只有从invoke 指令的展开目标直接跳转到它才是合法的。如果从 A 到 B 的跳跃是通过展开目标,则不能在其间添加基本块,除非将 C 本身变成一个着陆区并从 B 移除着陆区。
【讨论】:
BranchInst 的目标之一的目标标签)
有一个函数叫做llvm::splitEdge。它完全符合问题的要求。
【讨论】: