2013-07-15 2 views
0

В следующем коде в LLVMОшибка в ModulePass с установкой преемником BasicBlock

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, но с неправильным результатом

ответ

2

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

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

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

+0

Я мог обнаружить, что базовый блок имеет один терминатор, проверяя число новых преемников, если они равны 1, тогда я мог бы использовать setSuccessor, но как проверить другие случаи? –

+0

@ R.Omar Я не совсем понял ваш комментарий ... в частности, каждый базовый блок всегда имеет ровно один терминатор. Если вы хотите добавить больше преемников, чем терминатор может уже поддерживать, вам нужно использовать другой тип терминатора - см. Мой третий абзац выше. – Oak