Skip to content

Commit

Permalink
Allow non-affine control flow -- SCoP Modeling
Browse files Browse the repository at this point in the history
  This allows us to model non-affine regions in the SCoP representation.
  SCoP statements can now describe either basic blocks or non-affine
  regions. In the latter case all accesses in the region are accumulated
  for the statement and write accesses, except in the entry, have to be
  marked as may-write.

Differential Revision: http://reviews.llvm.org/D7846

llvm-svn: 230329
  • Loading branch information
Johannes Doerfert committed Feb 24, 2015
1 parent e704494 commit ff9d198
Show file tree
Hide file tree
Showing 6 changed files with 362 additions and 67 deletions.
80 changes: 71 additions & 9 deletions polly/include/polly/ScopInfo.h
Expand Up @@ -429,9 +429,21 @@ class ScopStmt {

//@}

/// The BasicBlock represented by this statement.
/// @brief A SCoP statement represents either a basic block (affine/precise
/// case) or a whole region (non-affine case). Only one of the
/// following two members will therefore be set and indicate which
/// kind of statement this is.
///
///{

/// @brief The BasicBlock represented by this statement (in the affine case).
BasicBlock *BB;

/// @brief The region represented by this statement (in the non-affine case).
Region *R;

///}

/// @brief The isl AST build for the new generated AST.
isl_ast_build *Build;

Expand All @@ -449,7 +461,17 @@ class ScopStmt {
TempScop &tempScop);
__isl_give isl_set *buildDomain(TempScop &tempScop, const Region &CurRegion);
void buildScattering(SmallVectorImpl<unsigned> &Scatter);
void buildAccesses(TempScop &tempScop);

/// @brief Create the accesses for instructions in @p Block.
///
/// @param tempScop The template SCoP.
/// @param Block The basic block for which accesses should be
/// created.
/// @param isApproximated Flag to indicate blocks that might not be executed,
/// hence for which write accesses need to be modelt as
/// may-write accesses.
void buildAccesses(TempScop &tempScop, BasicBlock *Block,
bool isApproximated = false);

/// @brief Detect and mark reductions in the ScopStmt
void checkForReductions();
Expand Down Expand Up @@ -489,14 +511,19 @@ class ScopStmt {
/// or non-optimal run-time checks.
void deriveAssumptionsFromGEP(GetElementPtrInst *Inst);

/// @brief Scan the scop and derive assumptions about parameter values.
void deriveAssumptions();
/// @brief Scan @p Block and derive assumptions about parameter values.
void deriveAssumptions(BasicBlock *Block);

/// Create the ScopStmt from a BasicBlock.
ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion,
BasicBlock &bb, SmallVectorImpl<Loop *> &NestLoops,
SmallVectorImpl<unsigned> &Scatter);

/// Create an overapproximating ScopStmt for the region @p R.
ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion, Region &R,
SmallVectorImpl<Loop *> &NestLoops,
SmallVectorImpl<unsigned> &Scatter);

friend class Scop;

