blob: 651ef17d16a5c576d34108930e90a8a6495090a1 [file] [log] [blame]
#define INSERT_BOUNDS_H
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "safecode/Config/config.h"
#include "ArrayBoundsCheck.h"
#include "ConvertUnsafeAllocas.h"
#ifndef LLVA_KERNEL
#include "SafeDynMemAlloc.h"
#include "poolalloc/PoolAllocate.h"
#endif
namespace llvm {
using namespace CUA;
struct DSNodePass;
struct PreInsertPoolChecks : public ModulePass {
friend struct InsertPoolChecks;
private :
// Flags whether we want to do dangling checks
bool DanglingChecks;
public :
static char ID;
PreInsertPoolChecks (bool DPChecks = false)
: ModulePass ((intptr_t) &ID) {
DanglingChecks = DPChecks;
}
const char *getPassName() const { return "Register Global variable into pools"; }
virtual bool runOnModule(Module &M);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
#ifndef LLVA_KERNEL
AU.addRequired<TargetData>();
#endif
AU.addRequiredTransitive<PoolAllocateGroup>();
AU.addPreserved<PoolAllocateGroup>();
AU.addRequired<DSNodePass>();
AU.addPreserved<DSNodePass>();
AU.setPreservesCFG();
};
private :
#ifndef LLVA_KERNEL
PoolAllocateGroup * paPass;
TargetData * TD;
#endif
DSNodePass * dsnPass;
Constant *RuntimeInit;
#ifndef LLVA_KERNEL
void registerGlobalArraysWithGlobalPools(Module &M);
#endif
};
struct InsertPoolChecks : public FunctionPass {
public :
static char ID;
InsertPoolChecks () : FunctionPass ((intptr_t) &ID) { }
const char *getPassName() const { return "Inserting Pool checks Pass"; }
virtual bool doInitialization(Module &M);
virtual bool doFinalization(Module &M);
virtual bool runOnFunction(Function &F);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
// AU.addRequired<CompleteBUDataStructures>();
// AU.addRequired<TDDataStructures>();
#ifndef LLVA_KERNEL
AU.addRequired<ArrayBoundsCheck>();
AU.addRequired<TargetData>();
#else
AU.addRequired<TDDataStructures>();
#endif
AU.addRequiredTransitive<PoolAllocateGroup>();
AU.addPreserved<PoolAllocateGroup>();
AU.addRequired<DSNodePass>();
AU.addPreserved<DSNodePass>();
AU.setPreservesCFG();
};
private :
ArrayBoundsCheck * abcPass;
#ifndef LLVA_KERNEL
PoolAllocateGroup * paPass;
TargetData * TD;
#else
TDDataStructures * TDPass;
#endif
DSNodePass * dsnPass;
Constant *PoolCheck;
Constant *PoolCheckUI;
Constant *PoolCheckAlign;
Constant *PoolCheckAlignUI;
Constant *PoolCheckArray;
Constant *PoolCheckArrayUI;
Constant *ExactCheck;
Constant *ExactCheck2;
Constant *FunctionCheck;
Constant *GetActualValue;
void addCheckProto(Module &M);
void addPoolChecks(Function &F);
void addGetElementPtrChecks(BasicBlock * BB);
void addGetActualValue(llvm::ICmpInst*, unsigned int);
bool insertExactCheck (GetElementPtrInst * GEP);
bool insertExactCheck (Instruction * , Value *, Value *, Instruction *);
void addLoadStoreChecks(Function &F);
void addExactCheck (Value * P, Value * I, Value * B, Instruction * InsertPt);
void addExactCheck2 (Value * B, Value * R, Value * C, Instruction * InsertPt);
void insertAlignmentCheck (LoadInst * LI);
#ifndef LLVA_KERNEL
void addLSChecks(Value *Vnew, const Value *V, Instruction *I, Function *F);
void registerGlobalArraysWithGlobalPools(Module &M);
#else
void addLSChecks(Value *V, Instruction *I, Function *F);
#endif
};
/// Monotonic Loop Optimization
struct MonotonicLoopOpt : public LoopPass {
static char ID;
const char *getPassName() const { return "Optimize SAFECode checkings in monotonic loops"; }
MonotonicLoopOpt() : LoopPass((intptr_t) &ID) {}
virtual bool doInitialization(Loop *L, LPPassManager &LPM);
virtual bool doFinalization();
virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfo>();
AU.addRequired<ScalarEvolution>();
}
private:
LoopInfo * LI;
ScalarEvolution * scevPass;
bool isMonotonicLoop(Loop * L, Value * loopVar);
bool isHoistableGEP(GetElementPtrInst * GEP, Loop * L);
void insertEdgeBoundsCheck(int checkFunctionId, Loop * L, const CallInst * callInst, GetElementPtrInst * origGEP, Instruction *
ptIns, int type);
bool optimizeCheck(Loop *L);
bool isEligibleForOptimization(const Loop * L);
};
/// Passes that holds DSNode and Pool Handle information
struct DSNodePass : public ModulePass {
public :
static char ID;
DSNodePass () : ModulePass ((intptr_t) &ID) { }
virtual ~DSNodePass() {};
const char *getPassName() const { return "DS Node And Pool Handle Pass"; }
virtual bool runOnModule(Module &M);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
#ifndef LLVA_KERNEL
AU.addRequired<EquivClassGraphs>();
#if 0
AU.addRequired<EmbeCFreeRemoval>();
#endif
AU.addPreserved<PoolAllocateGroup>();
AU.addRequired<PoolAllocateGroup>();
#else
AU.addRequired<TDDataStructures>();
#endif
};
public:
// FIXME: Provide better interfaces
#ifndef LLVA_KERNEL
PoolAllocateGroup * paPass;
#if 0
EmbeCFreeRemoval *efPass;
#endif
#else
TDDataStructures * TDPass;
#endif
DSGraph & getDSGraph (Function & F);
DSNode* getDSNode(const Value *V, Function *F);
unsigned getDSNodeOffset(const Value *V, Function *F);
#ifndef LLVA_KERNEL
Value * getPoolHandle(const Value *V, Function *F, PA::FuncInfo &FI, bool collapsed = true);
// Set of checked DSNodes
std::set<DSNode *> CheckedDSNodes;
// The set of values that already have run-time checks
std::set<Value *> CheckedValues;
#endif
};
struct RegisterStackObjPass : public FunctionPass {
public:
static char ID;
RegisterStackObjPass() : FunctionPass((intptr_t) &ID) {};
virtual ~RegisterStackObjPass() {};
virtual bool doInitialization(Module & M);
virtual bool runOnFunction(Function &F);
virtual const char * getPassName() const { return "Register stack variables into pool"; }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequiredTransitive<PoolAllocateGroup>();
AU.addRequired<DSNodePass>();
AU.addRequired<DominatorTree>();
AU.addRequired<TargetData>();
AU.setPreservesAll();
};
private:
PoolAllocateGroup * paPass;
TargetData * TD;
DSNodePass * dsnPass;
DominatorTree * DT;
void registerAllocaInst(AllocaInst *AI, AllocaInst *AIOrig, DomTreeNode * DTN);
};
}