Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
lib/Analysis/ScopInfo.cpp
Show First 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
// Multiplicative reductions can be disabled seperately as these kind of | // Multiplicative reductions can be disabled seperately as these kind of | ||||
// operations can overflow easily. Additive reductions and bit operations | // operations can overflow easily. Additive reductions and bit operations | ||||
// are in contrast pretty stable. | // are in contrast pretty stable. | ||||
static cl::opt<bool> DisableMultiplicativeReductions( | static cl::opt<bool> DisableMultiplicativeReductions( | ||||
"polly-disable-multiplicative-reductions", | "polly-disable-multiplicative-reductions", | ||||
cl::desc("Disable multiplicative reductions"), cl::Hidden, cl::ZeroOrMore, | cl::desc("Disable multiplicative reductions"), cl::Hidden, cl::ZeroOrMore, | ||||
cl::init(false), cl::cat(PollyCategory)); | cl::init(false), cl::cat(PollyCategory)); | ||||
static int extractAffine(__isl_take isl_set *Set, __isl_take isl_aff *Aff, | |||||
void *User) { | |||||
*((isl_aff **)(User)) = Aff; | |||||
isl_set_free(Set); | |||||
return 0; | |||||
} | |||||
/// Translate a 'const SCEV *' expression in an isl_pw_aff. | /// Translate a 'const SCEV *' expression in an isl_pw_aff. | ||||
struct SCEVAffinator : public SCEVVisitor<SCEVAffinator, isl_pw_aff *> { | struct SCEVAffinator : public SCEVVisitor<SCEVAffinator, isl_pw_aff *> { | ||||
public: | public: | ||||
/// @brief Translate a 'const SCEV *' to an isl_pw_aff. | /// @brief Translate a 'const SCEV *' to an isl_pw_aff. | ||||
/// | /// | ||||
/// @param Stmt The location at which the scalar evolution expression | /// @param Stmt The location at which the scalar evolution expression | ||||
/// is evaluated. | /// is evaluated. | ||||
/// @param Expr The expression that is translated. | /// @param Expr The expression that is translated. | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
__isl_give isl_pw_aff * | __isl_give isl_pw_aff * | ||||
SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) { | SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) { | ||||
llvm_unreachable("SCEVTruncateExpr not yet supported"); | llvm_unreachable("SCEVTruncateExpr not yet supported"); | ||||
} | } | ||||
__isl_give isl_pw_aff * | __isl_give isl_pw_aff * | ||||
SCEVAffinator::visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) { | SCEVAffinator::visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) { | ||||
// Explicitly check for expressions of the following form: | |||||
// i % 2^C | |||||
// which could either be a srem (%) expressions or an and (&) expressions. | |||||
// The srem (%) versions are caught by visitUnknown, the and (&) versions | |||||
// are expressed as | |||||
simbuerg: capture | |||||
// zext iC {0,+,1}<%for_i> | |||||
// by scalar evolution. | |||||
const SCEV *OpS = Expr->getOperand(); | |||||
if (auto *OpAR = dyn_cast<SCEVAddRecExpr>(OpS)) { | |||||
if (OpAR->getStart()->isZero() && | |||||
OpAR->getStepRecurrence(*S->getSE())->isOne()) { | |||||
unsigned ModCst = 1 << OpAR->getType()->getScalarSizeInBits(); | |||||
return isl_pw_aff_mod_val(visitAddRecExpr(OpAR), | |||||
isl_val_int_from_si(Ctx, ModCst)); | |||||
Not Done ReplyInline ActionsHere 'auto' is ok, because I can infer the type from the context on the same line (imho). simbuerg: Here 'auto' is ok, because I can infer the type from the context on the same line (imho). | |||||
} | |||||
} | |||||
Not Done ReplyInline ActionsI would use the type here instead of 'auto'. simbuerg: I would use the type here instead of 'auto'. | |||||
llvm_unreachable("SCEVZeroExtendExpr not yet supported"); | llvm_unreachable("SCEVZeroExtendExpr not yet supported"); | ||||
Not Done ReplyInline ActionsI would use the type here instead of 'auto'. simbuerg: I would use the type here instead of 'auto'. | |||||
} | } | ||||
__isl_give isl_pw_aff * | __isl_give isl_pw_aff * | ||||
SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) { | SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) { | ||||
// Assuming the value is signed, a sign extension is basically a noop. | // Assuming the value is signed, a sign extension is basically a noop. | ||||
// TODO: Reconsider this as soon as we support unsigned values. | // TODO: Reconsider this as soon as we support unsigned values. | ||||
return visit(Expr->getOperand()); | return visit(Expr->getOperand()); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | __isl_give isl_pw_aff *SCEVAffinator::visitSMaxExpr(const SCEVSMaxExpr *Expr) { | ||||
return Max; | return Max; | ||||
} | } | ||||
__isl_give isl_pw_aff *SCEVAffinator::visitUMaxExpr(const SCEVUMaxExpr *Expr) { | __isl_give isl_pw_aff *SCEVAffinator::visitUMaxExpr(const SCEVUMaxExpr *Expr) { | ||||
llvm_unreachable("SCEVUMaxExpr not yet supported"); | llvm_unreachable("SCEVUMaxExpr not yet supported"); | ||||
} | } | ||||
__isl_give isl_pw_aff *SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) { | __isl_give isl_pw_aff *SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) { | ||||
llvm_unreachable("Unknowns are always parameters"); | Value *Unknown = Expr->getValue(); | ||||
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Unknown)) { | |||||
Not Done ReplyInline ActionsNow you're not using 'auto', why? simbuerg: Now you're not using 'auto', why? | |||||
isl_pw_aff *RHS, *LHS; | |||||
isl_aff *RHSAff; | |||||
isl_val *RHSVal; | |||||
assert(BO->getOpcode() == Instruction::SRem && | |||||
"Binary operator unknowns are always signed modulo expressions"); | |||||
LHS = visit(S->getSE()->getSCEV(BO->getOperand(0))); | |||||
RHS = visit(S->getSE()->getSCEV(BO->getOperand(1))); | |||||
assert(isl_pw_aff_is_cst(RHS) && | |||||
"Modulo expressions are only valid for a constant right hand side"); | |||||
assert(isl_pw_aff_n_piece(RHS) == 1 && | |||||
"Modulo expressions are only valid for a non split right hand side"); | |||||
isl_pw_aff_foreach_piece(RHS, extractAffine, &RHSAff); | |||||
assert(isl_aff_is_cst(RHSAff) && | |||||
"Modulo expressions are only valid for a constant right hand side"); | |||||
RHSVal = isl_aff_get_constant_val(RHSAff); | |||||
isl_pw_aff_free(RHS); | |||||
isl_aff_free(RHSAff); | |||||
return isl_pw_aff_mod_val(LHS, RHSVal); | |||||
} | |||||
llvm_unreachable("Unknowns are always parameters or modulo expressions"); | |||||
} | } | ||||
int SCEVAffinator::getLoopDepth(const Loop *L) { | int SCEVAffinator::getLoopDepth(const Loop *L) { | ||||
Loop *outerLoop = S->getRegion().outermostLoopInRegion(const_cast<Loop *>(L)); | Loop *outerLoop = S->getRegion().outermostLoopInRegion(const_cast<Loop *>(L)); | ||||
assert(outerLoop && "Scop does not contain this loop"); | assert(outerLoop && "Scop does not contain this loop"); | ||||
return L->getLoopDepth() - outerLoop->getLoopDepth(); | return L->getLoopDepth() - outerLoop->getLoopDepth(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,176 Lines • Show Last 20 Lines |
capture