底下就把 LLVM + Boost c++ 做簡單的結合. 有 Lib 就是個 "爽"
#define DEBUG_TYPE "BoostPass"
#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 <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <map>
using namespace llvm;
using namespace boost;
using namespace std;
template<class T>
class BoostEdge {
public:
BoostEdge(T iEdgeFm,
T iEdgeTo) : InstructionEdgeFm(iEdgeFm),
InstructionEdgeTo(iEdgeTo) {}
~BoostEdge(){}
T GetInstructionEdgeFm(){ return InstructionEdgeFm; }
T GetInstructionEdgeTo(){ return InstructionEdgeTo; }
private:
T InstructionEdgeFm;
T InstructionEdgeTo;
};
class BoostPass : public FunctionPass {
public:
static char ID;
BoostPass() : FunctionPass(ID) { LLVM2BoostInx=0; }
~BoostPass(){
BoostEdgeList.clear();
BoostNodeList.clear();
LLVM2BoostMapList.clear();
Boost2LLVMMapList.clear();
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
}
bool runOnFunction(Function &F);
void setInstructionLLVM2Boost(Instruction *inst);
int getIndexLLVM2Boost(Instruction *inst);
private:
std::vector<BoostEdge<int>*> BoostEdgeList;
std::vector<Instruction*> BoostNodeList;
std::map<Instruction*,int> LLVM2BoostMapList;
std::map<int,Instruction*> Boost2LLVMMapList;
int LLVM2BoostInx;
};
void BoostPass::setInstructionLLVM2Boost(Instruction *inst){
if(std::find(BoostNodeList.begin(),BoostNodeList.end(), inst) == BoostNodeList.end()){
BoostNodeList.push_back(inst);
LLVM2BoostMapList[inst] = LLVM2BoostInx++;
}
}
int BoostPass::getIndexLLVM2Boost(Instruction *inst){
std::map<Instruction*,int>::iterator it = LLVM2BoostMapList.find(inst);
if(it!=LLVM2BoostMapList.end())
return it->second;
return -1;
}
bool BoostPass::runOnFunction(Function &F) {
for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE; ++BB) {
BasicBlock *BC = dyn_cast<BasicBlock>(BB);
for (BasicBlock::iterator IB = BB->begin(), IE = BB->end(); IB != IE; ++IB) {
Instruction *IT = dyn_cast<Instruction>(IB);
// @ Instruction::Add , Sub ...
if(dyn_cast<BinaryOperator>(IT)){
for (Instruction::use_iterator uit = IT->use_begin(); uit!= IT->use_end(); ++uit) {
if(dyn_cast<BinaryOperator>(*uit)){
Instruction *NT = dyn_cast<Instruction>(*uit);
//@ same basic block
if( NT->getParent()==BC ){
errs() << "LLVM->From Instruction :: " << *IT << "\n";
errs() << "LLVM->To Instruction :: " << *NT << "\n";
errs() << "\n";
setInstructionLLVM2Boost(IT);
setInstructionLLVM2Boost(NT);
int it = getIndexLLVM2Boost(IT);
int nt = getIndexLLVM2Boost(NT);
assert( it!=-1 && nt!=-1 && "LLVM2Boost Error<1>");
BoostEdge<int> *BtEdgePtr = new BoostEdge<int>(it,nt);
BoostEdgeList.push_back(BtEdgePtr);
}
}
}
}
} //end Instruction iterator
// @ LLVM 2 Boost Graph
const unsigned int NodeSize = BoostNodeList.size()+1;
const unsigned int EdgeSize = BoostEdgeList.size();
if( NodeSize>1 && EdgeSize>0 ){
typedef adjacency_list<vecS, vecS, bidirectionalS> Graph;
typedef std::pair<int, int> Edge;
Graph g(NodeSize);
for(std::vector<BoostEdge<int>*>::iterator IE = BoostEdgeList.begin(); IE != BoostEdgeList.end(); ++IE)
boost::add_edge((*IE)->GetInstructionEdgeFm(), (*IE)->GetInstructionEdgeTo(), g);
// get the property map for vertex indices
typedef property_map<Graph, vertex_index_t>::type IndexMap;
IndexMap index = get(vertex_index, g);
std::cout << "vertices(g) = ";
typedef graph_traits<Graph>::vertex_iterator vertex_iter;
std::pair<vertex_iter, vertex_iter> vp;
for (vp = vertices(g); vp.first != vp.second; ++vp.first)
std::cout << index[*vp.first] << " ";
std::cout << std::endl;
// @ Boost Graph Algorithm
// ....
// @ Boost Graph Result 2 LLVM
// ...
}
BoostNodeList.clear();
BoostEdgeList.clear();
LLVM2BoostMapList.clear();
Boost2LLVMMapList.clear();
LLVM2BoostInx =0;
} // end basic block iterator
return true;
}
char BoostPass::ID = 0;
RegisterPass<BoostPass> PXX("Boost_pass", "Boost c++ lib test",false,false);
compile
opt -load Debug+Asserts/lib/Boost_t.so -Boost_pass test/scalar.bc
ps: 後來發現可以用
std::pair 來取代 Edge class..XD
Table of Contents: the Boost Graph Library
沒有留言:
張貼留言