//===- FunctionRepBuilder.h - Structures for graph building ------*- C++ -*--=// // // This file defines the FunctionRepBuilder and InitVisitor classes that are // used to build the local data structure graph for a method. // //===----------------------------------------------------------------------===// #ifndef DATA_STRUCTURE_METHOD_REP_BUILDER_H #define DATA_STRUCTURE_METHOD_REP_BUILDER_H #include "llvm/Analysis/DataStructure.h" #include "llvm/Support/InstVisitor.h" // DEBUG_DATA_STRUCTURE_CONSTRUCTION - Define this to 1 if you want debug output //#define DEBUG_DATA_STRUCTURE_CONSTRUCTION 1 class FunctionRepBuilder; // InitVisitor - Used to initialize the worklists for data structure analysis. // Iterate over the instructions in the method, creating nodes for malloc and // call instructions. Add all uses of these to the worklist of instructions // to process. // class InitVisitor : public InstVisitor { FunctionRepBuilder *Rep; Function *Func; public: InitVisitor(FunctionRepBuilder *R, Function *F) : Rep(R), Func(F) {} void visitCallInst(CallInst *CI); void visitAllocationInst(AllocationInst *AI); void visitInstruction(Instruction *I); // visitOperand - If the specified instruction operand is a global value, add // a node for it... // void visitOperand(Value *V); }; // FunctionRepBuilder - This builder object creates the datastructure graph for // a method. // class FunctionRepBuilder : InstVisitor { friend class InitVisitor; FunctionDSGraph *F; PointerValSet RetNode; // ValueMap - Mapping between values we are processing and the possible // datastructures that they may point to... map ValueMap; // CallMap - Keep track of which call nodes correspond to which call insns. // The reverse mapping is stored in the CallDSNodes themselves. // map CallMap; // Worklist - Vector of (pointer typed) instructions to process still... std::vector WorkList; // Nodes - Keep track of all of the resultant nodes, because there may not // be edges connecting these to anything. // std::vector AllocNodes; std::vector ShadowNodes; std::vector GlobalNodes; std::vector CallNodes; // addAllUsesToWorkList - Add all of the instructions users of the specified // value to the work list for further processing... // void addAllUsesToWorkList(Value *V); public: FunctionRepBuilder(FunctionDSGraph *f) : F(f) { initializeWorkList(F->getFunction()); processWorkList(); } const std::vector &getAllocNodes() const { return AllocNodes; } const std::vector &getShadowNodes() const {return ShadowNodes;} const std::vector &getGlobalNodes() const {return GlobalNodes;} const std::vector &getCallNodes() const { return CallNodes; } ShadowDSNode *makeSynthesizedShadow(const Type *Ty, DSNode *Parent); const PointerValSet &getRetNode() const { return RetNode; } const map &getValueMap() const { return ValueMap; } private: static PointerVal getIndexedPointerDest(const PointerVal &InP, const MemAccessInst *MAI); void initializeWorkList(Function *Func); void processWorkList() { // While the worklist still has instructions to process, process them! while (!WorkList.empty()) { Instruction *I = WorkList.back(); WorkList.pop_back(); #ifdef DEBUG_DATA_STRUCTURE_CONSTRUCTION cerr << "Processing worklist inst: " << I; #endif visit(I); // Dispatch to a visitXXX function based on instruction type... #ifdef DEBUG_DATA_STRUCTURE_CONSTRUCTION if (I->hasName() && ValueMap.count(I)) { cerr << "Inst %" << I->getName() << " value is:\n"; ValueMap[I].print(cerr); } #endif } } //===--------------------------------------------------------------------===// // Functions used to process the worklist of instructions... // // Allow the visitor base class to invoke these methods... friend class InstVisitor; void visitGetElementPtrInst(GetElementPtrInst *GEP); void visitReturnInst(ReturnInst *RI); void visitLoadInst(LoadInst *LI); void visitStoreInst(StoreInst *SI); void visitCallInst(CallInst *CI); void visitPHINode(PHINode *PN); void visitSetCondInst(SetCondInst *SCI) {} // SetEQ & friends are ignored void visitFreeInst(FreeInst *FI) {} // Ignore free instructions void visitInstruction(Instruction *I) { std::cerr << "\n\n\nUNKNOWN INSTRUCTION type: "; I->dump(); std::cerr << "\n\n\n"; assert(0 && "Cannot proceed"); } }; #endif