public:
Expand Down Expand Up @@ -532,11 +559,24 @@ class ScopStmt {
/// @brief Get an isl string representing this scattering.
std::string getScatteringStr() const;

/// @brief Get the BasicBlock represented by this ScopStmt.
/// @brief Get the BasicBlock represented by this ScopStmt (if any).
///
/// @return The BasicBlock represented by this ScopStmt.
/// @return The BasicBlock represented by this ScopStmt, or null if the
/// statement represents a region.
BasicBlock *getBasicBlock() const { return BB; }

/// @brief Return true if this statement represents a single basic block.
bool isBlockStmt() const { return BB != nullptr; }

/// @brief Get the region represented by this ScopStmt (if any).
///
/// @return The region represented by this ScopStmt, or null if the statement
/// represents a basic block.
Region *getRegion() const { return R; }

/// @brief Return true if this statement represents a whole region.
bool isRegionStmt() const { return R != nullptr; }

const MemoryAccess &getAccessFor(const Instruction *Inst) const {
MemoryAccess *A = lookupAccessFor(Inst);
assert(A && "Cannot get memory access because it does not exist!");
Expand All @@ -549,7 +589,12 @@ class ScopStmt {
return at == InstructionToAccess.end() ? NULL : at->second;
}

void setBasicBlock(BasicBlock *Block) { BB = Block; }
void setBasicBlock(BasicBlock *Block) {
// TODO: Handle the case where the statement is a region statement, thus
// the entry block was split and needs to be changed in the region R.
assert(BB && "Cannot set a block for a region statement");
BB = Block;
}

typedef MemoryAccessVec::iterator iterator;
typedef MemoryAccessVec::const_iterator const_iterator;
Expand Down Expand Up @@ -697,7 +742,8 @@ class Scop {

/// Create the static control part with a region, max loop depth of this
/// region and parameters used in this region.
Scop(TempScop &TempScop, LoopInfo &LI, ScalarEvolution &SE, isl_ctx *ctx);
Scop(TempScop &TempScop, LoopInfo &LI, ScalarEvolution &SE, ScopDetection &SD,
isl_ctx *ctx);

/// @brief Check if a basic block is trivial.
///
Expand All @@ -719,12 +765,28 @@ class Scop {
/// @brief Simplify the assumed context.
void simplifyAssumedContext();

/// @brief Create a new SCoP statement for either @p BB or @p R.
///
/// Either @p BB or @p R should be non-null. A new statement for the non-null
/// argument will be created and added to the statement vector and map.
///
/// @param BB The basic block we build the statement for (or null)
/// @param R The region we build the statement for (or null).
/// @param tempScop The temp SCoP we use as model.
/// @param CurRegion The SCoP region.
/// @param NestLoops A vector of all surrounding loops.
/// @param Scatter The position of the new statement as scattering.
void addScopStmt(BasicBlock *BB, Region *R, TempScop &tempScop,
const Region &CurRegion, SmallVectorImpl<Loop *> &NestLoops,
SmallVectorImpl<unsigned> &Scatter);

/// Build the Scop and Statement with precalculated scop information.
void buildScop(TempScop &TempScop, const Region &CurRegion,
// Loops in Scop containing CurRegion
SmallVectorImpl<Loop *> &NestLoops,
// The scattering numbers
SmallVectorImpl<unsigned> &Scatter, LoopInfo &LI);
SmallVectorImpl<unsigned> &Scatter, LoopInfo &LI,
ScopDetection &SD);

/// @name Helper function for printing the Scop.
///
Expand Down
15 changes: 8 additions & 7 deletions polly/include/polly/TempScopInfo.h
Expand Up @@ -80,6 +80,8 @@ class IRAccess {

bool isWrite() const { return Type == MUST_WRITE; }

void setMayWrite() { Type = MAY_WRITE; }

bool isMayWrite() const { return Type == MAY_WRITE; }

bool isScalar() const { return Subscripts.size() == 0; }
Expand Down Expand Up @@ -136,7 +138,7 @@ class TempScop {
const BBCondMapType &BBConds;

// Access function of bbs.
const AccFuncMapType &AccFuncMap;
AccFuncMapType &AccFuncMap;

friend class TempScopInfo;

Expand Down Expand Up @@ -169,8 +171,8 @@ class TempScop {
///
/// @return All access functions in BB
///
const AccFuncSetType *getAccessFunctions(const BasicBlock *BB) const {
AccFuncMapType::const_iterator at = AccFuncMap.find(BB);
AccFuncSetType *getAccessFunctions(const BasicBlock *BB) {
AccFuncMapType::iterator at = AccFuncMap.find(BB);
return at != AccFuncMap.end() ? &(at->second) : 0;
}
//@}
Expand Down Expand Up @@ -239,10 +241,9 @@ class TempScopInfo : public FunctionPass {

/// @brief Build condition constrains to BBs in a valid Scop.
///
/// @param BB The BasicBlock to build condition constrains
/// @param RegionEntry The entry block of the Smallest Region that containing
/// BB
void buildCondition(BasicBlock *BB, BasicBlock *RegionEntry);
/// @param BB The BasicBlock to build condition constrains
/// @param R The region for the current TempScop.
void buildCondition(BasicBlock *BB, Region &R);

// Build the affine function of the given condition
void buildAffineCondition(Value &V, bool inverted, Comparison **Comp) const;
Expand Down

0 comments on commit ff9d198

Please sign in to comment.