llvm學習日記十三:PassManager 注冊pass

參考:http://www.alonemonkey.com/2016/12/21/learning-llvm/

一、目的:

寫入opt和clang的命令參數,可以直接參數指定調用

二、使用pass

把上一小節的pass稍加修改

  • 創建頭文件:include/llvm/Transforms/CountOpcode/CountOpcode.h
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Instructions.h"
#include "llvm/InitializePasses.h"

#define DEBUG_TYPE "opcodecounter"

namespace llvm {
    FunctionPass *createCountOpcodePass();
//    void initializeCountOpcodePass(PassRegistry &Registry);
}
  • cpp文件:lib/Transforms/CountOpcode/CountOpcode.cpp
#include "llvm/Transforms/CountOpcode/CountOpcode.h"

using namespace llvm;

static cl::opt<bool> EnableCountOpcode("opcodeCounter2", cl::init(false),
                                 cl::desc("Count opcode number"));

namespace llvm {
    struct CountOpcode : public FunctionPass {
        std::map<std::string,int> opcodeCounter;
        static char ID;
        CountOpcode() : FunctionPass(ID){}
        virtual bool runOnFunction(Function &F) {
            if(!EnableCountOpcode){
                return false;
            }
            errs()<<"FunctionName:"<<F.getName()<<"\n";
            for(Function::iterator bb = F.begin(),e = F.end();bb!=e;++bb){
                for(BasicBlock::iterator i = bb->begin(),ie = bb->end();i!=ie;++i){
                    if(opcodeCounter.find(i->getOpcodeName()) == opcodeCounter.end()){
                        opcodeCounter[i->getOpcodeName()] =1;
                    }else{
                        opcodeCounter[i->getOpcodeName()] +=1;
                    }
                }
            }
            std::map<std::string,int>::iterator ib = opcodeCounter.begin();
            std::map<std::string,int>::iterator ie = opcodeCounter.end();
            while (ib != ie) {
                errs() << ib->first << " : " << ib->second << "\n";
                ib++;
            }
            errs()<<"\n";
            opcodeCounter.clear();
            return false;
        }
        
    };
    FunctionPass * createCountOpcodePass(){
        return new CountOpcode();
    }

}

char CountOpcode::ID = 0;
//static RegisterPass<CountOpcode> X("opcodeCounter", "Count opcode number", false, false);
INITIALIZE_PASS(CountOpcode, "opcodeCounter", "Count opcode number", false, false)

  • 創建LLVMBuild.txt : lib/Transforms/CountOpcode/LLVMBuild.txt
[component_0]
type = Library
name = CountOpcode
parent = Transforms
library_name = CountOpcode
  • 創建CMakeLists.txt : lib/Transforms/CountOpcode/CMakeLists.txt

add_llvm_library( LLVMCountOpcode
  CountOpcode.cpp

  DEPENDS
  intrinsics_gen
  )

  • lib/Transforms/CMakeLists.txt
add_subdirectory(CountOpcode)
  • lib/Transforms/LLVMBuild.txt 加上我們的pass
[common]
subdirectories = AggressiveInstCombine Coroutines IPO InstCombine Instrumentation Scalar Utils Vectorize ObjCARC CountOpcode
  • PassManager 注冊
  • lib/Transforms/IPO/PassManagerBuilder.cpp 添加頭文件:
#include "llvm/Transforms/CountOpcode/CountOpcode.h"
  • lib/Transforms/IPO/PassManagerBuilder.cpp 函數 populateModulePassManager 添加:
MPM.add(createCountOpcode());
  • lib/Transforms/IPO/LLVMBuild.txt 添加:
required_libraries = AggressiveInstCombine Analysis BitReader BitWriter Core InstCombine IRReader Linker Object ProfileData Scalar Support TransformUtils Vectorize Instrumentation CountOpcode
  • 相關頭文件修改:
    llvm/LinkAllPasses.h 頭文件添加:
    #include "llvm/Transforms/CountOpcode/CountOpcode.h"
    (void) llvm::createCountOpcodePass();
    llvm/InitializePasses.h 頭文件添加:
    void initializeCountOpcodePass(PassRegistry&);
  • opt命令參數添加:
    initializeCountOpcodePass(Registry);

最后分別編譯opt和clang。

  • 編譯可能的問題:
  1. 最終鏈接找不到新pass的符號,需要在鏈接flag配置新創建pass庫的路徑:
    ld: symbol(s) not found for architecture x86_64
    如下配置鏈接庫:
    image.png

四、opt 和 clang執行:

  • opt 參數與運行結果:


    image.png
image.png
  • clang 參數與運行結果:


    image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容

  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 2,718評論 0 3
  • 近來,ollvm在國內移動安全,尤其是安全加固上的使用越來越廣泛,ollvm的混淆和反混淆也被視為比較高等的知識之...
    that_is_this閱讀 3,010評論 4 0
  • Swift介紹 Swift是一種高性能的語言,擁有整潔現代的語法。swift可以和C、OC的代碼和框架無縫銜接,并...
    sea_biscute閱讀 6,206評論 2 22
  • http://www.starming.com/index.php?v=index&view=107 http:/...
    111浪子111閱讀 3,172評論 0 11
  • PS: Clang為LLVM提供的C語言編譯器,默認參數可以生成本機可執行的二進制程序。-S和-c參數與GCC一樣...
    HAPPYers閱讀 4,637評論 0 2