Program Listing for File IntraProcAliasAnalysis.h

Program Listing for File IntraProcAliasAnalysis.h#

Return to documentation for file (src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.h)

#ifndef INTRA_PROC_ALIAS_ANALYSIS_H
#define INTRA_PROC_ALIAS_ANALYSIS_H
#include "IntraProcDataFlowAnalysis.h"
#include "customFilteredCFG.h"
#include "ClassHierarchyGraph.h"
#include "CallGraph.h"
#include <memory>
#include <unordered_map>
#include <algorithm>

using namespace std;

struct AliasRelationNode{
    SgVariableSymbol *var;
    int derefLevel;

    bool operator==(const AliasRelationNode &that) const {
        assert(this != NULL);
        return (this->var == that.var && this->derefLevel == that.derefLevel);
    }

};


struct AliasCfgFilter
{
        bool operator() (CFGNode cfgn) const
        {
                SgNode *node = cfgn.getNode();
                switch (node->variantT())
                {
                    case V_SgBasicBlock:
                        return cfgn == node->cfgForBeginning()  || cfgn == node->cfgForBeginning();
                    case V_SgAssignStatement:
                    case V_SgAssignOp:
                    case V_SgAssignInitializer:
                        //return (cfgn == node->cfgForBeginning());
                        return (cfgn == node->cfgForEnd());
                    case V_SgConditionalExp:
                                return (cfgn.getIndex() == 1);
                    case V_SgConstructorInitializer:
                    case V_SgFunctionCallExp:
                    case V_SgReturnStmt:
                                return (cfgn == node->cfgForBeginning());
                                //return (cfgn == node->cfgForEnd());
                     default:
                        return false;

                }
        }
};
// Base class for CompactRepresentation
class CompReprBase{


public:
    CompReprBase() {
    }
    virtual void computeAliases (SgVariableSymbol *var, int derefLevel, vector<SgGraphNode *> &) = 0;

    virtual void computeAliases (SgGraphNode *node, int derefLevel, vector<SgGraphNode *> &) = 0;

    virtual void addMustAliasRelation(const AliasRelationNode &left, const AliasRelationNode &right) = 0;

    virtual void addMayAliasRelation(const AliasRelationNode &left, const AliasRelationNode &right) = 0;

    virtual unsigned long getHash() const = 0;
    virtual SgIncidenceDirectedGraph * getGraph() const = 0;

    virtual void merge(const CompReprBase &) = 0;

    virtual void toDot(const std::string& file_name) = 0;

protected:
    SgIncidenceDirectedGraph *graph;
    unsigned long hash;
 // DQ (12/6/2016): Aded virtual to fix compiler warning that we want to considered an error: -Wdelete-non-virtual-dtor
    virtual ~CompReprBase(){
        delete graph;
        graph = NULL;
    }
};

// The actual Compact Representation. It's implemented
// as a graph(SgIncidenceDirectedGraph).
class CompactRepresentation : public CompReprBase{

    std::unordered_map<SgNode *,SgGraphNode *> all_nodes;

    SgGraphNode * getGraphNode(SgNode *node);

    void merge(SgIncidenceDirectedGraph *thatGraph);

    void updateHash(SgNode *from, SgNode *to);

    void init();

    void addEdge(SgGraphNode *g_from, SgGraphNode *g_to);

    void processNodes(std::ostream & o, SgGraphNode* n, std::set<SgGraphNode*>& explored);

    void printNodePlusEdges(std::ostream & o, SgGraphNode* node);

    void printNode(std::ostream & o, SgGraphNode* node);

    void printEdge(std::ostream & o, SgDirectedGraphEdge* edge, bool isInEdge);


public:
    std::unordered_map<SgNode *,SgGraphNode *>  getNodesMapping(){ return all_nodes;}
    CompactRepresentation() {  init(); }

    SgIncidenceDirectedGraph * getGraph() const{ return graph; }

    unsigned long getHash() const {  return hash; }

    CompactRepresentation(const CompactRepresentation& copy);

    CompactRepresentation& operator=(const CompactRepresentation& p);

    void computeAliases (SgVariableSymbol *var, int derefLevel, vector<SgGraphNode *> &nodes);

    void computeAliases (SgGraphNode *node, int derefLevel, vector<SgGraphNode *> &);

    void addMustAliasRelation(const AliasRelationNode &left, const AliasRelationNode &right);

    void addMayAliasRelation(const AliasRelationNode &left, const AliasRelationNode &right);

    void merge(const CompReprBase &that);

    bool operator==(const CompactRepresentation &that) const;

    bool operator !=(const CompactRepresentation &that) const;

    void toDot(const std::string& file_name);
};

class CompReprPtr  {
     std::shared_ptr<CompReprBase> ptr;
public:
    CompReprPtr() { ptr = std::shared_ptr<CompReprBase>(); }

    CompReprPtr(CompactRepresentation *repr)   { ptr = std::shared_ptr<CompReprBase>(repr);  }

    CompReprBase * get() const{ return ptr.get();  }

    // Equality operator overload. Compares two CompactRepresentations
    bool operator==(const CompReprPtr &that) const;

    // Not Equality operator overload. Compares two CompactRepresentations
    bool operator!=(const CompReprPtr &that) const {  return !(*this == that);   }

    // += operator overload
    void operator+=(const CompReprPtr &that) const;
};

class AliasInfoGenerator {
    std::unordered_map<SgGraphNode *, CompReprPtr> ins;

    std::unordered_map<SgGraphNode *, CompReprPtr> outs;

