BasicBlock succ iterator

Hi, All

I want to implement DSWP Which is used for parallelization of loops. For this purpose, the loop was replaced with a new basic block in main function.
And new functions were created and basic blocks of Loop assigned to them.I have checked blocks and branches for Succ and Pred relation and I have not found any problems.
However I get the following error:

opt: /home/llvm/src/include/llvm/Support/CFG.h:105: llvm::SuccIterator<Term_, BB_>::SuccIterator(Term_) [with Term_ = llvm::TerminatorInst*, BB_ = llvm::BasicBlock]: Assertion `T && “getTerminator returned null!”’ failed.
0 opt 0x0848e569
Stack dump:
*0. Program arguments: opt -dot-cfg -dot-postdom -dot-dom -load /home/llvm/src/Release/lib/*parallel.so -parallel obj.o -o out.o
1. Running pass ‘Function Pass Manager’ on module ‘obj.o’.
2. Running pass ‘Loop Pass Manager’ on function ‘@main
Aborted (core dumped)

I do not know why this error occurred.Who knows why this error occurs and what should I do?

Best regards
neda

Every basic block in LLVM is required to have a Terminator instruction (). I suspect that you’ve created a basic block without a Terminator instruction. Call the dump() method on all the basic blocks you added and see if they have a Terminator instruction. – John T.

This may also be a starting point for you. I think it was someone's
class project:
http://code.google.com/p/15745-project-dswp/

thank john,
i have used dump() , and each blocks had pred except entery block, i get the following output:

fun main entry
entry:
%retval = alloca i32
%0 = alloca i32
%i = alloca i32
%j = alloca i32
%a = alloca [2 x i32]
%n = alloca i32
%t = alloca i32
%“alloca point” = bitcast i32 0 to i32
%1 = getelementptr inbounds [2 x i32]* %a, i32 0, i32 0
%2 = load i32* getelementptr inbounds ([2 x i32]* @C.0.2045, i32 0, i32 0), align 4
store i32 %2, i32* %1, align 4
%3 = getelementptr inbounds [2 x i32]* %a, i32 0, i32 1
%4 = load i32* getelementptr inbounds ([2 x i32]* @C.0.2045, i32 0, i32 1), align 4
store i32 %4, i32* %3, align 4
store i32 2, i32* %n, align 4
store i32 0, i32* %j, align 4
br label %loop-replace

fun main loop-replace
loop-replace: ; preds = %entry
%5 = alloca [3 x i64]
%j_arg = ptrtoint i32* %j to i64
%6 = getelementptr [3 x i64]* %5, i64 0, i64 0
store i64 %j_arg, i64* %6
%t_arg = ptrtoint i32* %t to i64
%7 = getelementptr [3 x i64]* %5, i64 0, i64 1
store i64 %t_arg, i64* %7
%a_arg = ptrtoint [2 x i32]* %a to i64
%8 = getelementptr [3 x i64]* %5, i64 0, i64 2
store i64 %a_arg, i64* %8
call void @sync_init()
%9 = bitcast [3 x i64]* %5 to i64*
call void @sync_delegate(i32 0, i8* (i8*)* @“1_subloop_0”, i64* %9)
%10 = bitcast [3 x i64]* %5 to i64*
call void @sync_delegate(i32 1, i8* (i8*)* @“1_subloop_1”, i64* %10)
call void @sync_join()
br label %bb5

fun main bb5
bb5: ; preds = %loop-replace
%11 = load i32* @sum, align 4
store i32 %11, i32* %0, align 4
%12 = load i32* %0, align 4
store i32 %12, i32* %retval, align 4
br label %return

fun main return
return: ; preds = %bb5
%retval6 = load i32* %retval
ret i32 %retval6

fun 1_subloop_0 new-entry

new-entry:
call void @showPlace()
%1 = bitcast i8* %0 to i64*
%2 = getelementptr i64* %1, i64 0
%j_val = load i64* %2, align 8
call void @showValue(i64 %j_val)
%3 = trunc i64 %j_val to i32
%4 = inttoptr i64 %j_val to i32*
%5 = getelementptr i64* %1, i64 1
%t_val = load i64* %5, align 8
call void @showValue(i64 %t_val)
%6 = trunc i64 %t_val to i32
%7 = inttoptr i64 %t_val to i32*
%8 = getelementptr i64* %1, i64 2
%a_val = load i64* %8, align 8
call void @showValue(i64 %a_val)
%9 = trunc i64 %a_val to i32
%10 = inttoptr i64 %a_val to [2 x i32]*
br label %bb4_0

fun 1_subloop_0 bb1_0

bb1_0: ; No predecessors!
%c0 = call i64 @sync_consume(i32 0)
%c0_val = trunc i64 %c0 to i32
%t18_0 = load i32* @p, align 4
br label %bb3_0

fun 1_subloop_0 bb2_0
bb2_0: ; No predecessors!
br label %bb3_0

fun 1_subloop_0 bb3_0

bb3_0: ; preds = %bb4_0, %bb2_0, %bb1_0
%t3_0 = load i32* %7, align 4
%t4_0 = getelementptr inbounds [2 x i32]* %10, i32 0, i32 %t3_0
%t5_0 = load i32* %t4_0, align 4
%t6_0 = load i32* @sum, align 4
%t7_0 = add nsw i32 %t5_0, %t6_0
store i32 %t7_0, i32* @sum, align 4
%t9_0 = load i32* @sum, align 4
%t10_0 = call i32 (i8*, …)* @printf(i8* noalias getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %t9_0) nounwind
%t11_0 = load i32* %4, align 4
%t12_0 = add nsw i32 %t11_0, 1
store i32 %t12_0, i32* %4, align 4
br label %bb4_0

fun 1_subloop_0 bb4_0

bb4_0: ; preds = %bb3_0, %new-entry
%t0_0 = load i32* %4, align 4
%t1_0 = icmp sle i32 %t0_0, 9
br i1 %t1_0, label %bb3_0, label %new-exit

fun 1_subloop_0 new-exit

new-exit: ; preds = %bb4_0
ret i8* null

fun 1_subloop_1 new-entry

new-entry:
call void @showPlace()
%1 = bitcast i8* %0 to i64*
%2 = getelementptr i64* %1, i64 0
%j_val = load i64* %2, align 8
call void @showValue(i64 %j_val)
%3 = trunc i64 %j_val to i32
%4 = inttoptr i64 %j_val to i32*
%5 = getelementptr i64* %1, i64 1
%t_val = load i64* %5, align 8
call void @showValue(i64 %t_val)
%6 = trunc i64 %t_val to i32
%7 = inttoptr i64 %t_val to i32*
%8 = getelementptr i64* %1, i64 2
%a_val = load i64* %8, align 8
call void @showValue(i64 %a_val)
%9 = trunc i64 %a_val to i32
%10 = inttoptr i64 %a_val to [2 x i32]*
br label %bb4_1

fun 1_subloop_1 bb_1
bb_1: ; preds = %bb4_1
br i1 undef, label %bb1_1, label %bb2_1

fun 1_subloop_1 bb1_1

bb1_1: ; preds = %bb_1
%t15_1 = load i32* %7, align 4
%t16_1 = getelementptr inbounds [2 x i32]* %10, i32 0, i32 %t15_1
%t17_1 = load i32* %t16_1, align 4
%t19_1 = mul nsw i32 %t17_1, undef
%t19_1_64 = sext i32 %t19_1 to i64
call void @sync_produce(i64 %t19_1_64, i32 0)
store i32 %t19_1, i32* @p, align 4
br label %bb3_1

fun 1_subloop_1 bb2_1

bb2_1: ; preds = %bb_1
store i32 1, i32* @p, align 4
br label %bb3_1

fun 1_subloop_1 bb3_1

bb3_1: ; preds = %bb2_1, %bb1_1
br label %bb4_1

fun 1_subloop_1 bb4_1

bb4_1: ; preds = %bb3_1, %new-entry
br i1 undef, label %bb_1, label %new-exit

fun 1_subloop_1 new-exit

new-exit: ; preds = %bb4_1
ret i8* null

Hi neda,

i have used dump() , and each blocks had pred except entery block, i get the
following output:

maybe there are also some basic blocks that you created but forgot to add to
any function?

Ciao, Duncan.

Hi

I have checked all blocks, each block have a Terminator instruction and each blocks belongs to a function.
I’m really confused. I guess the problem is caused by the removal of the Loop,The code is as follows:

//every block to header (except the ones in the loop), will now redirect to newblock
for (pred_iterator PI = pred_begin(header); PI != pred_end(header); ++PI) {
BasicBlock *pred = *PI;
if (L->contains(pred)) {
continue;
}
TerminatorInst *termInst = pred->getTerminator();

for (unsigned i = 0; i < termInst->getNumOperands(); i++) {
BasicBlock *bb = dyn_cast (termInst->getOperand(i));
if (bb == header) {
termInst->setOperand(i,newBlock);
}
}
}

cout << “begin to delete loop” << endl;
for (Loop::block_iterator bi = L->block_begin(), bi2; bi != L->block_end(); bi = bi2)
{
bi2 = bi;
bi2++;
BasicBlock * BB = *bi;
for (BasicBlock::iterator ii = BB->begin(), ii2; ii != BB->end(); ii= ii2)
{
ii2 = ii;
ii2++;
Instruction *inst = ii;
inst->replaceAllUsesWith(UndefValue::get(inst->getType()));
inst->eraseFromParent();
}
for (pred_iterator PI = pred_begin(BB); PI != pred_end(BB); ++PI)
{
BasicBlock *pred = *PI;
if (!L->contains(pred))
continue;
pred->getTerminator()->eraseFromParent();
}
BB->eraseFromParent();
}

May this code be causing the problem?

Best regards
neda

Hi neda, general advice: (1) build LLVM with assertions enabled; (2) run your
pass under valgrind.

Ciao, Duncan.