Program Listing for File CFGRewrite.h

Program Listing for File CFGRewrite.h#

Return to documentation for file (src/midend/programAnalysis/genericDataflow/cfgUtils/CFGRewrite.h)

#include <featureTests.h>
#ifdef ROSE_ENABLE_SOURCE_ANALYSIS

#ifndef CFG_REWRITE_H
#define CFG_REWRITE_H

#include "DataflowCFG.h"
#include <string>
#include <iostream>
#include <sstream>
#include <list>

namespace VirtualCFG{

//SgStatement* getParentStmt(SgNode* node);*/
//
//void insertAfterCFG(DataflowNode& cfgNode);
//
//void placeInserts(SgProject *project);

void initCFGRewrite(SgProject* project);

// returns true if the given SgNode is a value expression or a computational expression with no side-effects
bool isNonMutatingOperator(SgNode* n);

// returns true if the given SgNode's sub-tree has no side-effects
bool isNonMutatingSubTree(SgNode* n);

// if the given SgNode is an SgStatement, returns that SgStatement. Otherwise, if it is an
//    gExpression or SgInitializedName, wraps it in an SgStatement and returns that.
//static SgStatement* convertToStatement(SgNode* n);

// Replace the expression from with the expression to in the SgNode parent, which
//    must be from's parent. Function checks to ensure that it is used properly.
// Note that if parent is an SgInitializedName, to must be SgInitializer in order
//    for the replacement to work properly.
void replaceExpressionChecked(SgNode* parent, SgExpression* from, SgExpression* to);

// replace the from statement with the to statement in the parent SgNode
// Note: Only parent = SgBasicBlock
void replaceStatement(SgNode* parent, SgStatement* from, SgStatement* to);

Sg_File_Info* getFileInfo(SgNode* n);

 std::string getFileInfoString(SgNode* n);

 std::string getFileInfoString(CFGNode n);

// Returns the source of n's only in-edge. Yells if n has multiple in-edges.
CFGNode theInEdge(CFGNode n);

// Returns the target of n's only out-edge. Yells if n has multiple out-edges.
CFGNode theOutEdge(CFGNode n);

// FIXME -- these functions need to split subexpressions, since the expression
// evaluation order in the CFG and the one used by the compiler may be
// different

// replace expr with (newNode, expr)
SgExpression* insertBeforeExpression(SgExpression* expr, SgExpression* newNode);

// replace expr with (expr, newNode)
SgExpression* insertAfterExpression(SgExpression* expr, SgExpression* newNode);

// replace stmt; with {newNode; stmt;}
void replaceStatementByBlockBefore(SgStatement* stmt, SgStatement* newNode) ;

// replace stmt; with {stmt; newNode;}
void replaceStatementByBlockAfter(SgStatement* stmt, SgStatement* newNode);

// creates a new variable declaration for a temporary variable
// newName: the name of the temporary variable. If newName=="", a random name is generated.
// varType: the type of the temporary variable, if byReference==true, the new variable's type is a reference type of varType
//
// sets varname to the new variable's SgName
// sets initName to the new variable's SgInitializedName
// sets newType to the new variable's type
// sets newType to the new variable's declaration
 void createTmpVarInit(SgType* varType, std::string newName, bool byReference,
                      SgName& varName, SgInitializedName *& initName, SgType*& newType, SgVariableDeclaration*& varDecl);

// creates and returns a statement contains a call to the given function with no arguments
SgStatement* createFuncCallStmt(SgFunctionDeclaration* funcDecl);

// given a SgInitializedName, returns a SgVariableSymbol for the variable declared in the SgInitializedName
SgVariableSymbol* varSymFromInitName(SgInitializedName* initName);

// given a SgInitializedName, returns a SgVarRefExp to the variable declared in the SgInitializedName
SgVarRefExp* varRefFromInitName(SgInitializedName* initName);

// replaces the given SgExpression with a SgAssignOp (lhsVar = orig)
// returns the SgAssignOp
SgAssignOp * replaceExprWithAssignOp(SgExpression* orig, SgVarRefExp* lhsVar);

// Creates a declaration of a new temporary variable of type varType and inserts it before anchor
// if before=true, the temporary variable in inserted before anchor and otherwise, after anchor
// sets initName to the SgInitializedName of the declaration
void insertVarDecl(SgStatement *anchor, SgType *varType, bool before, SgInitializedName*& initName);

// inserts the given expression before or after a given SgDeclaration that appears inside a SgForStatement
void insertAroundForInit(SgVariableDeclaration* n, SgExpression *newNode, bool before);

typedef void (*CFGTransform)(SgNode *target, SgNode* newNode, void* data);

class cfgRWTransaction
{
        typedef enum {insBef, insAft, callback} modType;
        class modRequest{
                protected:
                modType type;

                public:
                modRequest()
                {}
                /*modRequest(modType type_arg)
                {
                        type = type_arg;
                }*/

                modType getType()
                { return type; }

                std::string str() { return ""; }
        };

        class insertRequest: public modRequest{
                protected:
                SgExpression *newNode;
                SgNode* origNode;

                public:
                insertRequest(modType type_arg, SgNode* origNode, SgExpression *&newNode)
                {
                        this->type = type_arg;
                        this->newNode = newNode;
                        this->origNode = origNode;
                }

                SgNode* getTgtNode() { return origNode; }

                std::string str();
                friend class cfgRWTransaction;
        };

        class transformRequest: public modRequest{
                CFGTransform callbackFunc;
                SgNode* target;
                SgNode* newNode;
                void* data;

                public:
                transformRequest(CFGTransform callbackFunc, SgNode *&target, SgNode* newNode, void* data)//: modRequest(callback)
                {
                        this->type = callback;
                        this->target = target;
                        this->newNode = newNode;
                        this->callbackFunc = callbackFunc;
                        this->data = data;
                }

                std::string str();
                friend class cfgRWTransaction;
        };

        public:
        std::list<modRequest*> requests;
        //list<void*> requests;


        cfgRWTransaction();

        void beginTransaction();

        void insertBefore(DataflowNode n, SgExpression* newNode);
        void insertBefore(SgNode* n, SgExpression* newNode);

        void insertAfter(DataflowNode n, SgExpression* newNode);
        void insertAfter(SgNode* n, SgExpression* newNode);

        void transform(CFGTransform callbackFunc, SgNode* n, SgNode* newNode, void* data);

        // insert an SgNode along the given CFGEdge
        void insertAlong(DataflowEdge e, SgExpression* newNode);

        void commitTransaction();

        protected:
        void do_insertBefore(DataflowNode n, SgExpression* newNode);
        void do_insertBefore(SgNode* n, SgExpression* newNode);
        void do_insertAfter(DataflowNode n, SgExpression* newNode);
        void do_insertAfter(SgNode* n, SgExpression* newNode);
};

/*************************************************************
 *** CALL-BACK FUNCTIONS FOR cfgRWTransaction::transform() ***
 *************************************************************/

// places newNode as thh first statement in the given SgScopeStmt
void prependToScopeStmt(SgNode *target, SgNode *newNode, void* data);

// places newNode as thh last statement in the given SgBasicBlock
void appendToScopeStmt(SgNode *target, SgNode *newNode, void* data);

}
#endif
#endif