2014-11-24 51 views
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; 

}; 

回答

0

你內心的循環是:

for (j = 0; j < 5000; j = i+1) { 

你的意思的增量爲:

j = j + 1 

爲了避免無限循環?

+0

對不起,這是一個錯字。 (j = j + 1)是正確的 – 2014-11-27 05:54:24