1
我在做一些基本的循環轉換練習的llvm。 目標循環我想變換是如下:使用llvm做循環展開,分割塊失敗
int main()
{
int j=0,i=0;
int x[100][5000] = {0};
for (i = 0; i < 100; i = i+1){
for (j = 0; j < 5000; j = j+1){
x[i][j] = 2 * x[i][j];
}
}
return 0;
}
此代碼的IR已經嵌套循環結構是這樣:
entry:
....
for.cond:
....
for.body:
....
for.cond1:
....
for.body3:
....
for.inc:
....
for.end:
當我想展開內環這是。 cond1,for.body3和for.inc這三部分。我第一次在指令分支分裂for.body3,然後想在兩者之間插入新展開塊:
%3 = load i32* %j, align 4
%idxprom = sext i32 %3 to i64
%4 = load i32* %i, align 4
%idxprom4 = sext i32 %4 to i64
%arrayidx = getelementptr inbounds [5000 x [100 x i32]]* %x, i32 0, i64 %idxprom4
%arrayidx5 = getelementptr inbounds [100 x i32]* %arrayidx, i32 0, i64 %idxprom
%5 = load i32* %arrayidx5, align 4
%mul = mul nsw i32 2, %5
%6 = load i32* %j, align 4
%idxprom6 = sext i32 %6 to i64
%7 = load i32* %i, align 4
%idxprom7 = sext i32 %7 to i64
%arrayidx8 = getelementptr inbounds [5000 x [100 x i32]]* %x, i32 0, i64 %idxprom7
%arrayidx9 = getelementptr inbounds [100 x i32]* %arrayidx8, i32 0, i64 %idxprom6
store i32 %mul, i32* %arrayidx9, align 4
// insert new blocks here
br label %for.inc
但是,當我給insrtuction在我傳球,我得到了錯誤。
我的指令:
BasicBlock *bb_new = bb->splitBasicBlock(inst_br);
錯誤:
Assertion (`HasInsideLoopSuccs && "Loop block has no in-loop successors!)
任何人都熟悉LLVM能告訴我是什麼問題?還是我有其他方法來分割塊並插入展開的塊?
的HasInsideLoopSuccs被設定在以下LoopInfoImpl.h
// Check the individual blocks.
for (; BI != BE; ++BI) {
BlockT *BB = *BI;
bool HasInsideLoopSuccs = false;
bool HasInsideLoopPreds = false;
SmallVector<BlockT *, 2> OutsideLoopPreds;
typedef GraphTraits<BlockT*> BlockTraits;
for (typename BlockTraits::ChildIteratorType SI =
BlockTraits::child_begin(BB), SE = BlockTraits::child_end(BB);
SI != SE; ++SI)
if (contains(*SI)) {
HasInsideLoopSuccs = true;
break;
}
11/26加:這是我的通行證。
class IndependentUnroll : public llvm::LoopPass
{
public:
virtual void unroll(llvm::Loop *L){
for (Loop::block_iterator block = L->block_begin(); block !=
L->block_end(); block++) {
BasicBlock *bb = *block;
/* Handle loop body. */
if (string(bb->getName()).find("for.body3") !=string::npos) {
Instruction *inst = &bb->back();
BasicBlock *new_bb = bb->splitBasicBlock(inst);
/*Then the code get crashed!*/
}
}
}
IndependentUnroll() : llvm::LoopPass(IndependentUnroll::ID) { }
virtual bool runOnLoop(llvm::Loop *L, llvm::LPPassManager &LPM) {
if (L->getLoopDepth() == 1){
unroll(L);
}
}
static char ID;
};
對不起,這是一個錯字。 (j = j + 1)是正確的 – 2014-11-27 05:54:24