寫了個簡單的 sample @ LLVM, 就當練習練習...XD. 不過沒有考慮 function 的正確性.
#define DEBUG_TYPE "SamplePass"
#include "llvm/Pass.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/Dominators.h"
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <map>
using namespace llvm;
using std::set;
using std::map;
using std::vector;
using std::pair;
using std::string;
class SamplePass : public FunctionPass {
public:
static char ID;
SamplePass() : FunctionPass(ID) {}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
}
bool runOnFunction(Function &F);
};
bool SamplePass::runOnFunction(Function &F) {
for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE; ++BB) {
BasicBlock *BC = dyn_cast<BasicBlock>(BB);
std::vector<Instruction*> RemoveList;
RemoveList.clear();
for (BasicBlock::iterator IB = BB->begin(), IE = BB->end(); IB != IE; ++IB) {
Instruction *IT = dyn_cast<Instruction>(IB);
// @ get Array Load instruction
if (dyn_cast<GetElementPtrInst>(IB)) {
for (Instruction::use_iterator uit = IT->use_begin(); uit!= IT->use_end(); ++uit) {
if(dyn_cast<LoadInst>(*uit)){
Instruction *NT = dyn_cast<Instruction>(*uit);
errs() << "getelementptr ::" << *IT << "\n";
errs() << "load ::" << *NT << "\n";
errs() << "\n";
}
}
}
// @ get ALL PHI values && same basic block check
if(dyn_cast<PHINode>(IT)){
PHINode *phi = dyn_cast<PHINode>(IT);
unsigned incs = phi->getNumIncomingValues();
for(unsigned i =0; i<incs; i++){
BasicBlock *INB = phi->getIncomingBlock(i);
Value *val = phi->getIncomingValue(i);
if( INB==BC ){
errs() << "Instruct ::" << *IT << "\n";
errs() << "PHI value ::" << *val << "\n";
errs() << "\n";
}
}
}
// @ get Binary Operator Instruction::Add
if(dyn_cast<BinaryOperator>(IT)){
BinaryOperator* bin = dyn_cast<BinaryOperator>(IT);
if (bin->getOpcode() == Instruction::Add) {
Value *val0 = IT->getOperand(0);
Value *val1 = IT->getOperand(1);
errs() << "Add Value0 ::" << *val0 << "\n";
errs() << "Add Value1 ::" << *val1 << "\n";
}
}
// @ insert Sub Instruction after Add Instruction
if(dyn_cast<BinaryOperator>(IT)){
BinaryOperator* bin = dyn_cast<BinaryOperator>(IT);
if (bin->getOpcode() == Instruction::Add){
Value *val0 = IT->getOperand(0);
Value *val1 = IT->getOperand(1);
BinaryOperator::Create(Instruction::Sub, val0, val1, "SUB", IT);
}
}
// @ remove ALL Instruction::Add && link the Value0 at next connect
if(dyn_cast<BinaryOperator>(IT)){
BinaryOperator* bin = dyn_cast<BinaryOperator>(IT);
if (bin->getOpcode() == Instruction::Add) {
Value *val0 = IT->getOperand(0);
IT->replaceAllUsesWith(val0);
RemoveList.push_back(IT);
}
}
} //end Instruction iterator
// @ remove ALL Instruction::Add
for(std::vector<Instruction*>::iterator rmIt = RemoveList.begin();
rmIt != RemoveList.end(); ++rmIt){
Instruction *It = dyn_cast<Instruction>(*rmIt);
It->eraseFromParent();
}
RemoveList.clear();
} // end basic block iterator
return true;
}
char SamplePass::ID = 0;
RegisterPass<SamplePass> PXX("Sample_pass", "extract Sample DFG",false,false);
compile
opt -load Debug+Asserts/lib/Parallel_t.so -Sample_pass test/opt_scalar.bc | llvm-dis | grep sub
沒有留言:
張貼留言