blob: 40b47b1ca70e2d32eee1b92f98035aa3bd18c09f [file] [log] [blame]
#include <map>
#include <set>
#include <iterator>
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
using namespace llvm;
namespace {
struct ProofStrip : public ModulePass {
const Value* getProof(const Value* V) {
return stuff[V];
}
virtual bool runOnModule(Module &M);
private:
void setProof(const Value* V, const Value* P) {
stuff[V] = P;
}
std::map<const Value*, const Value*> stuff;
};
// call AddProof until you are done annotating
// then call Finalize
struct ProofPlace {
std::map<Value*, Value*> stuff;
void AddProof(Value* V, Value* P) {
assert(isa<PointerType>(V->getType()));
assert(isa<ConstantInt>(P));
stuff[V] = P;
}
void AddProof(Value* V, unsigned P) {
AddProof(V, ConstantInt::get(Type::LongTy,P));
}
void Finalize(Module& M) {
//try to be semi clever
//find homes for values
BasicBlock* SomeBB;
std::map<std::pair<BasicBlock*, Value*>, std::set<Value*> > homes;
for (std::map<Value*, Value*>::iterator ii = stuff.begin(),
ee = stuff.end(); ii != ee; ++ii) {
Value* V = ii->first;
if (isa<GlobalValue>(V)) {
homes[std::make_pair((BasicBlock*)0, ii->second)].insert(V);
} else if (isa<Instruction>(V)) {
homes[std::make_pair(cast<Instruction>(V)->getParent(), ii->second)].insert(V);
SomeBB = cast<Instruction>(V)->getParent();
} else {
V->dump();
assert(0 && "Not supported");
}
}
//get proof function
std::vector<const Type * > FTV;
FTV.push_back(Type::LongTy);
FunctionType* FT = FunctionType::get(Type::VoidTy, FTV, true);
Function* F = M.getOrInsertFunction("llvm.proof.ptr", FT);
//insert at end of BBs
for (std::map<std::pair<BasicBlock*, Value*>, std::set<Value*> >::iterator
ii = homes.begin(), ee = homes.end(); ii != ee; ++ii) {
BasicBlock* BB = ii->first.first ? ii->first.first : SomeBB;
std::vector<Value*> Args;
Args.push_back(ii->first.second);
std::copy(ii->second.begin(), ii->second.end(), std::back_insert_iterator<std::vector<Value*> > (Args));
new CallInst(F, Args, "", BB->getTerminator());
}
}
};
}