Это похоже на Вставка блока между двумя блоками в LLVM , однако описание решения мне неясно - или лучше - я пытался сделать это, как описано, но это не работает (для меня).
Что я хочу сделать: где бы у блока basi c было более одного преемника, я хочу вставить блок basi c. Поэтому, если базовый c блок A выполняет условный переход к B или C, я хочу вставить базовый 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!
Я уверен, что решение очень простое - но я не могу его найти: - (
Большое спасибо за любую помощь или указатели!