Ошибка в ModulePass с установкой преемника BasicBlock

В следующем коде в LLVM

   unsigned ii=0;
BasicBlock* Bb = &*i;
TerminatorInst *TI = i->getTerminator();
    for( std::set<BasicBlock*>::iterator rit=Result.begin(); rit!=Result.end();++rit,++ii)
      {
    TI->setSuccessor(ii,(*rit));
    errs() << "\n\tBasic block (name=" <<(*rit)->getName() << ")";

      }

Код дает мне следующую ошибку, когда он реализован в модуле Pass

    Basic block (name=if.then)opt: /home/rasha/llvm2/llvm/include/llvm/IR
/Instructions.h:2406: void llvm::BranchInst::setSuccessor(unsigned int, llvm::BasicBlock
 *): Assertion `idx < getNumSuccessors() && "Successor # out of range for Branch!"' failed.

0  opt             0x00000000018895be llvm::sys::PrintStackTrace(_IO_FILE*) + 46

Есть ли критерии, которые я должен использовать, чтобы установить idx каждого базового блока в качестве преемника? Кроме того, он не выдает эту ошибку только после удаления приращения ii , но с неправильным результатом


person R.Omar    schedule 15.07.2013    source источник


Ответы (1)


Сначала вы должны использовать TI->getNumSuccessors(), чтобы убедиться, что этот терминатор поддерживает необходимое количество преемников.

Также имейте в виду, что если вы хотите добавить преемника сверх текущего числа преемников в терминаторе, вы не можете использовать setSuccessor — это может только изменить существующих преемников, а не добавить новых. Чтобы добавить новые, вам нужно использовать либо addCase, если это коммутатор, либо addDestination, если это непрямая ветвь. Никакие другие виды терминаторов не поддерживают неограниченное количество ветвей.

Кроме того, из сообщения об ошибке кажется, что вы пытаетесь использовать setSuccessor на BranchInst, у которого может быть не более двух преемников. Если вы хотите изменить CFG, я рекомендую сначала понять, как должны выглядеть ваши терминаторы.

person Oak    schedule 15.07.2013
comment
Я мог бы обнаружить, что базовый блок имеет один терминатор, проверив количество новых преемников, если они равны 1, тогда я мог бы использовать setSuccessor, но как проверить другие случаи?? - person R.Omar; 16.07.2013
comment
@ R.Omar Я не совсем понял ваш комментарий ... в частности, каждый базовый блок всегда имеет ровно один терминатор. Если вы хотите добавить больше преемников, чем терминатор уже может поддерживать, вам нужно использовать терминатор другого типа — см. мой 3-й абзац выше. - person Oak; 16.07.2013