#pragma once #define ACCAN_DEBUG 0 #define USE_INTRINSIC_DVM_LIST 1 #define PRIVATE_ANALYSIS_NOT_CONDUCTED 650 #define PRIVATE_ANALYSIS_ADD_VAR 651 #define PRIVATE_ANALYSIS_REMOVE_VAR 652 #define PRIVATE_ANALYSIS_NO_RECURSION_ANALYSIS 653 #ifdef __SPF extern "C" void printLowLevelWarnings(const char *fileName, const int line, const wchar_t* messageR, const char* messageE, const int group); extern "C" void printLowLevelNote(const char *fileName, const int line, const wchar_t *messageR, const char *messageE, const int group); extern "C" void addToCollection(const int line, const char *file, void *pointer, int type); extern "C" void removeFromCollection(void *pointer); bool IsPureProcedureACC(SgSymbol* s); #endif struct AnalysedCallsList; class ControlFlowItem { int stmtNo; SgLabel* label; ControlFlowItem *jmp; bool for_jump_flag; SgLabel* label_jump; ControlFlowItem* prev; ControlFlowItem* next; bool leader; int bbno; bool is_parloop_start; SgExpression* private_list; bool is_parloop_end; SgStatement* prl_stmt; AnalysedCallsList* call; SgFunctionCallExp* func; SgExpression* pPl; bool fPl; bool drawn; AnalysedCallsList* thisproc; //int refs; SgStatement* originalStatement; ControlFlowItem* conditionFriend; union { SgStatement *stmt; SgExpression *expr; }; public: inline ControlFlowItem(AnalysedCallsList* proc) : stmtNo(-1), label(NULL), jmp(NULL), label_jump(NULL), next(NULL), leader(false), bbno(0), stmt(NULL), is_parloop_start(false), is_parloop_end(false), private_list(NULL), call(NULL), func(NULL), thisproc(proc), originalStatement(NULL), for_jump_flag(false), drawn(false), prev(NULL), conditionFriend(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 3); #endif } inline ControlFlowItem(SgStatement *s, ControlFlowItem *n, AnalysedCallsList* proc, AnalysedCallsList* c = NULL) : stmtNo(-1), label(s ? s->label() : NULL), jmp(NULL), label_jump(NULL), next(n), leader(false), bbno(0), stmt(s), is_parloop_start(false), is_parloop_end(false), private_list(NULL), call(c), func(NULL), thisproc(proc), originalStatement(NULL), for_jump_flag(false), drawn(false), prev(NULL), conditionFriend(NULL) { if (n) { n->prev = this; } #if __SPF addToCollection(__LINE__, __FILE__, this, 3); #endif } inline ControlFlowItem(SgExpression *e, ControlFlowItem *j, ControlFlowItem *n, SgLabel* l, AnalysedCallsList* proc, bool fjf = false, AnalysedCallsList* c = NULL) : stmtNo(-1), label(l), jmp(j), label_jump(NULL), next(n), leader(false), bbno(0), expr(e), is_parloop_start(false), is_parloop_end(false), private_list(NULL), call(c), func(NULL), thisproc(proc), originalStatement(NULL), for_jump_flag(fjf), drawn(false), prev(NULL), conditionFriend(NULL) { if (n) { n->prev = this; } #if __SPF addToCollection(__LINE__, __FILE__, this, 3); #endif } inline ControlFlowItem(SgExpression *e, SgLabel* j, ControlFlowItem* n, SgLabel* l, AnalysedCallsList* proc, AnalysedCallsList* c = NULL) : stmtNo(-1), label(l), jmp(NULL), label_jump(j), next(n), leader(false), bbno(0), expr(e), is_parloop_start(false), is_parloop_end(false), private_list(NULL), call(c), func(NULL), thisproc(proc), originalStatement(NULL), for_jump_flag(false), drawn(false), prev(NULL), conditionFriend(NULL) { if (n) { n->prev = this; } #if __SPF addToCollection(__LINE__, __FILE__, this, 3); #endif } inline void setOriginalStatement(SgStatement* s) { originalStatement = s; } inline SgStatement* getOriginalStatement() { return originalStatement; } inline bool isEnumerated() { return stmtNo >= 0; } inline void setBBno(int bb) { bbno = bb; } inline int getBBno() { return bbno; } inline void AddNextItem(ControlFlowItem *n) { next = n; if (n) n->prev = this; } inline void MakeParloopStart() { is_parloop_start = true; } inline void MakeParloopEnd() { is_parloop_end = true; } inline bool IsParloopStart() { return is_parloop_start; } inline bool IsParloopEnd() { return is_parloop_end; } inline bool isUnconditionalJump() { return ((jmp != NULL || label_jump != NULL) && expr == NULL); } inline SgStatement* getStatement() { if (jmp == NULL) return stmt; else return NULL; } inline SgExpression* getExpression() { if (jmp != NULL) return expr; else return NULL; } inline ControlFlowItem* getJump() { return jmp; } inline ControlFlowItem* getNext() { return next; } inline void setLeader() { leader = true; } inline unsigned int getStmtNo() { return stmtNo; } inline void setStmtNo(unsigned int no) { stmtNo = no; } inline int isLeader() { return leader; } inline void setLabel(SgLabel* l) { label = l; } inline SgLabel* getLabel() { return label; } inline void setLabelJump(SgLabel* l) { label_jump = l; } inline SgLabel* getLabelJump() { return label_jump; } inline void initJump(ControlFlowItem* item) { jmp = item; } inline void setPrivateList(SgExpression* p, SgStatement* s, SgExpression* m, bool mf) { private_list = p; prl_stmt = s; pPl = m; fPl = mf; } inline SgExpression* getPrivateList() { return private_list; } inline SgStatement* getPrivateListStatement() { return prl_stmt; } inline SgExpression* getExpressionToModifyPrivateList(bool* rhs) { if (rhs) *rhs = fPl; return pPl; } inline AnalysedCallsList* getCall() { return call; } inline void setFunctionCall(SgFunctionCallExp* f) { func = f; } inline SgFunctionCallExp* getFunctionCall() { return func; } inline AnalysedCallsList* getProc() { return thisproc; } inline bool IsForJumpFlagSet() { return for_jump_flag; } inline bool IsEmptyCFI() { return getStatement() == NULL; } inline void SetIsDrawn() { drawn = true; } inline void ResetDrawnStatus() { drawn = false; } inline bool IsDrawn() { return drawn; } inline ControlFlowItem* GetPrev() { return prev; } inline void SetConditionFriend(ControlFlowItem* f) { conditionFriend = f; } inline ControlFlowItem* GetFriend() { return conditionFriend; } int GetLineNumber(); #if ACCAN_DEBUG void printDebugInfo(); #endif ~ControlFlowItem() { #if __SPF removeFromCollection(this); #endif } }; class doLoopItem { int label; SgSymbol* name; ControlFlowItem* iter; ControlFlowItem* emptyAfter; bool current; doLoopItem* next; int parallel_depth; SgExpression* prl; SgExpression* pPl; bool plf; SgStatement* prs; public: inline doLoopItem(int l, SgSymbol* s, ControlFlowItem* i, ControlFlowItem* e) : label(l), name(s), iter(i), emptyAfter(e), current(true), next(NULL), parallel_depth(-1) { #if __SPF addToCollection(__LINE__, __FILE__, this, 4); #endif } ~doLoopItem() { #if __SPF removeFromCollection(this); #endif } inline void HandleNewItem(doLoopItem* it) { setParallelDepth(it->parallel_depth, it->prl, it->prs, it->pPl, it->plf); } inline void setNext(doLoopItem* n) { next = n; } inline void setNewLabel(int l) { label = l; } inline ControlFlowItem* getSourceForCycle() { return iter; } inline ControlFlowItem* getSourceForExit() { return emptyAfter; } inline SgSymbol* getName() { return name; } inline doLoopItem* getNext() { return next; } inline int getLabel() { return label; } inline void setParallelDepth(int k, SgExpression* pl, SgStatement* ps, SgExpression* pPl, bool plf) { parallel_depth = k; prl = pl; prs = ps; this->pPl = pPl; this->plf = plf; } inline SgStatement* GetParallelStatement() { return prs; } inline bool isLastParallel() { if (parallel_depth > 0) return --parallel_depth == 0; return 0; } inline SgExpression* getPrivateList() { return prl; } inline SgExpression* getExpressionToModifyPrivateList(bool* rhs) { if (rhs) *rhs = plf; return pPl; } }; class doLoops { doLoopItem* first; doLoopItem* current; doLoopItem* findLoop(SgSymbol*); public: inline doLoops() : first(NULL), current(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 5); #endif } inline ControlFlowItem* getSourceForCycle() { return current ? current->getSourceForCycle() : NULL; } inline ControlFlowItem* getSourceForCycle(SgSymbol* loop) { return loop ? findLoop(loop)->getSourceForCycle() : getSourceForCycle(); } inline ControlFlowItem* getSourceForExit() { return current ? current->getSourceForExit() : NULL; } inline ControlFlowItem* getSourceForExit(SgSymbol* loop) { return loop ? findLoop(loop)->getSourceForExit() : getSourceForExit(); } inline void setParallelDepth(int k, SgExpression* pl, SgStatement* ps, SgExpression* pPl, bool plf) { current->setParallelDepth(k, pl, ps, pPl, plf); } inline SgStatement* GetParallelStatement() { return current->GetParallelStatement(); } inline bool isLastParallel() { return current && current->isLastParallel(); } inline SgExpression* getPrivateList() { return current->getPrivateList(); } inline SgExpression* getExpressionToModifyPrivateList(bool* rhs) { return current->getExpressionToModifyPrivateList(rhs); } void addLoop(int l, SgSymbol* s, ControlFlowItem* i, ControlFlowItem* e); ControlFlowItem* endLoop(ControlFlowItem* last); ControlFlowItem* checkStatementForLoopEnding(int label, ControlFlowItem* item); ~doLoops(); }; struct LabelCFI { int l; ControlFlowItem* item; LabelCFI() : item(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 6); #endif } ~LabelCFI() { #if __SPF removeFromCollection(this); #endif } }; struct CLAStatementItem { SgStatement* stmt; CLAStatementItem* next; ~CLAStatementItem(); CLAStatementItem* GetLast(); CLAStatementItem() : stmt(NULL), next(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 7); #endif } }; enum eVariableType { VAR_REF_VAR_EXP, VAR_REF_RECORD_EXP, VAR_REF_ARRAY_EXP }; #define PRIVATE_GET_LAST_ASSIGN 0 class CVarEntryInfo; struct VarItem { CVarEntryInfo* var; CVarEntryInfo* ov; int file_id; //CLAStatementItem* lastAssignments; #if PRIVATE_GET_LAST_ASSIGN std::list lastAssignments; #endif VarItem* next; VarItem() : var(NULL), ov(NULL), next(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 8); #endif } ~VarItem() { #if __SPF removeFromCollection(this); #endif } }; class CArrayVarEntryInfo; class VarSet { VarItem* list; public: inline VarSet() : list(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 9); #endif } void addToSet(CVarEntryInfo*, SgStatement*, CVarEntryInfo* ov = NULL); void PossiblyAffectArrayEntry(CArrayVarEntryInfo*); void intersect(VarSet*, bool, bool); void unite(VarSet*, bool); void minus(VarSet*, bool complete = false); void minusFinalize(VarSet*, bool complete = false); bool RecordBelong(CVarEntryInfo*); void LeaveOnlyRecords(); void RemoveDoubtfulCommonVars(AnalysedCallsList*); VarItem* GetArrayRef(CArrayVarEntryInfo*); //VarItem* belongs(SgVarRefExp*, bool os = false); VarItem* belongs(const CVarEntryInfo*, bool os = false); VarItem* belongs(SgSymbol*, bool os = false); bool equal(VarSet*); int count(); void print(); void remove(const CVarEntryInfo*); VarItem* getFirst(); ~VarSet(); inline bool isEmpty() { return list == NULL; } }; struct DoLoopDataItem { int file_id; SgStatement* statement; SgExpression* l; SgExpression* r; SgExpression* st; SgSymbol* loop_var; DoLoopDataItem* next; DoLoopDataItem() : l(NULL), r(NULL), st(NULL), loop_var(NULL), next(NULL), statement(NULL), file_id(-1) { #if __SPF addToCollection(__LINE__, __FILE__, this, 10); #endif } ~DoLoopDataItem() { #if __SPF removeFromCollection(this); #endif } }; class DoLoopDataList { DoLoopDataItem* list; public: DoLoopDataList() : list(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 11); #endif } void AddLoop(int file_id, SgStatement* st, SgExpression* l, SgExpression* r, SgExpression* step, SgSymbol* lv); DoLoopDataItem* FindLoop(SgStatement* st); ~DoLoopDataList(); }; struct ArraySubscriptData; class CVarEntryInfo { SgSymbol* symbol; int references; public: CVarEntryInfo(SgSymbol* s) : symbol(s), references(1) { #if __SPF addToCollection(__LINE__, __FILE__, this, 12); #endif } virtual ~CVarEntryInfo() { #if __SPF removeFromCollection(this); #endif } virtual eVariableType GetVarType() const = 0; virtual CVarEntryInfo* Clone(SgSymbol*) const = 0; virtual CVarEntryInfo* Clone() const = 0; virtual CVarEntryInfo* GetLeftmostParent() = 0; virtual void RegisterUsage(VarSet* def, VarSet* use, SgStatement* st) = 0; virtual void RegisterDefinition(VarSet* def, VarSet* use, SgStatement* st) = 0; SgSymbol* GetSymbol() const { return symbol; } virtual bool operator==(const CVarEntryInfo& rhs) const = 0; void AddReference() { references++; } bool RemoveReference() { return --references == 0; } void SwitchSymbol(SgSymbol* s) { symbol = s; } }; class CScalarVarEntryInfo: public CVarEntryInfo { public: CScalarVarEntryInfo(SgSymbol* s) : CVarEntryInfo(s) { #if __SPF addToCollection(__LINE__, __FILE__, this, 13); #endif } ~CScalarVarEntryInfo() { #if __SPF removeFromCollection(this); #endif } eVariableType GetVarType() const { return VAR_REF_VAR_EXP; } CVarEntryInfo* Clone(SgSymbol* s) const { return new CScalarVarEntryInfo(s); } CVarEntryInfo* Clone() const { return new CScalarVarEntryInfo(GetSymbol()); } bool operator==(const CVarEntryInfo& rhs) const { return rhs.GetVarType() == VAR_REF_VAR_EXP && rhs.GetSymbol() == GetSymbol(); } CVarEntryInfo* GetLeftmostParent() { return this; } void RegisterUsage(VarSet* def, VarSet* use, SgStatement* st) { if (def == NULL || !def->belongs(this)) use->addToSet(this, st); } void RegisterDefinition(VarSet* def, VarSet* use, SgStatement* st) { def->addToSet(this, st); } }; class CRecordVarEntryInfo : public CVarEntryInfo { CVarEntryInfo* parent; public: CRecordVarEntryInfo(SgSymbol* s, CVarEntryInfo* ptr) : CVarEntryInfo(s), parent(ptr) { #if __SPF addToCollection(__LINE__, __FILE__, this, 14); #endif } ~CRecordVarEntryInfo() { #if __SPF removeFromCollection(this); return; #endif if (parent->RemoveReference()) delete parent; } eVariableType GetVarType() const { return VAR_REF_RECORD_EXP; } CVarEntryInfo* Clone(SgSymbol* s) const { return new CRecordVarEntryInfo(s, parent->Clone()); } CVarEntryInfo* Clone() const { return new CRecordVarEntryInfo(GetSymbol(), parent->Clone()); } bool operator==(const CVarEntryInfo& rhs) const { return rhs.GetVarType() == VAR_REF_RECORD_EXP && rhs.GetSymbol() == GetSymbol() && parent && static_cast(rhs).parent && *static_cast(rhs).parent == *parent; } CVarEntryInfo* GetLeftmostParent() { return parent->GetLeftmostParent(); } void RegisterUsage(VarSet* def, VarSet* use, SgStatement* st) { if (def == NULL || !def->belongs(this)) use->addToSet(this, st); } void RegisterDefinition(VarSet* def, VarSet* use, SgStatement* st) { def->addToSet(this, st); } }; struct ArraySubscriptData { bool defined; int bound_modifiers[2]; int step; int coefs[2]; DoLoopDataItem *loop; SgExpression *left_bound; SgExpression *right_bound; ArraySubscriptData() : loop(NULL), left_bound(NULL), right_bound(NULL) { defined = false; step = 0; coefs[0] = coefs[1] = 0; bound_modifiers[0] = bound_modifiers[1] = 0; //nowhere allocated /*#if __SPF addToCollection(__LINE__, __FILE__, this, 15); #endif*/ } ~ArraySubscriptData() { } }; class CArrayVarEntryInfo : public CVarEntryInfo { int subscripts; bool disabled; std::vector data; public: CArrayVarEntryInfo(SgSymbol* s, SgArrayRefExp* r); CArrayVarEntryInfo(SgSymbol* s, int sub, int ds, const std::vector &d); ~CArrayVarEntryInfo() { #if __SPF removeFromCollection(this); #endif } CVarEntryInfo* Clone(SgSymbol* s) const { return new CArrayVarEntryInfo(s, subscripts, disabled, data); } CVarEntryInfo* Clone() const { return new CArrayVarEntryInfo(GetSymbol(), subscripts, disabled, data); } bool operator==(const CVarEntryInfo& rhs) const { return rhs.GetVarType() == VAR_REF_ARRAY_EXP && rhs.GetSymbol() == GetSymbol(); } friend CArrayVarEntryInfo* operator-(const CArrayVarEntryInfo&, const CArrayVarEntryInfo&); friend CArrayVarEntryInfo* operator+(const CArrayVarEntryInfo&, const CArrayVarEntryInfo&); CArrayVarEntryInfo& operator+=(const CArrayVarEntryInfo&); CArrayVarEntryInfo& operator-=(const CArrayVarEntryInfo&); CArrayVarEntryInfo& operator*=(const CArrayVarEntryInfo&); eVariableType GetVarType() const { return VAR_REF_ARRAY_EXP; } CVarEntryInfo* GetLeftmostParent() { return this; } void RegisterUsage(VarSet* def, VarSet* use, SgStatement* st); void RegisterDefinition(VarSet* def, VarSet* use, SgStatement* st); bool HasActiveElements() const; void MakeInactive(); void ProcessChangesToUsedEntry(CArrayVarEntryInfo*); }; class CBasicBlock; class ControlFlowGraph; struct AnalysedCallsList; class PrivateDelayedItem; struct BasicBlockItem { CBasicBlock* block; bool for_jump_flag; bool cond_value; bool drawn; ControlFlowItem* jmp; BasicBlockItem* next; BasicBlockItem() : drawn(false) { #if __SPF addToCollection(__LINE__, __FILE__, this, 17); #endif } ~BasicBlockItem() { #if __SPF removeFromCollection(this); #endif } }; struct CommonVarSet; struct ActualDelayedData; struct CallAnalysisLog { AnalysedCallsList* el; int depth; CallAnalysisLog* prev; CallAnalysisLog() : el(NULL), prev(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 18); #endif } ~CallAnalysisLog() { #if __SPF removeFromCollection(this); #endif } }; struct CExprList { SgExpression* entry; CExprList* next; CExprList() : entry(NULL), next(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 19); #endif } ~CExprList() { #if __SPF removeFromCollection(this); #endif } }; #ifdef __SPF class SymbolKey { private: SgSymbol *var; std::string varName; bool pointer; public: SymbolKey(SgSymbol *v): var(v), varName(v->identifier()), pointer(false) { #if __SPF addToCollection(__LINE__, __FILE__, this, 20); #endif } SymbolKey(SgSymbol *v, bool isPointer): var(v), varName(v->identifier()), pointer(isPointer) { #if __SPF addToCollection(__LINE__, __FILE__, this, 20); #endif } ~SymbolKey() { #if __SPF removeFromCollection(this); #endif } inline const std::string& getVarName() const { return varName; } inline const SgSymbol* getSymbol() const { return var; } inline bool isPointer() const { return pointer; } inline bool operator<(const SymbolKey &rhs) const { return varName < rhs.varName; } inline bool operator==(const SymbolKey &rhs) const { return varName == rhs.varName; } inline bool operator==(SgSymbol *rhs) const { return strcmp(varName.c_str(), rhs->identifier()) == 0; } }; class ExpressionValue { private: SgExpression *exp; std::string unparsed; SgStatement* from; public: ExpressionValue(): exp(NULL), unparsed(""), from(NULL) {} //ExpressionValue(SgExpression *e): exp(e) { unparsed = (e != NULL ? e->unparse() : ""); } ExpressionValue(SgExpression *e, const std::string &unp) : exp(e), unparsed(unp), from(NULL) { } ExpressionValue(SgExpression *e, const std::string &unp, SgStatement* f) : exp(e), unparsed(unp), from(f) { } inline bool unparsedEquals(ExpressionValue &other) const {return unparsed == other.unparsed; } inline bool unparsedEquals(ExpressionValue *other) const {return unparsed == other->unparsed; } inline SgExpression* getExp() const { return exp; } inline const std::string& getUnparsed() const { return unparsed; } inline void setFrom(SgStatement* st) { from = st; } inline SgStatement* getFrom() const { return from; } inline bool operator<(const ExpressionValue &other) const { return from == other.from ? unparsed < other.unparsed : from < other.from; } inline bool operator==(const ExpressionValue &other) const { return from == other.from && unparsed == other.unparsed; } inline bool operator==(SgExpression* e) const { return strcmp(unparsed.c_str(), e->unparse()) == 0; } }; #endif class CBasicBlock { int num; ControlFlowGraph* parent; ControlFlowItem* start; AnalysedCallsList* proc; BasicBlockItem* prev; BasicBlockItem* succ; CBasicBlock* lexNext; CBasicBlock* lexPrev; VarSet* def; VarSet* use; VarSet* old_mrd_out; VarSet* old_mrd_in; VarSet* mrd_in; VarSet* mrd_out; VarSet* old_lv_out; VarSet* old_lv_in; VarSet* lv_in; VarSet* lv_out; CommonVarSet* common_def; CommonVarSet* common_use; bool undef; bool lv_undef; void setDefAndUse(); char prev_status; bool temp; void addExprToUse(SgExpression* e, CArrayVarEntryInfo*, CExprList*); void AddOneExpressionToUse(SgExpression*, SgStatement*, CArrayVarEntryInfo*); void AddOneExpressionToDef(SgExpression*, SgStatement*, CArrayVarEntryInfo*); PrivateDelayedItem* privdata; CVarEntryInfo* findentity; std::string visname; std::string visunparse; #ifdef __SPF bool varIsPointer(SgSymbol* symbol); void processAssignThroughPointer(SgSymbol *symbol, SgExpression *right, SgStatement *st); void processPointerAssignment(SgSymbol *symbol, SgExpression *right, SgStatement *st); void processReadStat(SgStatement* readSt); void addVarUnknownToGen(SymbolKey var, SgStatement *defSt); std::map > gen_p; std::set kill_p; std::map > in_defs_p; std::map > out_defs_p; std::map gen; std::set kill; std::map > in_defs; std::map > out_defs; std::set e_gen; std::set e_in; std::set e_out; #endif public: inline CBasicBlock(bool t, ControlFlowItem* st, int n, ControlFlowGraph* par, AnalysedCallsList* pr) : temp(t), num(n), start(st), prev(NULL), lexNext(NULL), def(NULL), use(NULL), mrd_in(new VarSet()), mrd_out(new VarSet()), undef(true), lv_in(new VarSet()), lv_out(new VarSet()), lv_undef(false), succ(NULL), lexPrev(NULL), prev_status(-1), parent(par), common_def (NULL), common_use(NULL), old_mrd_in(NULL), old_mrd_out(NULL), old_lv_in(NULL), old_lv_out(NULL), privdata(NULL), findentity(NULL), proc(pr) { #if __SPF addToCollection(__LINE__, __FILE__, this, 21); #endif } ~CBasicBlock(); inline CommonVarSet* getCommonDef() { return common_def; } inline CommonVarSet* getCommonUse() { return common_use; } inline void setNext(CBasicBlock* next) { lexNext = next; } inline void setPrev(CBasicBlock* prev) { lexPrev = prev; } void addToPrev(CBasicBlock* pr, bool, bool, ControlFlowItem*); void addToSucc(CBasicBlock* su, bool, bool, ControlFlowItem*); VarSet* getDef(); VarSet* getUse(); VarSet* getMrdIn(bool); VarSet* getMrdOut(bool); VarSet* getLVIn(); VarSet* getLVOut(); bool stepMrdIn(bool); bool stepMrdOut(bool); bool stepLVIn(); bool stepLVOut(); ControlFlowItem* containsParloopStart(); ControlFlowItem* containsParloopEnd(); ControlFlowItem* getStart(); ControlFlowItem* getEnd(); inline CBasicBlock* getLexNext() { return lexNext; } inline CBasicBlock* getLexPrev() { return lexPrev; } inline BasicBlockItem* getPrev() { return prev; } inline BasicBlockItem* getSucc() { return succ; } inline VarSet* getLiveIn() { return lv_in; } inline int getNum() { return num; } inline void SetDelayedData(PrivateDelayedItem* p) { privdata = p; } inline PrivateDelayedItem* GetDelayedData() { return privdata; } void print(); void markAsReached(); bool hasPrev(); void ProcessProcedureHeader(bool, SgProcHedrStmt*, void*, const char*); void ProcessIntrinsicProcedure(bool, int narg, void* f, const char*); void ProcessUserProcedure(bool isFun, void* call, AnalysedCallsList* c); void ProcessProcedureWithoutBody(bool, void*, bool); //SgExpression* GetProcedureArgument(bool, void*, int); //int GetNumberOfArguments(bool, void*); SgSymbol* GetProcedureName(bool, void*); void PrivateAnalysisForAllCalls(); ActualDelayedData* GetDelayedDataForCall(CallAnalysisLog*); bool IsVarDefinedAfterThisBlock(CVarEntryInfo*, bool); bool ShouldThisBlockBeCheckedAgain(CVarEntryInfo* var) { return findentity && var && *var == *findentity; } std::string GetGraphVisDescription(); std::string GetGraphVisData(); bool IsEmptyBlock(); std::string GetEdgesForBlock(std::string name, bool original, std::string); void addUniqObjects(std::set &pointers) const { for (ControlFlowItem *it = start; it != NULL; it = it->getNext()) pointers.insert(it); } #ifdef __SPF AnalysedCallsList* getProc() { return proc; } void clearGenKill() { gen.clear(); kill.clear(); e_gen.clear(); } void clearGenKillPointers() { gen_p.clear(); kill_p.clear(); } void clearDefs() { in_defs.clear(); out_defs.clear(); e_in.clear(); e_out.clear(); } void clearDefsPointers() { in_defs_p.clear(); out_defs_p.clear(); } void addVarToGen(SymbolKey var, SgExpression* value, SgStatement *defSt); void addVarToKill(const SymbolKey &key); void checkFuncAndProcCalls(ControlFlowItem* cfi); void adjustGenAndKill(ControlFlowItem* cfi); void adjustGenAndKillP(ControlFlowItem* cfi); std::set* getOutVars(); void correctInDefsSimple(); bool correctInDefsIterative(); bool expressionIsAvailable(ExpressionValue* expValue); //const std::map> getReachedDefinitions(SgStatement* stmt); const std::map> getReachedDefinitionsExt(SgStatement* stmt); void initializeOut(); void initializeEOut(std::set& allEDefs); bool updateEDefs(); inline std::map>* getGenP() { return &gen_p; } inline std::set* getKillP() { return &kill_p; } inline void setInDefsP(std::map>* inDefsP) { in_defs_p = *inDefsP; } inline std::map>* getInDefsP() { return &in_defs_p; } inline std::map>* getOutDefsP() { return &out_defs_p; } inline std::map* getGen() { return &gen; } inline std::set* getKill() { return &kill; } inline void setInDefs(std::map>* inDefs) { in_defs = *inDefs; } inline std::map>* getInDefs() { return &in_defs; } inline std::map>* getOutDefs() { return &out_defs; } inline std::set* getEGen() { return &e_gen; } inline std::set* getEIn() { return &e_in; } inline std::set* getEOut() { return &e_out; } #endif }; struct CommonVarInfo; struct CommonVarSet { CommonVarInfo* cvd; CommonVarSet* next; CommonVarSet(const CommonVarSet&); CommonVarSet() : cvd(NULL), next(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 22); #endif } ~CommonVarSet() { #if __SPF removeFromCollection(this); #endif } }; struct ActualDelayedData; class CommonData; class CallData; class ControlFlowGraph { CBasicBlock* last; CBasicBlock* first; VarSet* def; VarSet* use; VarSet* pri; CommonVarSet* common_def; bool cdf; CommonVarSet* common_use; bool cuf; bool temp; bool main; int refs; bool hasBeenAnalyzed; void liveAnalysis(); #ifdef __SPF std::set pointers; #endif public: ControlFlowGraph(bool temp, bool main, ControlFlowItem* item, ControlFlowItem* end); ~ControlFlowGraph(); VarSet* getPrivate(); VarSet* getUse(); VarSet* getDef(); void privateAnalyzer(); bool ProcessOneParallelLoop(ControlFlowItem* lstart, CBasicBlock* of, CBasicBlock*& p, bool); ActualDelayedData* ProcessDelayedPrivates(CommonData*, AnalysedCallsList*, CallAnalysisLog*, void*, bool, int); bool IsMain() { return main; } // change to refs void AddRef() { refs++; } bool RemoveRef() { return refs == 0; } ControlFlowItem* getCFI() { return first->getStart(); } CommonVarSet* getCommonDef() { return common_def; } CommonVarSet* getCommonUse() { return common_use; } inline CBasicBlock* getFirst() { return first; } inline CBasicBlock* getLast() { return last; } std::string GetVisualGraph(CallData*); void ResetDrawnStatusForAllItems(); inline void addCFItoCollection(std::set &collection) const { for (CBasicBlock *bb = first; bb != NULL; bb = bb->getLexNext()) bb->addUniqObjects(collection); } #ifdef __SPF std::set* getPointers() { return &pointers; }; #endif }; struct AnalysedCallsList { SgStatement* header; ControlFlowGraph* graph; bool isIntrinsic; bool isPure; bool isFunction; AnalysedCallsList* next; bool hasBeenAnalysed; bool isCurrent; int file_id; AnalysedCallsList(SgStatement* h, bool intr, bool pure, bool fun, const char* name, int fid) : header(h), isIntrinsic(intr), isPure(pure), isFunction(fun), hasBeenAnalysed(false), graph(NULL), funName(name), file_id(fid), next(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 23); #endif } ~AnalysedCallsList() { #if __SPF removeFromCollection(this); #endif } bool isArgIn(int num, CArrayVarEntryInfo**); bool isArgOut(int num, CArrayVarEntryInfo**); const char* funName; bool IsIntrinsic() { return isIntrinsic; } }; class CommonData; class CallData { AnalysedCallsList* calls_list; bool recursion_flag; public: AnalysedCallsList* getLinkToCall(SgExpression*, SgStatement*, CommonData*); AnalysedCallsList* AddHeader(SgStatement*, bool isFun, SgSymbol* name, int fid); void AssociateGraphWithHeader(SgStatement*, ControlFlowGraph*); AnalysedCallsList* IsHeaderInList(SgStatement*); AnalysedCallsList* GetDataForGraph(ControlFlowGraph*); CallData() { recursion_flag = false; calls_list = NULL; #if __SPF addToCollection(__LINE__, __FILE__, this, 24); #endif } void printControlFlows(); ~CallData(); }; struct CommonDataItem; struct CommonVarInfo { CVarEntryInfo* var; bool isPendingLastPrivate; bool isInUse; CommonDataItem* parent; CommonVarInfo* next; CommonVarInfo() : var(NULL), parent(NULL), next(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 25); #endif } ~CommonVarInfo() { #if __SPF removeFromCollection(this); #endif } }; struct CommonDataItem { SgStatement *cb; std::vector commonRefs; bool isUsable; bool onlyScalars; std::string name; AnalysedCallsList* proc; AnalysedCallsList* first; CommonVarInfo* info; CommonDataItem* next; CommonDataItem() : cb(NULL), proc(NULL), first(NULL), info(NULL), next(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 26); #endif } ~CommonDataItem() { #if __SPF removeFromCollection(this); #endif } }; class CommonData { CommonDataItem* list; public: CommonDataItem* getList() { return list; } void RegisterCommonBlock(SgStatement*, AnalysedCallsList*); void MarkEndOfCommon(AnalysedCallsList*); void MarkAsUsed(VarSet*, AnalysedCallsList*); bool CanHaveNonScalarVars(CommonDataItem*); //void ProcessDelayedPrivates(PrivateDelayedItem*); CommonDataItem* IsThisCommonUsedInProcedure(CommonDataItem*, AnalysedCallsList*); CommonDataItem* GetItemForName(const std::string&, AnalysedCallsList*); CommonVarSet* GetCommonsForVarSet(VarSet*, AnalysedCallsList*); CommonDataItem* IsThisCommonVar(VarItem*, AnalysedCallsList*); CommonData() : list(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 27); #endif } ~CommonData(); }; class PrivateDelayedItem { VarSet* detected; VarSet* original; VarSet* lp; VarSet* delay; ControlFlowItem* lstart; ControlFlowGraph* graph; PrivateDelayedItem* next; int file_id; public: PrivateDelayedItem(VarSet* d, VarSet* o, VarSet* p, ControlFlowItem* l, PrivateDelayedItem* n, ControlFlowGraph* g, VarSet* dl, int fd) : detected(d), original(o), lp(p), lstart(l), next(n), graph(g), delay(dl), file_id(fd) { #if __SPF addToCollection(__LINE__, __FILE__, this, 28); #endif } ~PrivateDelayedItem(); void PrintWarnings(); void MoveFromPrivateToLastPrivate(CVarEntryInfo*); VarSet* getDetected() { return detected; } VarSet* getDelayed() { return delay; } }; #define MAX_ARGS_FOR_INTRINSIC 10 #define INTRINSIC_IN 1 #define INTRINSIC_OUT 2 struct IntrinsicParameterData { int index; const char* name; unsigned char status; }; struct IntrinsicSubroutineData { const char* name; int args; IntrinsicParameterData parameters[MAX_ARGS_FOR_INTRINSIC]; }; struct ActualDelayedData { PrivateDelayedItem* original; CommonVarSet* commons; VarSet* buse; ActualDelayedData* next; AnalysedCallsList* call; void MoveVarFromPrivateToLastPrivate(CVarEntryInfo*, CommonVarSet*, VarSet*); void RemoveVarFromCommonList(CommonVarSet*); ActualDelayedData() : original(NULL), commons(NULL), next(NULL), call(NULL) { #if __SPF addToCollection(__LINE__, __FILE__, this, 29); #endif } ~ActualDelayedData() { #if __SPF removeFromCollection(this); #endif } }; ControlFlowGraph* GetControlFlowGraphWithCalls(bool, SgStatement*, CallData*, CommonData*); void FillCFGSets(ControlFlowGraph*); void SetUpVars(CommonData*, CallData*, AnalysedCallsList*, DoLoopDataList*); AnalysedCallsList* GetCurrentProcedure(); int SwitchFile(int); #if __SPF ExpressionValue* allocateExpressionValue(SgExpression*, SgStatement*); void deleteAllocatedExpressionValues(int file_id); #endif