    std::vector <AliasRelationNode > returnStmts;

    std::unordered_map<SgGraphNode *, std::vector <std::pair<AliasRelationNode, AliasRelationNode> > >aliasRelations;

public :
    AliasInfoGenerator();

    void init(SgGraphNode *n);

    CompReprPtr getEntryData(SgGraphNode *node);

    void setEntryData(SgGraphNode *node, CompReprPtr en) {    ins[node] = en;    }

    CompReprPtr getExitData(SgGraphNode *node);

    void setExitData(SgGraphNode *node, CompReprPtr en) {  outs[node] = en;   }

    std::vector <std::pair<AliasRelationNode, AliasRelationNode> > getAliasRelations(SgGraphNode *node);

    void addNewAliasRelation(SgGraphNode *node, std::pair<AliasRelationNode, AliasRelationNode> a_relation) ;

    void addReturnStmt(AliasRelationNode node) { returnStmts.push_back(node);  }

    std::vector<AliasRelationNode> getReturnStmts(){ return returnStmts; }

};

namespace ProcessExpression {
    void processLHS(SgNode *node, struct AliasRelationNode &arNode) ;

    void processRHS(SgNode *node, struct AliasRelationNode &arNode) ;
}

class CollectAliasRelations {
      StaticCFG::CFG *cfg;

      AliasInfoGenerator *g;

      void processNode(SgGraphNode *);
  public:
      enum COLOR {WHITE=0, GREY, BLACK};
      enum TRAVERSAL_TYPE {TOPOLOGICAL=0, NON_TOPOLOGICAL};

      CollectAliasRelations(StaticCFG::CFG *_cfg, AliasInfoGenerator *_g ) : cfg(_cfg), g(_g) { }
      void run();
  private:
      void recursiveCollect(SgGraphNode *, std::unordered_map<SgGraphNode*, CollectAliasRelations::COLOR> &);
};

class IntraProcAliasAnalysis :
        public IntraProcDataFlowAnalysis <SgGraphNode, CompReprPtr> {

    AliasInfoGenerator *gen;

    ClassHierarchyWrapper *classHierarchy;

protected:
    StaticCFG::CustomFilteredCFG<AliasCfgFilter> *cfg;

    CallGraphBuilder *cgBuilder;

    vector<SgGraphNode *> cfgNodes;

   //typedef FilteredCFGNode<AliasCfgFilter> FilteredCfgNode;
   //typedef FilteredCFGEdge<AliasCfgFilter> FilteredCfgEdge;

   CompReprPtr entry;

   CompReprPtr exit;

   unsigned long checkPointHash;

   virtual void buildCFG() ;

   std::unordered_map<SgFunctionDeclaration *, IntraProcAliasAnalysis *> &mapping;

   std::unordered_map<SgExpression*, std::vector<SgFunctionDeclaration*> > &resolver;

   void getFunctionParametersAliasRelations(SgFunctionCallExp *f_exp, SgFunctionDeclaration *funcDecl,
        std::vector <std::pair<AliasRelationNode, AliasRelationNode> > &arg_relations,
        std::vector <std::pair<AliasRelationNode, AliasRelationNode> > &return_relations);

   void getConstructorParametersAliasRelations(SgConstructorInitializer *f_exp, SgFunctionDeclaration *funcDecl,
        std::vector <std::pair<AliasRelationNode, AliasRelationNode> > &arg_relations );

   bool addVirtualFunction(SgType *type, SgFunctionCallExp *funcExp);

   bool updateVirtualFunctionInCallGraph (SgFunctionCallExp *funcCall, CompReprPtr &callSiteIN);

   // Get all the aliases
    void getAliases(CompReprPtr &ptr, AliasRelationNode &node, std::vector<SgVariableSymbol*>& aliases);

public:
    //ReachingDefinitionAnalysis(SgNode *head) : DataFlowAnalysis<ReachingDefNode, ReachingDefinitions>(head),  g(0) {
    IntraProcAliasAnalysis(SgNode *head, ClassHierarchyWrapper *_classHierarchy, CallGraphBuilder *_cgB,
                std::unordered_map<SgFunctionDeclaration *, IntraProcAliasAnalysis *> &mapping,
                std::unordered_map<SgExpression*, std::vector<SgFunctionDeclaration*> > &resolver);

    CompReprPtr getFunctionEntry() {return entry;}

    CompReprPtr getFunctionExit() {return exit;}

    std::vector<AliasRelationNode> getReturnStmts () { return gen->getReturnStmts(); }

    void setFunctionEntry(CompReprPtr &n);

    void setFunctionExit(CompReprPtr &n);

    bool runCheck();

    virtual void run() ;

    void init() { }

 // DQ (12/6/2016): Aded virtual to fix compiler warning that we want to considered an error: -Wdelete-non-virtual-dtor
    virtual ~IntraProcAliasAnalysis();

    CompReprPtr meet_data( const CompReprPtr& d1, const CompReprPtr& d2);

    virtual std::vector<SgGraphNode *> getAllNodes() {    return cfgNodes;  }

    virtual std::vector<SgGraphNode *> getPredecessors(SgGraphNode *n);

    CompReprPtr getCFGInData(SgGraphNode *a) {     return gen->getEntryData(a);   }

    CompReprPtr getCFGOutData(SgGraphNode *a) {      return gen->getExitData(a);  }

    void setCFGInData(SgGraphNode*a, CompReprPtr &b) {      gen->setEntryData(a, b);  }


    void applyCFGTransferFunction(SgGraphNode* s);

};

#endif