Files
SAPFOR/dvm/fdvm/trunk/include/acc_analyzer.h
2023-09-14 19:43:13 +03:00

1212 lines
36 KiB
C++

#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<SgStatement*> 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<const CRecordVarEntryInfo&>(rhs).parent && *static_cast<const CRecordVarEntryInfo&>(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<ArraySubscriptData> data;
public:
CArrayVarEntryInfo(SgSymbol* s, SgArrayRefExp* r);
CArrayVarEntryInfo(SgSymbol* s, int sub, int ds, const std::vector<ArraySubscriptData> &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 <SymbolKey, std::set<SgExpression*>> gen_p;
std::set <SymbolKey> kill_p;
std::map <SymbolKey, std::set<ExpressionValue*>> in_defs_p;
std::map <SymbolKey, std::set<ExpressionValue*>> out_defs_p;
std::map <SymbolKey, ExpressionValue*> gen;
std::set <SymbolKey> kill;
std::map <SymbolKey, std::set<ExpressionValue*>> in_defs;
std::map <SymbolKey, std::set<ExpressionValue*>> out_defs;
std::set <ExpressionValue*> e_gen;
std::set <ExpressionValue*> e_in;
std::set <ExpressionValue*> 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<ControlFlowItem*> &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<SymbolKey>* getOutVars();
void correctInDefsSimple();
bool correctInDefsIterative();
bool expressionIsAvailable(ExpressionValue* expValue);
//const std::map<SymbolKey, std::set<SgExpression*>> getReachedDefinitions(SgStatement* stmt);
const std::map<SymbolKey, std::set<ExpressionValue*>> getReachedDefinitionsExt(SgStatement* stmt);
void initializeOut();
void initializeEOut(std::set<ExpressionValue*>& allEDefs);
bool updateEDefs();
inline std::map<SymbolKey, std::set<SgExpression*>>* getGenP() { return &gen_p; }
inline std::set<SymbolKey>* getKillP() { return &kill_p; }
inline void setInDefsP(std::map<SymbolKey, std::set<ExpressionValue*>>* inDefsP) { in_defs_p = *inDefsP; }
inline std::map<SymbolKey, std::set<ExpressionValue*>>* getInDefsP() { return &in_defs_p; }
inline std::map<SymbolKey, std::set<ExpressionValue*>>* getOutDefsP() { return &out_defs_p; }
inline std::map<SymbolKey, ExpressionValue*>* getGen() { return &gen; }
inline std::set<SymbolKey>* getKill() { return &kill; }
inline void setInDefs(std::map<SymbolKey, std::set<ExpressionValue*>>* inDefs) { in_defs = *inDefs; }
inline std::map<SymbolKey, std::set<ExpressionValue*>>* getInDefs() { return &in_defs; }
inline std::map<SymbolKey, std::set<ExpressionValue*>>* getOutDefs() { return &out_defs; }
inline std::set<ExpressionValue*>* getEGen() { return &e_gen; }
inline std::set<ExpressionValue*>* getEIn() { return &e_in; }
inline std::set<ExpressionValue*>* 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<SymbolKey> 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<ControlFlowItem*> &collection) const
{
for (CBasicBlock *bb = first; bb != NULL; bb = bb->getLexNext())
bb->addUniqObjects(collection);
}
#ifdef __SPF
std::set<SymbolKey>* 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<SgExpression*> 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