ollvm源码分析 - Pass之SplitBaiscBlocks
Posted 看雪学院
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ollvm源码分析 - Pass之SplitBaiscBlocks相关的知识,希望对你有一定的参考价值。
All LLVM passes are subclasses of the Pass class, which implement functionality by overriding virtual methods inherited from Pass. Depending on how your pass works, you should inherit from the ModulePass , CallGraphSCCPass, FunctionPass , or LoopPass, or RegionPass, or BasicBlockPass classes, which gives the system more information about what your pass does, and how it can be combined with other passes. One of the main features of the LLVM Pass Framework is that it schedules passes to run in an efficient way based on the constraints that your pass meets (which are indicated by which class they derive from).
我粗略的翻译一下:所有的LLVM Pass都是Pass这个类的子类,这些Pass继承自Pass类,然后通过实现Pass类的虚函数来实现自身的功能。如果你要自己实现一个Pass, 那么你要从哪个类继承呢?目前LLVM系统提供了 ModulePass、CallGraphSCCPass、FunctionPass、LoopPass和BasicBlocks这个基类可供使用,根据你想要实现的功能来选择从哪个类来继承。一旦你写好了自己的Pass, LLVM Pass Framework会以一种高效的方式在LLVM编译过程中在合适的时机调用你的Pass(具体的调用实际就完全取决于你继承的基类)
29 namespace {
30 struct SplitBasicBlock : public FunctionPass {
31 static char ID; // Pass identification, replacement for typeid
32 bool flag;
33
34 SplitBasicBlock() : FunctionPass(ID) {}
35 SplitBasicBlock( bool flag) : FunctionPass(ID) {
36
37 this->flag = flag;
38 }
39
40 bool runOnFunction(Function &F);
41 void split(Function *f);
42
43 bool containsPHI(BasicBlock *b);
44 void shuffle(std::vector<int> &vec);
45 };
46 }
55 bool SplitBasicBlock::runOnFunction( Function &F) {
56 // Check if the number of applications is correct
57 if (!((SplitNum > 1) && (SplitNum <= 10))) {
58 errs()<< "Split application basic block percentage
59 -split_num=x must be 1 < x <= 10";
60 return false;
61 }
62
63 Function *tmp = &F;
64
65 // Do we obfuscate
66 if (toObfuscate(flag, tmp, "split")) {
67 split(tmp);
68 ++Split;
69 }
70
71 return false;
72 }
74 void SplitBasicBlock::split(Function *f) {
75 std:: vector<BasicBlock *> origBB;
76 int splitN = SplitNum;
77
78 // Save all basic blocks
79 for (Function::iterator I = f->begin(), IE = f->end(); I != IE; ++I) {
80 origBB.push_back(&*I);
81 }
82
83 for ( std:: vector<BasicBlock *>::iterator I = origBB.begin(),
84 IE = origBB.end();
85 I != IE; ++I) {
86 BasicBlock *curr = *I;
87
88 // 这里省略了一些细枝末节...
98 // 这里开始,生成切割点
99 // Generate splits point
100 std:: vector< int> test;
101 for ( unsigned i = 1; i < curr->size(); ++i) {
102 test.push_back(i);
103 }
104
105 // Shuffle
106 if (test.size() != 1) {
107 shuffle(test);
108 std::sort(test.begin(), test.begin() + splitN);
109 }
110 //切割点生成完毕,下面开始切割
111 // Split
112 BasicBlock::iterator it = curr->begin();
113 BasicBlock *toSplit = curr;
114 int last = 0;
115 for ( int i = 0; i < splitN; ++i) {
116 for ( int j = 0; j < test[i] - last; ++j) {
117 ++it;
118 }
119 last = test[i];
120 if(toSplit->size() < 2)
121 continue;
122 toSplit = toSplit->splitBasicBlock(it, toSplit->getName() + ".split");
123 }
124
125 ++Split;
126 }
127 }
363 /// This splits a basic block into two at the specified
364 /// instruction. Note that all instructions BEFORE the specified iterator stay
365 /// as part of the original basic block, an unconditional branch is added to
366 /// the new BB, and the rest of the instructions in the BB are moved to the new
367 /// BB, including the old terminator. This invalidates the iterator.
368 ///
369 /// Note that this only works on well formed basic blocks (must have a
370 /// terminator), and 'I' must not be the end of instruction list (which would
371 /// cause a degenerate basic block to be formed, having a terminator inside of
372 /// the basic block).
373 ///
374 BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName) {
375 assert(getTerminator() && "Can't use splitBasicBlock on degenerate BB!");
376 assert(I != InstList.end() &&
377 "Trying to get me to create degenerate basic block!");
378
379 BasicBlock * New = BasicBlock::Create(getContext(), BBName, getParent(),
380 this->getNextNode());
381
382 // Save DebugLoc of split point before invalidating iterator.
383 DebugLoc Loc = I->getDebugLoc();
384 // Move all of the specified instructions from the original basic block into
385 // the new basic block.
386 New->getInstList().splice( New->end(), this->getInstList(), I, end());
387
388 // Add a branch instruction to the newly formed basic block.
389 BranchInst *BI = BranchInst::Create( New, this);
390 BI->setDebugLoc(Loc);
391
392 // Now we must loop through all of the successors of the New block (which
393 // _were_ the successors of the 'this' block), and update any PHI nodes in
394 // successors. If there were PHI nodes in the successors, then they need to
395 // know that incoming branches will be from New, not from Old.
396 //
397 for (succ_iterator I = succ_begin( New), E = succ_end( New); I != E; ++I) {
398 // Loop over any phi nodes in the basic block, updating the BB field of
399 // incoming values...
400 BasicBlock *Successor = *I;
401 PHINode *PN;
402 for (BasicBlock::iterator II = Successor->begin();
403 (PN = dyn_cast<PHINode>(II)); ++II) {
404 int IDX = PN->getBasicBlockIndex(this);
405 while (IDX != -1) {
406 PN->setIncomingBlock((unsigned)IDX, New);
407 IDX = PN->getBasicBlockIndex(this);
408 }
409 }
410 }
411 return New;
412 }
看雪ID:freakish
https://bbs.pediy.com/user-126904.htm
推荐文章++++
*
以上是关于ollvm源码分析 - Pass之SplitBaiscBlocks的主要内容,如果未能解决你的问题,请参考以下文章