如何在LLVM中的两个块之间插入基本块
这与解决方案描述相似,但我不清楚——或者更好——我试图按照描述的方式来做,但它不起作用(对我来说) 我想做的是: 如果一个基本块有多个后续块,我想插入一个基本块。 所以,如果基本块A有条件地跳转到B或C,我想在A和B之间以及A和C之间插入一个基本块。如果有跳转表,它也应该工作 所以我要做的是:如何在LLVM中的两个块之间插入基本块,llvm,llvm-ir,Llvm,Llvm Ir,这与解决方案描述相似,但我不清楚——或者更好——我试图按照描述的方式来做,但它不起作用(对我来说) 我想做的是: 如果一个基本块有多个后续块,我想插入一个基本块。 所以,如果基本块A有条件地跳转到B或C,我想在A和B之间以及A和C之间插入一个基本块。如果有跳转表,它也应该工作 所以我要做的是: while (...) { // get next basic block and ensure it has at least 2 successors: BasicBlock *origBB
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);
}
}
然而,我得到的错误指令并不是支配所有用途代码>
我确信解决方案非常简单,但我找不到:-(
非常感谢您的帮助和指点!好的,我在这里回答我自己的问题
建议a)使用splitBlock()的注释方向错误,因为它是关于插入到边中,因此结果将是错误的。b) 更新phi实际上可以解决这个问题。然而,这是非常复杂的,因为不能使用简单的replacephiusswith
——如果a->B和a是循环头,B是循环尾(因此返回到B),则会导致编译错误,因此必须仔细评估所有的PHI
因此,解决方案实际上非常简单,我在浏览llvm:SplitEdge()的源代码时发现了这一点。它完全符合我的要求,在两个基本块的边缘之间插入一个基本块
这并不明显,因为该函数未记录在doxygen类列表中,因此除了通过浏览源代码和包含外,找不到它
下面是如何使用它:
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
void inYourFunction() {
...
// Insert the new block into the edge between thisBB and a successorBB
BasicBlock *insertedBB = SplitEdge(thisBB, successorBB);
if (!insertedBB) {
// SplitEdge can fail, e.g. if the successor is a landing pad
return;
}
// Then put instructions into the new BB
BasicBlock::iterator IP = newBB->getFirstInsertionPt();
IRBuilder<> IRB(&(*IP));
// and then work with IRB
// You need not to take care of the branch to successorBB - it is already there
...
}
#包括“llvm/Transforms/Utils/BasicBlockUtils.h”
函数()中的void{
...
//将新块插入此BB和成功块B之间的边缘
BasicBlock*insertedBB=SplitEdge(thisBB,successorBB);
如果(!insertedBB){
//SplitEdge可能会失败,例如,如果后继设备是着陆台
返回;
}
//然后将说明放入新的BB中
基本块::迭代器IP=newBB->getFirstInsertionPt();
内部评级机构内部评级(&(*IP));
//然后与IRB合作
//你不需要照顾成功的分支机构B-它已经在那里了
...
}
就是这样,就这么简单。好的,我在这里回答我自己的问题
建议a)使用splitBlock()的注释方向错误,因为它是关于插入到边中,因此结果将是错误的。b) 更新phi实际上可以解决这个问题。然而,这是非常复杂的,因为不能使用简单的replacephiusswith
——如果a->B和a是循环头,B是循环尾(因此返回到B),则会导致编译错误,因此必须仔细评估所有的PHI
因此,解决方案实际上非常简单,我在浏览llvm:SplitEdge()的源代码时发现了这一点。它完全符合我的要求,在两个基本块的边缘之间插入一个基本块
这并不明显,因为该函数未记录在doxygen类列表中,因此除了通过浏览源代码和包含外,找不到它
下面是如何使用它:
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
void inYourFunction() {
...
// Insert the new block into the edge between thisBB and a successorBB
BasicBlock *insertedBB = SplitEdge(thisBB, successorBB);
if (!insertedBB) {
// SplitEdge can fail, e.g. if the successor is a landing pad
return;
}
// Then put instructions into the new BB
BasicBlock::iterator IP = newBB->getFirstInsertionPt();
IRBuilder<> IRB(&(*IP));
// and then work with IRB
// You need not to take care of the branch to successorBB - it is already there
...
}
#包括“llvm/Transforms/Utils/BasicBlockUtils.h”
函数()中的void{
...
//将新块插入此BB和成功块B之间的边缘
BasicBlock*insertedBB=SplitEdge(thisBB,successorBB);
如果(!insertedBB){
//SplitEdge可能会失败,例如,如果后继设备是着陆台
返回;
}
//然后将说明放入新的BB中
基本块::迭代器IP=newBB->getFirstInsertionPt();
内部评级机构内部评级(&(*IP));
//然后与IRB合作
//你不需要照顾成功的分支机构B-它已经在那里了
...
}
就是这样,就这么简单。可以通过查看SI中的Phi节点来解决Phi节点问题,如果有任何节点指向origBB,请将它们改为指向BB。或者你可以使用,这将为你处理几乎所有的事情。我如何在继承者的phi节点上做到这一点?如何纠正它们?我需要一个指向函数调用的指针:)。我不能使用splitBlock(我想),因为它不是关于分割块,而是将一个块插入一条不同的边。你可以在splitBlock()中看到一个如何更正phi节点的示例。phi节点问题可以通过查看SI中的phi节点来解决,如果有引用origBB的节点,则将它们改为引用BB。或者你可以使用,这将为你处理几乎所有的事情。我如何在继承者的phi节点上做到这一点?如何纠正它们?我需要一个指向函数调用的指针:)。我不能使用splitBlock(我想),因为它不是关于分割块,而是将一个块插入到一条不同的边中。您可以在splitBlock()中看到一个如何更正phi节点的示例。