【发布时间】:2020-06-16 05:55:45
【问题描述】:
这与Inserting a block between two blocks in LLVM 类似,但我不清楚解决方案描述 - 或者更好 - 我尝试按照描述的方式进行操作,但它不起作用(对我而言)。
我想做什么: 无论一个基本块有多于一个后继者,我都想插入一个基本块。 所以如果基本块A有条件跳转到B或C,我想在A和B之间以及A和C之间插入一个基本块。如果有跳转表,它也应该工作。
所以我要做的是:
while (...) {
// get next basic block and ensure it has at least 2 successors:
BasicBlock *origBB = getNextBB();
Instruction *TI = origBB->getTerminator()
if (!TI || TI->getNumSuccessors() < 2)
continue;
// collect successors:
std::vector<BasicBlock *> Successors;
for (succ_iterator SI = succ_begin(origBB), SE = succ_end(origBB); SI != SE; ++SI) {
BasicBlock *succ = *SI;
Successors.push_back(succ);
}
// now for each successor:
for (uint32_t i = 0; i < Successors.size(); i++) {
// Create a new basic block
BasicBlock *BB = BasicBlock::Create(C, "", &F, nullptr);
// F.getBasicBlockList().push_back(BB); <= this did not work, seem to result in endless loop
IRBuilder<> IRB(BB);
// put instructions into BB
... // omitted
// then add the terminator:
IRB.CreateBr(Successors[i]);
// Now we have to fix the original BB to our new basic block:
TI->setSuccessor(i, BB);
}
}
当我运行这个 LLVM 通道时,我收到以下错误:
PHI node entries do not match predecessors!
好的,所以我想我必须从后继者中删除相应的前任,并在 setSuccessor() 之后添加以下代码:
origBB->replaceSuccessorsPhiUsesWith(Successors[j], BB);
BasicBlock *S = Successors[i];
S->removePredecessor(origBB);
然后我得到错误Instruction does not dominate all uses!
我确信解决方案非常简单 - 但我找不到它:-(
非常感谢任何帮助或指点!
【问题讨论】:
-
Phi 节点问题可以通过查看 SI 中的 phi 节点来解决,如果有引用 origBB,则让它们引用 BB。或者您可以使用llvm::splitBlock(succ),它会为您处理几乎所有事情。
-
如何查看后继节点的 phi 节点?以及如何纠正它们?我需要一个指向函数调用的指针:)。我不能使用 splitBlock(我认为),因为它不是拆分块,而是将块插入到不同的边缘。
-
您可以在 splitBlock() 中查看如何更正 phi 节点的示例。