//===- IPModRef.h - Compute IP Mod/Ref information --------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class IPModRef: // // class IPModRef is an interprocedural analysis pass that computes // flow-insensitive IP Mod and Ref information for every function // (the GMOD and GREF problems) and for every call site (MOD and REF). // // In practice, this needs to do NO real interprocedural work because // all that is needed is done by the data structure analysis. // This uses the top-down DS graph for a function and the bottom-up DS graph // for each callee (including the Mod/Ref flags in the bottom-up graph) // to compute the set of nodes that are Mod and Ref for the function and // for each of its call sites. // // // class FunctionModRefInfo: // // The results of IPModRef are encapsulated in the class FunctionModRefInfo. // The results are stored as bit vectors: bit i represents node i // in the TD DSGraph for the current function. (This node numbering is // implemented by class FunctionModRefInfo.) Each FunctionModRefInfo // includes: // -- 2 bit vectors for the function (GMOD and GREF), and // -- 2 bit vectors for each call site (MOD and REF). // // // IPModRef vs. Alias Analysis for Clients: // // The IPModRef pass does not provide simpler query interfaces for specific // LLVM values, instructions, or pointers because those results should be // obtained through alias analysis (e.g., class DSAliasAnalysis). // class IPModRef is primarily meant for other analysis passes that need to // use Mod/Ref information efficiently for more complicated purposes; // the bit-vector representations make propagation very efficient. // //===----------------------------------------------------------------------===// #ifndef LLVM_ANALYSIS_IPMODREF_H #define LLVM_ANALYSIS_IPMODREF_H #include "llvm/Pass.h" #include "llvm/ADT/BitSetVector.h" #include "llvm/ADT/hash_map" namespace llvm { class Module; class Function; class CallSite; class Instruction; class CallInst; class InvokeInst; class DSNode; class DSGraph; class DSNodeHandle; class ModRefInfo; // Result of IP Mod/Ref for one entity class FunctionModRefInfo; // ModRefInfo for a func and all calls in it class IPModRef; // Pass that computes IP Mod/Ref info //---------------------------------------------------------------------------- /// ModRefInfo Class - Representation of Mod/Ref information for a single /// function or callsite. This is represented as a pair of bit vectors, one each /// for Mod and Ref. Each bit vector is indexed by the node id of the DS graph /// node index. /// class ModRefInfo { BitSetVector modNodeSet; // set of modified nodes BitSetVector refNodeSet; // set of referenced nodes public: // Methods to construct ModRefInfo objects. ModRefInfo(unsigned int numNodes) : modNodeSet(numNodes), refNodeSet(numNodes) { } unsigned getSize() const { assert(modNodeSet.size() == refNodeSet.size() && "Mod & Ref different size?"); return modNodeSet.size(); } void setNodeIsMod (unsigned nodeId) { modNodeSet[nodeId] = true; } void setNodeIsRef (unsigned nodeId) { refNodeSet[nodeId] = true; } // Methods to query the mod/ref info bool nodeIsMod (unsigned nodeId) const { return modNodeSet.test(nodeId); } bool nodeIsRef (unsigned nodeId) const { return refNodeSet.test(nodeId); } bool nodeIsKill(unsigned nodeId) const { return false; } const BitSetVector& getModSet() const { return modNodeSet; } BitSetVector& getModSet() { return modNodeSet; } const BitSetVector& getRefSet() const { return refNodeSet; } BitSetVector& getRefSet() { return refNodeSet; } // Debugging support methods void print(std::ostream &O, const std::string& prefix=std::string("")) const; void dump() const; }; //---------------------------------------------------------------------------- /// FunctionModRefInfo Class - Representation of the results of IP Mod/Ref /// analysis for a function and for each of the call sites within the function. /// Each of these are represented as bit vectors of size = the number of nodes /// in the top-dwon DS graph of the function. Nodes are identified by their /// nodeId, in the range [0 .. funcTDGraph.size()-1]. /// class FunctionModRefInfo { const Function& F; // The function IPModRef& IPModRefObj; // The IPModRef Object owning this DSGraph* funcTDGraph; // Top-down DS graph for function ModRefInfo funcModRefInfo; // ModRefInfo for the function body std::map callSiteModRefInfo; // ModRefInfo for each callsite std::map NodeIds; friend class IPModRef; void computeModRef(const Function &func); void computeModRef(CallSite call); DSGraph* ResolveCallSiteModRefInfo(CallSite CS, hash_map &NodeMap); public: FunctionModRefInfo(const Function& func, IPModRef &IPModRefObj, DSGraph* tdgClone); ~FunctionModRefInfo(); // Identify the function and its relevant DS graph // const Function& getFunction() const { return F; } const DSGraph& getFuncGraph() const { return *funcTDGraph; } // Retrieve Mod/Ref results for a single call site and for the function body // const ModRefInfo* getModRefInfo(const Function& func) const { return &funcModRefInfo; } const ModRefInfo* getModRefInfo(const CallInst& callInst) const { std::map::const_iterator I = callSiteModRefInfo.find((Instruction*)&callInst); return (I == callSiteModRefInfo.end()) ? NULL : I->second; } const ModRefInfo* getModRefInfo(const InvokeInst& II) const { std::map::const_iterator I = callSiteModRefInfo.find((Instruction*)&II); return (I == callSiteModRefInfo.end()) ? NULL : I->second; } // Get the nodeIds used to index all Mod/Ref information for current function // unsigned getNodeId(const DSNode* node) const { std::map::const_iterator iter = NodeIds.find(node); assert(iter != NodeIds.end() && iter->second < funcModRefInfo.getSize()); return iter->second; } unsigned getNodeId(const Value* value) const; // Debugging support methods void print(std::ostream &O) const; void dump() const; }; //---------------------------------------------------------------------------- /// IPModRef Class - An interprocedural pass that computes IP Mod/Ref info for /// functions and for individual call sites. /// /// Given the DSGraph of a function, this class can be queried for /// a ModRefInfo object describing all the nodes in the DSGraph that are /// (a) modified, and (b) referenced during an execution of the function /// from an arbitrary callsite, or during an execution of a single call-site /// within the function. /// class IPModRef : public Pass { std::map funcToModRefInfoMap; Module* M; FunctionModRefInfo& getFuncInfo(const Function& func, bool computeIfMissing = false); public: IPModRef() : M(NULL) {} ~IPModRef() {} /// run - Driver function to run IP Mod/Ref on a Module. /// This initializes the module reference, and then computes IPModRef /// results immediately if demand-driven analysis was *not* specified. /// virtual bool run(Module &M); /// getFunctionModRefInfo - Retrieve the Mod/Ref information for a single /// function /// const FunctionModRefInfo& getFunctionModRefInfo(const Function& func) { return getFuncInfo(func); } /// getBUDSGraph - This method returns the BU data structure graph for F /// through the use of the BUDataStructures object. /// const DSGraph &getBUDSGraph(const Function &F); // Debugging support methods // void print(std::ostream &O) const; void dump() const; /// releaseMemory - Release memory held by this pass when the pass pipeline is /// done /// virtual void releaseMemory(); /// getAnalysisUsage - This pass requires top-down data structure graphs. /// It modifies nothing. /// virtual void getAnalysisUsage(AnalysisUsage &AU) const; }; } // End llvm namespace #endif