2015-09-23 25 views
5

LLVMバイトコードで簡単なループを見つけて、ループの基本情報( )を抽出します。例えばLLVMバイトコードでループを見つける

for (i=0; i<1000; i++) 
    sum += i; 

私が結合した[0、1000)、ループ変数 "i" のと ループ本体(合計+ = Iを抽出したいです)。
どうすればよいですか?

私はLLVM APIドキュメントを読んで、 "Loop"、 "LoopInfo"のような有用なクラスを見つけました。
しかし、私は詳細にそれらを使用する方法がわかりません。

私に助けてもらえますか?詳しい使い方が役立つかもしれません。

答えて

5

あなたがパス・マネージャを使用しない場合、あなたはLLVM ::で分析メソッドを呼び出す必要があるかもしれませんが(あなたはLLVM-3.4を使用していると仮定)IRの各機能にクラスをLoopInfoBase。しかし、Analyzeメソッドは各関数のDominatorTreeを入力として受け取ります。これは最初に生成する必要があります。以下のコードは、私がLLVM-3でテストするものです。4(あなたはIRファイルを読み込み、モジュールとして名前モジュール*にそれを変換したと仮定した場合):基本的に

for(llvm::Module::iterator func = module->begin(), y=module->end(); func!=y; func++){ 
     //get the dominatortree of the current function 
     llvm::DominatorTree* DT = new llvm::DominatorTree();   
     DT->DT->recalculate(*func); 
     //generate the LoopInfoBase for the current function 
     llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>* KLoop = new llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>(); 
     KLoop->releaseMemory(); 
     KLoop->Analyze(DT->getBase());   
} 

、KLoopが発生したと、あなたはIRレベルでLOOP情報のすべての種類を取得します。詳細については、LoopInfoBaseクラスのAPIを参照できます。ところで、次のヘッダーを追加することができます。 "llvm/Analysis/LoopInfo.h" "llvm/Analysis/Dominators.h"

+0

ありがとう、それはうまく動作します:) – Napoleon

1

LLVMはただのライブラリです。そこにASTノードはありません。

LLVMの上に構築されたコンパイラであるClangを見てみることをお勧めします。

thisはお探しの商品ですか?

1

Matteoと同様に、LLVMがループ変数と条件を認識できるようにするには、ファイルをLLVM IRにする必要があります。質問は、あなたがLLVMバイトコードでそれを持っていると言うが、LLVM IRは、SSA形式で書かれているので、「ループ変数」の話は本当にではありません。あなたが何をしようとしているのか、どんなタイプの結果が期待できるのか、私たちがさらに助けてくれると思うなら、私は確信しています。

あなたが始めるのに役立ついくつかのコード:

virtual void getAnalysisUsage(AnalysisUsage &AU) const{ 
     AU.addRequired<LoopInfo>(); 
    } 

    bool runOnLoop(Loop* L, LPPassManager&){ 
     BasicBlock* h = L->getHeader(); 
     if (BranchInst *bi = dyn_cast<BranchInst>(h->getTerminator())) { 
      Value *loopCond = bi->getCondition(); 
     } 
     return false; 
    } 

このコードスニペットは、通常のLLVMパスの内側からです。

+1

ありがとう、アンドレアス。しかし、私はLLVMパスを書くのに慣れていません。私はいつもLLVMライブラリ関数を使って変換プログラムを書く。入力はLLVMバイトコードファイルで、出力は変更されたバイトコードファイルです。 LLVMのパスを変換プログラムに変更する方法はありますか? – Napoleon

2

LLVM IRレベルに達すると、要求された情報が正確でなくなることがあります。たとえば、clangがコードを変換して、-1000から0に変わる可能性があります。あるいは、 "i"を完全に最適化して、明示的な誘導変数がないようにすることもできます。あなたは本当にそれがCコードで額面で言うように正確な情報を抽出する必要がある場合は、打ち鳴らすを見る必要はなく、LLVM IR。そうでなければ、あなたができる最善のは、その場合には、ScalarEvolutionパスを見て、ループのトリップカウントを計算することです。

のPowerPCハードウェアをチェックはかなりよくトリップ数の計算を示していた変換パスを、ループ:http://llvm.org/docs/doxygen/html/PPCCTRLoops_8cpp_source.html

コードはかなり重いですが、追従可能でなければなりません。興味深い関数はPPCCTRLoops :: convertToCTRLoopです。それ以上の質問があれば、私はそれらに答えることができます。

0

Junxzmの回答に関するちょっとした更新、いくつかの参照、ポインタ、およびメソッドがLLVM 3.5に変更されました。

for(llvm::Module::iterator f = m->begin(), fe=m->end(); f!=fe; ++f){ 
     llvm::DominatorTree DT = llvm::DominatorTree(); 
     DT.recalculate(*f); 
     llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>* LoopInfo = new llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>(); 
     LoopInfo->releaseMemory(); 
     LoopInfo->Analyze(DT);  
     } 
関連する問題