Program Listing for File LoopTreeTransform.h#
↰ Return to documentation for file (src/midend/programTransformation/loopProcessing/computation/LoopTreeTransform.h)
#ifndef TRANSFORM_LOOP_TREE_H
#define TRANSFORM_LOOP_TREE_H
#include <vector>
#include <list>
#include <LoopTree.h>
#include <LoopTreeHoldNode.h>
#include <DepRel.h>
class ObserveTransform;
class LoopTreeTransform
{
protected:
void UnlinkNode( LoopTreeNode* n) { n->Unlink(); }
void ReplaceChildren( LoopTreeNode *on, LoopTreeNode *nn, int pos);
void InsertNode( LoopTreeNode *node, LoopTreeNode *pos, int opt);
void RemoveNode( LoopTreeNode* node) { node->RemoveSelf(); }
public:
LoopTreeNode* InsertHandle(LoopTreeNode *pos, int opt); // opt == -1 as parent; 1 : as child
LoopTreeNode* InsertLoop( LoopTreeNode* l,LoopTreeNode *pos, int opt);
};
class LoopTreeDistributeNode : public LoopTreeTransform
{
typedef RoseSelectObject<LoopTreeNode*>& SelectLoopTreeNode;
LoopTreeNode* Distribute( LoopTreeNode *n, SelectLoopTreeNode sel,
int pos, /*-1: before n; 1: after n*/
ObserveTransform &ob, LoopTreeNode** loc=0);
/* QY: distribute the parent of loc to separate all children before loc */
LoopTreeNode* DistributeBefore(LoopTreeNode* parent, LoopTreeNode* loc);
public:
typedef enum {BEFORE, AFTER} Location;
/* QY: distribute n; put the distributed node before/after n or based on
on original locations of split children */
LoopTreeNode* operator () (LoopTreeNode *n, SelectLoopTreeNode sel, Location config=BEFORE);
};
class LoopTreeSplitStmt : public LoopTreeTransform
{
LoopTreeNode* operator() (LoopTreeNode *stmt, LoopTreeNode* restr1, LoopTreeNode* restr2);
public:
LoopTreeNode* operator() ( LoopTreeNode *stmt, LoopTreeNode* loop1,
LoopTreeNode* loop2, DepRel r);
LoopTreeNode* operator() ( LoopTreeNode *stmt, LoopTreeNode* loop, const SymbolicVal& split);
};
class LoopTreeMergeLoop : public LoopTreeTransform
{ public: void operator () (LoopTreeNode *ancs,LoopTreeNode *desc, int align);
};
class LoopTreeMergeStmtLoop : public LoopTreeTransform
{ public: void operator () (LoopTreeNode *ancs, LoopTreeNode *desc,
LoopTreeNode *stmt, int align);
};
class LoopTreeBlockLoop : public LoopTreeTransform
{ public:
LoopTreeNode* operator() ( LoopTreeNode *n, SymbolicVar bvar, SymbolicVal b);
};
class LoopTreeSwapNodePos : public LoopTreeTransform
{ public: void operator () ( LoopTreeNode *n1, LoopTreeNode *n2);
};
class LoopTreeEmbedStmt : public LoopTreeTransform
{ public: void operator () (LoopTreeNode *loop, LoopTreeNode* stmt, SymbolicVal selIter);
};
typedef enum {NONE = 0, INIT_COPY = 1, SAVE_COPY = 2, INIT_SAVE_COPY=3,
ALLOC_COPY = 4, ALLOC_INIT_COPY=5, ALLOC_SAVE_COPY=6,
ALLOC_INIT_SAVE_COPY=7, DELETE_COPY = 8,
ALLOC_DELETE_COPY=12, ALLOC_INIT_DELETE_COPY=13,
ALLOC_SAVE_DELETE_COPY=14, ALLOC_INIT_SAVE_DELETE_COPY=15,
SHIFT_COPY = 16, COPY_INSIDE=32} CopyArrayOpt;
std::string CopyArrayOpt2String( CopyArrayOpt opt);
/*QY: descriptor for copying array elements to a buffer space */
class SelectArray
{
public:
/* QY: the array dimension to copy; support only rectangle copy regions */
class ArrayDim
{
SymbolicVal incr, size; /*QY: the increment and size of the copy dim */
int dim; /*QY: dim# (for multi-dimentional arrays) */
std::pair<int,int> accLoops; /*QY: the loops that access the copied dim*/
public:
ArrayDim( int _dim, const SymbolicVal& _incr, const SymbolicVal& _size,
int minLoopLevel, int maxLoopLevel)
: incr(_incr), size(_size), dim(_dim), accLoops(minLoopLevel,maxLoopLevel)
{}
const SymbolicVal& get_incr() const { return incr; }
const SymbolicVal& get_size() const { return size; }
int get_arrDim() const { return dim; }
int get_minLoopLevel() const { return accLoops.first; }
int get_maxLoopLevel() const { return accLoops.second; }
friend class SelectArray;
};
private:
std::vector<SymbolicVal> selstart;/*QY: the array starting address to copy*/
std::list<ArrayDim> selinfo; /*QY: elements to copy after selstart*/
std::string arrname, bufname; /*QY: array name and buffer name */
AstNodeType basetype; /*QY: type of array elements*/
std::vector<SymbolicVal> bufsize; /*QY: buffer stride for each copy dim*/
AstNodePtr prep; /*QY: AST to be inserted before copying */
public:
SelectArray(const AstNodeType& base, const std::string& arr, int arrdim)
: arrname(arr), basetype(base)
{ for (int i = 0; i < arrdim; ++i) selstart.push_back(SymbolicVal()); }
std::string toString() const;
/*QY: insert new select info (selincr,selsize,startdiff) to selinfo.
return whether the internal is modified */
bool insert_selinfo (LoopTreeGetVarBound &context,
int arrDim, SymbolicVal& selincr, SymbolicVal& selsize,
int minLevel, int maxLevel, const SymbolicVal& startdiff);
/*QY: select copy dimension */
bool select( LoopTreeNode* stmt, LoopTreeNode* cproot,
AstInterface::AstNodeList& index) ;
void set_bufname( AstInterface& fa); /*QY: done before doing xform */
void set_bufsize( AstInterface& fa); /*QY: done after selecting dimensions*/
std::string arr_name() const { return arrname; }
AstNodeType elem_type() const { return basetype; }
unsigned arr_dim() const { return selstart.size(); }
unsigned sel_dim() const { return selinfo.size(); }
const SymbolicVal& sel_start(unsigned dim) const
{ assert(dim < selstart.size()); return selstart[dim]; }
SymbolicVal& sel_start(unsigned dim)
{ assert(dim < selstart.size()); return selstart[dim]; }
bool scalar_repl() const;
bool need_allocate_buffer() const;
bool need_delete_buffer() const;
AstNodePtr initcopy_codegen( LoopInfo* shift = 0) const;
AstNodePtr savecopy_codegen() const;
AstNodePtr shiftcopy_codegen( LoopInfo& shift,
const std::vector<SymbolicVal>& arrshift,
const SymbolicVal& bufshift) const;
AstNodePtr allocate_codegen(AstInterface& fa) const;
AstNodePtr delete_codegen(AstInterface& fa) const;
SymbolicVal buf_size() const { return bufsize[bufsize.size()-1]; }
SymbolicVal buf_offset(AstInterface& fa, std::vector<SymbolicVal>& arroffset) const;
/*QY: return scalar repl buffer reference for the given buffer offset */
AstNodePtr buf_codegen(AstInterface& fa, int offset) const;
/*QY: return array copy buffer reference for the given buffer offset */
AstNodePtr buf_codegen(AstInterface& fa, const SymbolicVal& offset) const;
/*QY: return array copy buffer reference for the given array ref*/
AstNodePtr buf_codegen(AstInterface& fa, AstInterface::AstNodeList& arrindex) const;
class const_iterator
{
std::list<ArrayDim>::const_iterator impl;
public:
const_iterator(const std::list<ArrayDim>::const_iterator& that)
: impl(that) {}
const_iterator(const const_iterator& that) : impl(that.impl) {}
bool operator == (const const_iterator& that) const
{ return impl == that.impl; }
bool operator != (const const_iterator& that) const
{ return impl != that.impl; }
void operator ++() { ++impl;}
void operator ++(int) { impl++;}
const ArrayDim& operator *() const { return *impl; }
};
class iterator
{
std::list<ArrayDim>::iterator impl;
public:
iterator(const std::list<ArrayDim>::iterator& that) : impl(that) {}
iterator(const iterator& that) : impl(that.impl) {}
bool operator == (const iterator& that) const
{ return impl == that.impl; }
bool operator != (const iterator& that) const
{ return impl != that.impl; }
void operator ++() { ++impl;}
void operator ++(int) { impl++;}
ArrayDim& operator *() { return *impl; }
friend class SelectArray;
};
const_iterator begin() const { return selinfo.begin(); }
const_iterator end() const { return selinfo.end(); }
iterator begin() { return selinfo.begin(); }
iterator end() { return selinfo.end(); }
void erase(iterator& p) { selinfo.erase(p.impl); }
friend class SelectArray::const_iterator;
};
class CopyArrayConfig
{
public:
CopyArrayConfig(AstInterface& fa, const SelectArray& sel,
CopyArrayOpt opt, LoopTreeNode* shift = 0);
std::string toString() const;
bool shift_buffer() const { return shift != 0; }
CopyArrayOpt get_opt() const { return opt; }
void set_opt(CopyArrayOpt _opt) { opt = _opt; }
AstNodePtr CodeGen( const AstNodePtr& c) const;
SelectArray& get_arr() { return sel; }
const SelectArray& get_arr() const { return sel; }
private:
std::vector<SymbolicVal> arrshift;
LoopInfo* shift;
SymbolicVal bufshift;
SelectArray sel;
CopyArrayOpt opt;
};
class LoopTreeCopyArrayToBuffer : public LoopTreeTransform
{
public:
void operator()( LoopTreeNode* repl,
LoopTreeNode* init, LoopTreeNode* save,
CopyArrayConfig& c);
};
class LoopTreeReplaceAst : public LoopTreeTransform
{
public:
LoopTreeNode* operator()( LoopTreeNode* h,
const AstNodePtr& orig, const AstNodePtr& repl);
};
void ApplyLoopSplitting(LoopTreeNode *r);
void OptimizeLoopTree( LoopTreeNode *r);
#endif