summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp298
1 files changed, 164 insertions, 134 deletions
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 9118bf08c78..424b0f8fd67 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -55,186 +55,216 @@ using namespace polly;
STATISTIC(ScopFound, "Number of valid Scops");
STATISTIC(RichScopFound, "Number of Scops containing a loop");
-/// Translate a SCEVExpression into an isl_pw_aff object.
+/// Translate a 'const SCEV *' expression in an isl_pw_aff.
struct SCEVAffinator : public SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
+public:
+
+ /// @brief Translate a 'const SCEV *' to an isl_pw_aff.
+ ///
+ /// @param Stmt The location at which the scalar evolution expression
+ /// is evaluated.
+ /// @param Expr The expression that is translated.
+ static __isl_give isl_pw_aff *getPwAff(ScopStmt *Stmt, const SCEV *Expr);
+
private:
isl_ctx *Ctx;
int NbLoopSpaces;
const Scop *S;
-public:
- static isl_pw_aff *getPwAff(ScopStmt *Stmt, const SCEV *Scev) {
- Scop *S = Stmt->getParent();
- const Region *Reg = &S->getRegion();
+ SCEVAffinator(const ScopStmt *Stmt);
+ int getLoopDepth(const Loop *L);
+
+ __isl_give isl_pw_aff *visit(const SCEV *Expr);
+ __isl_give isl_pw_aff *visitConstant(const SCEVConstant *Expr);
+ __isl_give isl_pw_aff *visitTruncateExpr(const SCEVTruncateExpr *Expr);
+ __isl_give isl_pw_aff *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr);
+ __isl_give isl_pw_aff *visitSignExtendExpr(const SCEVSignExtendExpr *Expr);
+ __isl_give isl_pw_aff *visitAddExpr(const SCEVAddExpr *Expr);
+ __isl_give isl_pw_aff *visitMulExpr(const SCEVMulExpr *Expr);
+ __isl_give isl_pw_aff *visitUDivExpr(const SCEVUDivExpr *Expr);
+ __isl_give isl_pw_aff *visitAddRecExpr(const SCEVAddRecExpr *Expr);
+ __isl_give isl_pw_aff *visitSMaxExpr(const SCEVSMaxExpr *Expr);
+ __isl_give isl_pw_aff *visitUMaxExpr(const SCEVUMaxExpr *Expr);
+ __isl_give isl_pw_aff *visitUnknown(const SCEVUnknown *Expr);
+
+ friend struct SCEVVisitor<SCEVAffinator, isl_pw_aff *>;
+};
- S->addParams(getParamsInAffineExpr(Reg, Scev, *S->getSE()));
+SCEVAffinator::SCEVAffinator(const ScopStmt *Stmt)
+ : Ctx(Stmt->getIslCtx()), NbLoopSpaces(Stmt->getNumIterators()),
+ S(Stmt->getParent()) {}
- SCEVAffinator Affinator(Stmt);
- return Affinator.visit(Scev);
- }
+__isl_give isl_pw_aff *SCEVAffinator::getPwAff(ScopStmt *Stmt,
+ const SCEV *Scev) {
+ Scop *S = Stmt->getParent();
+ const Region *Reg = &S->getRegion();
- isl_pw_aff *visit(const SCEV *Scev) {
- // In case the scev is a valid parameter, we do not further analyze this
- // expression, but create a new parameter in the isl_pw_aff. This allows us
- // to treat subexpressions that we cannot translate into an piecewise affine
- // expression, as constant parameters of the piecewise affine expression.
- if (isl_id *Id = S->getIdForParam(Scev)) {
- isl_space *Space = isl_space_set_alloc(Ctx, 1, NbLoopSpaces);
- Space = isl_space_set_dim_id(Space, isl_dim_param, 0, Id);
-
- isl_set *Domain = isl_set_universe(isl_space_copy(Space));
- isl_aff *Affine =
- isl_aff_zero_on_domain(isl_local_space_from_space(Space));
- Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1);
-
- return isl_pw_aff_alloc(Domain, Affine);
- }
+ S->addParams(getParamsInAffineExpr(Reg, Scev, *S->getSE()));
- return SCEVVisitor<SCEVAffinator, isl_pw_aff *>::visit(Scev);
- }
-
- SCEVAffinator(const ScopStmt *Stmt)
- : Ctx(Stmt->getIslCtx()), NbLoopSpaces(Stmt->getNumIterators()),
- S(Stmt->getParent()) {}
-
- __isl_give isl_pw_aff *visitConstant(const SCEVConstant *Constant) {
- ConstantInt *Value = Constant->getValue();
- isl_val *v;
-
- // LLVM does not define if an integer value is interpreted as a signed or
- // unsigned value. Hence, without further information, it is unknown how
- // this value needs to be converted to GMP. At the moment, we only support
- // signed operations. So we just interpret it as signed. Later, there are
- // two options:
- //
- // 1. We always interpret any value as signed and convert the values on
- // demand.
- // 2. We pass down the signedness of the calculation and use it to interpret
- // this constant correctly.
- v = isl_valFromAPInt(Ctx, Value->getValue(), /* isSigned */ true);
+ SCEVAffinator Affinator(Stmt);
+ return Affinator.visit(Scev);
+}
- isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
- isl_local_space *ls = isl_local_space_from_space(isl_space_copy(Space));
- isl_aff *Affine = isl_aff_zero_on_domain(ls);
- isl_set *Domain = isl_set_universe(Space);
+__isl_give isl_pw_aff *SCEVAffinator::visit(const SCEV *Expr) {
+ // In case the scev is a valid parameter, we do not further analyze this
+ // expression, but create a new parameter in the isl_pw_aff. This allows us
+ // to treat subexpressions that we cannot translate into an piecewise affine
+ // expression, as constant parameters of the piecewise affine expression.
+ if (isl_id *Id = S->getIdForParam(Expr)) {
+ isl_space *Space = isl_space_set_alloc(Ctx, 1, NbLoopSpaces);
+ Space = isl_space_set_dim_id(Space, isl_dim_param, 0, Id);
- Affine = isl_aff_add_constant_val(Affine, v);
+ isl_set *Domain = isl_set_universe(isl_space_copy(Space));
+ isl_aff *Affine = isl_aff_zero_on_domain(isl_local_space_from_space(Space));
+ Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1);
return isl_pw_aff_alloc(Domain, Affine);
}
- __isl_give isl_pw_aff *visitTruncateExpr(const SCEVTruncateExpr *Expr) {
- llvm_unreachable("SCEVTruncateExpr not yet supported");
- }
-
- __isl_give isl_pw_aff *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
- llvm_unreachable("SCEVZeroExtendExpr not yet supported");
- }
+ return SCEVVisitor<SCEVAffinator, isl_pw_aff *>::visit(Expr);
+}
- __isl_give isl_pw_aff *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
- // Assuming the value is signed, a sign extension is basically a noop.
- // TODO: Reconsider this as soon as we support unsigned values.
- return visit(Expr->getOperand());
- }
+__isl_give isl_pw_aff *
+SCEVAffinator::visitConstant(const SCEVConstant *Expr) {
+ ConstantInt *Value = Expr->getValue();
+ isl_val *v;
- __isl_give isl_pw_aff *visitAddExpr(const SCEVAddExpr *Expr) {
- isl_pw_aff *Sum = visit(Expr->getOperand(0));
+ // LLVM does not define if an integer value is interpreted as a signed or
+ // unsigned value. Hence, without further information, it is unknown how
+ // this value needs to be converted to GMP. At the moment, we only support
+ // signed operations. So we just interpret it as signed. Later, there are
+ // two options:
+ //
+ // 1. We always interpret any value as signed and convert the values on
+ // demand.
+ // 2. We pass down the signedness of the calculation and use it to interpret
+ // this constant correctly.
+ v = isl_valFromAPInt(Ctx, Value->getValue(), /* isSigned */ true);
- for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
- isl_pw_aff *NextSummand = visit(Expr->getOperand(i));
- Sum = isl_pw_aff_add(Sum, NextSummand);
- }
+ isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
+ isl_local_space *ls = isl_local_space_from_space(isl_space_copy(Space));
+ isl_aff *Affine = isl_aff_zero_on_domain(ls);
+ isl_set *Domain = isl_set_universe(Space);
- // TODO: Check for NSW and NUW.
+ Affine = isl_aff_add_constant_val(Affine, v);
- return Sum;
- }
+ return isl_pw_aff_alloc(Domain, Affine);
+}
- __isl_give isl_pw_aff *visitMulExpr(const SCEVMulExpr *Expr) {
- isl_pw_aff *Product = visit(Expr->getOperand(0));
+__isl_give isl_pw_aff *
+SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) {
+ llvm_unreachable("SCEVTruncateExpr not yet supported");
+}
- for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
- isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
+__isl_give isl_pw_aff *
+SCEVAffinator::visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
+ llvm_unreachable("SCEVZeroExtendExpr not yet supported");
+}
- if (!isl_pw_aff_is_cst(Product) && !isl_pw_aff_is_cst(NextOperand)) {
- isl_pw_aff_free(Product);
- isl_pw_aff_free(NextOperand);
- return NULL;
- }
+__isl_give isl_pw_aff *
+SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
+ // Assuming the value is signed, a sign extension is basically a noop.
+ // TODO: Reconsider this as soon as we support unsigned values.
+ return visit(Expr->getOperand());
+}
- Product = isl_pw_aff_mul(Product, NextOperand);
- }
+__isl_give isl_pw_aff *SCEVAffinator::visitAddExpr(const SCEVAddExpr *Expr) {
+ isl_pw_aff *Sum = visit(Expr->getOperand(0));
- // TODO: Check for NSW and NUW.
- return Product;
+ for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
+ isl_pw_aff *NextSummand = visit(Expr->getOperand(i));
+ Sum = isl_pw_aff_add(Sum, NextSummand);
}
- __isl_give isl_pw_aff *visitUDivExpr(const SCEVUDivExpr *Expr) {
- llvm_unreachable("SCEVUDivExpr not yet supported");
- }
+ // TODO: Check for NSW and NUW.
- int getLoopDepth(const Loop *L) {
- Loop *outerLoop =
- S->getRegion().outermostLoopInRegion(const_cast<Loop *>(L));
- assert(outerLoop && "Scop does not contain this loop");
- return L->getLoopDepth() - outerLoop->getLoopDepth();
- }
+ return Sum;
+}
- __isl_give isl_pw_aff *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
- assert(Expr->isAffine() && "Only affine AddRecurrences allowed");
+__isl_give isl_pw_aff *SCEVAffinator::visitMulExpr(const SCEVMulExpr *Expr) {
+ isl_pw_aff *Product = visit(Expr->getOperand(0));
- // Directly generate isl_pw_aff for Expr if 'start' is zero.
- if (Expr->getStart()->isZero()) {
- assert(S->getRegion().contains(Expr->getLoop()) &&
- "Scop does not contain the loop referenced in this AddRec");
+ for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
+ isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
- isl_pw_aff *Start = visit(Expr->getStart());
- isl_pw_aff *Step = visit(Expr->getOperand(1));
- isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
- isl_local_space *LocalSpace = isl_local_space_from_space(Space);
+ if (!isl_pw_aff_is_cst(Product) && !isl_pw_aff_is_cst(NextOperand)) {
+ isl_pw_aff_free(Product);
+ isl_pw_aff_free(NextOperand);
+ return NULL;
+ }
- int loopDimension = getLoopDepth(Expr->getLoop());
+ Product = isl_pw_aff_mul(Product, NextOperand);
+ }
- isl_aff *LAff = isl_aff_set_coefficient_si(
- isl_aff_zero_on_domain(LocalSpace), isl_dim_in, loopDimension, 1);
- isl_pw_aff *LPwAff = isl_pw_aff_from_aff(LAff);
+ // TODO: Check for NSW and NUW.
+ return Product;
+}
- // TODO: Do we need to check for NSW and NUW?
- return isl_pw_aff_add(Start, isl_pw_aff_mul(Step, LPwAff));
- }
+__isl_give isl_pw_aff *SCEVAffinator::visitUDivExpr(const SCEVUDivExpr *Expr) {
+ llvm_unreachable("SCEVUDivExpr not yet supported");
+}
+
+__isl_give isl_pw_aff *
+SCEVAffinator::visitAddRecExpr(const SCEVAddRecExpr *Expr) {
+ assert(Expr->isAffine() && "Only affine AddRecurrences allowed");
- // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
- // if 'start' is not zero.
- ScalarEvolution &SE = *S->getSE();
- const SCEV *ZeroStartExpr = SE.getAddRecExpr(
- SE.getConstant(Expr->getStart()->getType(), 0),
- Expr->getStepRecurrence(SE), Expr->getLoop(), SCEV::FlagAnyWrap);
+ // Directly generate isl_pw_aff for Expr if 'start' is zero.
+ if (Expr->getStart()->isZero()) {
+ assert(S->getRegion().contains(Expr->getLoop()) &&
+ "Scop does not contain the loop referenced in this AddRec");
- isl_pw_aff *ZeroStartResult = visit(ZeroStartExpr);
isl_pw_aff *Start = visit(Expr->getStart());
+ isl_pw_aff *Step = visit(Expr->getOperand(1));
+ isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
+ isl_local_space *LocalSpace = isl_local_space_from_space(Space);
- return isl_pw_aff_add(ZeroStartResult, Start);
+ int loopDimension = getLoopDepth(Expr->getLoop());
+
+ isl_aff *LAff = isl_aff_set_coefficient_si(
+ isl_aff_zero_on_domain(LocalSpace), isl_dim_in, loopDimension, 1);
+ isl_pw_aff *LPwAff = isl_pw_aff_from_aff(LAff);
+
+ // TODO: Do we need to check for NSW and NUW?
+ return isl_pw_aff_add(Start, isl_pw_aff_mul(Step, LPwAff));
}
- __isl_give isl_pw_aff *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
- isl_pw_aff *Max = visit(Expr->getOperand(0));
+ // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
+ // if 'start' is not zero.
+ ScalarEvolution &SE = *S->getSE();
+ const SCEV *ZeroStartExpr = SE.getAddRecExpr(
+ SE.getConstant(Expr->getStart()->getType(), 0),
+ Expr->getStepRecurrence(SE), Expr->getLoop(), SCEV::FlagAnyWrap);
- for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
- isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
- Max = isl_pw_aff_max(Max, NextOperand);
- }
+ isl_pw_aff *ZeroStartResult = visit(ZeroStartExpr);
+ isl_pw_aff *Start = visit(Expr->getStart());
- return Max;
- }
+ return isl_pw_aff_add(ZeroStartResult, Start);
+}
- __isl_give isl_pw_aff *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
- llvm_unreachable("SCEVUMaxExpr not yet supported");
- }
+__isl_give isl_pw_aff *SCEVAffinator::visitSMaxExpr(const SCEVSMaxExpr *Expr) {
+ isl_pw_aff *Max = visit(Expr->getOperand(0));
- __isl_give isl_pw_aff *visitUnknown(const SCEVUnknown *Expr) {
- llvm_unreachable("Unknowns are always parameters");
+ for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
+ isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
+ Max = isl_pw_aff_max(Max, NextOperand);
}
-};
+
+ return Max;
+}
+
+__isl_give isl_pw_aff *SCEVAffinator::visitUMaxExpr(const SCEVUMaxExpr *Expr) {
+ llvm_unreachable("SCEVUMaxExpr not yet supported");
+}
+
+__isl_give isl_pw_aff *SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) {
+ llvm_unreachable("Unknowns are always parameters");
+}
+
+int SCEVAffinator::getLoopDepth(const Loop *L) {
+ Loop *outerLoop = S->getRegion().outermostLoopInRegion(const_cast<Loop *>(L));
+ assert(outerLoop && "Scop does not contain this loop");
+ return L->getLoopDepth() - outerLoop->getLoopDepth();
+}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud