#pragma once struct BasicBlock { int index; SgStatement* head; SgStatement* tail; std::vector in, out;// blocks this block takes control from / passes control to std::set INrd, OUTrd, INae, OUTae;// reaching definitions and extended available expressions std::map > INss;// safe substitutes (expression propagation) BasicBlock() : index(-1), head(NULL), tail(NULL) {} }; class Access; class Array; class Loop; class Access { private: int blockIndex; SgExpression* expr; std::string str; Array* array; int* alignment; public: int getBlockIndex() const { return blockIndex; } SgExpression* getSubscripts() { return expr; } int* getAlignment() const { return alignment; } Access(SgExpression* subscripts, std::string s, Array* array, int blockIndex) : expr(subscripts), str(s), array(array), blockIndex(blockIndex), alignment(NULL) {} void analyze(); void getReferences(SgExpression* expr, std::set& references, std::map& unparsedRefs, std::map& refs) const; ~Access() { delete [] alignment; } }; struct TfmInfo { std::vector transformDims; std::vector > exprs; std::vector coefficients; std::vector first; std::vector second; std::vector zeroSt; std::map > ifCalls; std::map > elseCalls; }; class Array { private: SgSymbol* symbol; int dimension; Loop* loop; std::map accesses; int* alignment; std::vector acrossDims; int acrossType; TfmInfo tfmInfo; public: SgSymbol* getSymbol() const { return symbol; } Loop* getLoop() const { return loop; } int getDimension() const { return dimension; } int getAcrossType() const { return acrossType; } void setAcrossType(const int acrossType) { this->acrossType = acrossType; } std::vector& getAcrossDims() { return acrossDims; } int* getAlignment() const { return alignment; } std::map& getAccesses() { return accesses; } TfmInfo& getTfmInfo() { return tfmInfo; } Array(SgSymbol* symbol, int dimension, Loop* loop) : symbol(symbol), dimension(dimension), loop(loop), alignment(NULL), acrossDims(dimension, -1), acrossType(0) {} void analyze(); void analyzeTransformDimensions(); SgSymbol* findAccess(SgExpression* subscripts, std::string& expr); void addCoefficient(SgExpression* subscripts, std::string& expr, SgSymbol* symbol); void generateAssigns(SgVarRefExp* offsetX, SgVarRefExp* offsetY, SgVarRefExp* Rx, SgVarRefExp* Ry, SgVarRefExp* slash); ~Array() { delete [] alignment; for (std::map::iterator it = accesses.begin(); it != accesses.end(); ++it) delete it->second; } }; class Loop { private: bool enable_opt; bool irregular_acc_opt; bool do_irreg_opt; std::vector blocks; std::map blockIn; enum { ENTRY, EXIT }; SgStatement* loop_body; int dimension; std::map arrays; int* acrossDims; int acrossType; std::vector symbols; std::set privateList; bool IsTargetable(SgStatement* stmt) const; void analyzeAcrossClause(); void analyzeAcrossType(); void analyzeAssignments(int blockIndex, SgStatement* stmt); void buildCFG(); void setupSubstitutes(); void analyzeAssignments(SgExpression* ex, const int blockIndex); void analyzeInderectAccess(); public: const std::vector& getBlocks() const { return blocks; } const std::map& getBlockIn() const { return blockIn; } const std::vector& getSymbols() const { return symbols; } int getDimension() const { return dimension; } int getAcrossType() const { return acrossType; } std::map& getArrays() { return arrays; } std::set& getPrivateList() { return privateList; } Loop(SgStatement* loop_body, bool enable_opt, bool irreg_access = false); // only for RD/AE analyses, which can be later performed only on statements in loop_body // usage: Loop* loop = new Loop(loop_body_stmt); RDs = loop->RDsAt(stmtI); AEs = loop->AEsAt(stmtJ); // note: only one loop object can exist at a time (lhs, rhs, unparsedLhs, unparsedRhs are global for all methods for simplicity, // probably can be added to Loop class and transferred to Array/Access by pointer/reference, and this constraint will be solved) Loop(SgStatement* loop_body); // get defining statements which reach stmt std::set RDsAt(SgStatement* stmt) const; // get statements, rhss of which are available at stmt std::set AEsAt(SgStatement* stmt) const; void getRPN(SgExpression* expr, std::list& rpn) const; void unrollRPN(std::list& rpn, std::map& arity) const; void optimizeRPN(std::list& rpn, std::map& arity, bool unrolled) const; SgExpression* simplify(SgExpression* expr) const; void visualize(const char* scriptName) const; bool irregularAnalysisIsOn() const; ~Loop() { delete [] acrossDims; for (std::map::iterator it = arrays.begin(); it != arrays.end(); ++it) delete it->second; } };