1 //===--------- SCEVAffinator.cpp - Create Scops from LLVM IR -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Create a polyhedral description for a SCEV value. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "polly/Support/SCEVAffinator.h" 15 #include "polly/ScopInfo.h" 16 #include "polly/Support/GICHelper.h" 17 #include "polly/Support/SCEVValidator.h" 18 #include "polly/Support/ScopHelper.h" 19 #include "isl/aff.h" 20 #include "isl/local_space.h" 21 #include "isl/set.h" 22 #include "isl/val.h" 23 24 using namespace llvm; 25 using namespace polly; 26 27 // The maximal number of basic sets we allow during the construction of a 28 // piecewise affine function. More complex ones will result in very high 29 // compile time. 30 static int const MaxConjunctsInPwAff = 100; 31 32 /// @brief Add the number of basic sets in @p Domain to @p User 33 static isl_stat addNumBasicSets(isl_set *Domain, isl_aff *Aff, void *User) { 34 auto *NumBasicSets = static_cast<unsigned *>(User); 35 *NumBasicSets += isl_set_n_basic_set(Domain); 36 isl_set_free(Domain); 37 isl_aff_free(Aff); 38 return isl_stat_ok; 39 } 40 41 /// @brief Determine if @p PWA is to complex to continue 42 /// 43 /// Note that @p PWA will be "free" (deallocated) if this function returns true, 44 /// but not if this function returns false. 45 static bool isToComplex(isl_pw_aff *PWA) { 46 unsigned NumBasicSets = 0; 47 isl_pw_aff_foreach_piece(PWA, addNumBasicSets, &NumBasicSets); 48 if (NumBasicSets <= MaxConjunctsInPwAff) 49 return false; 50 isl_pw_aff_free(PWA); 51 return true; 52 } 53 54 SCEVAffinator::SCEVAffinator(Scop *S, LoopInfo &LI) 55 : S(S), Ctx(S->getIslCtx()), R(S->getRegion()), SE(*S->getSE()), LI(LI), 56 TD(R.getEntry()->getParent()->getParent()->getDataLayout()) {} 57 58 SCEVAffinator::~SCEVAffinator() { 59 for (const auto &CachedPair : CachedExpressions) 60 isl_pw_aff_free(CachedPair.second); 61 } 62 63 __isl_give isl_pw_aff *SCEVAffinator::getPwAff(const SCEV *Expr, 64 BasicBlock *BB) { 65 this->BB = BB; 66 67 if (BB) { 68 auto *DC = S->getDomainConditions(BB); 69 NumIterators = isl_set_n_dim(DC); 70 isl_set_free(DC); 71 } else 72 NumIterators = 0; 73 74 auto *Scope = LI.getLoopFor(BB); 75 S->addParams(getParamsInAffineExpr(&R, Scope, Expr, SE)); 76 77 return visit(Expr); 78 } 79 80 __isl_give isl_set * 81 SCEVAffinator::getWrappingContext(SCEV::NoWrapFlags Flags, Type *ExprType, 82 __isl_keep isl_pw_aff *PWA, 83 __isl_take isl_set *ExprDomain) const { 84 // If the SCEV flags do contain NSW (no signed wrap) then PWA already 85 // represents Expr in modulo semantic (it is not allowed to overflow), thus we 86 // are done. Otherwise, we will compute: 87 // PWA = ((PWA + 2^(n-1)) mod (2 ^ n)) - 2^(n-1) 88 // whereas n is the number of bits of the Expr, hence: 89 // n = bitwidth(ExprType) 90 91 if (Flags & SCEV::FlagNSW) 92 return nullptr; 93 94 isl_pw_aff *PWAMod = addModuloSemantic(isl_pw_aff_copy(PWA), ExprType); 95 if (isl_pw_aff_is_equal(PWA, PWAMod)) { 96 isl_pw_aff_free(PWAMod); 97 return nullptr; 98 } 99 100 PWA = isl_pw_aff_copy(PWA); 101 102 auto *NotEqualSet = isl_pw_aff_ne_set(PWA, PWAMod); 103 NotEqualSet = isl_set_intersect(NotEqualSet, isl_set_copy(ExprDomain)); 104 NotEqualSet = isl_set_gist_params(NotEqualSet, S->getContext()); 105 NotEqualSet = isl_set_params(NotEqualSet); 106 return NotEqualSet; 107 } 108 109 __isl_give isl_set *SCEVAffinator::getWrappingContext() const { 110 111 isl_set *WrappingCtx = isl_set_empty(S->getParamSpace()); 112 113 for (const auto &CachedPair : CachedExpressions) { 114 const SCEV *Expr = CachedPair.first.first; 115 SCEV::NoWrapFlags Flags; 116 117 switch (Expr->getSCEVType()) { 118 case scAddExpr: 119 Flags = cast<SCEVAddExpr>(Expr)->getNoWrapFlags(); 120 break; 121 case scMulExpr: 122 Flags = cast<SCEVMulExpr>(Expr)->getNoWrapFlags(); 123 break; 124 case scAddRecExpr: 125 Flags = cast<SCEVAddRecExpr>(Expr)->getNoWrapFlags(); 126 break; 127 default: 128 continue; 129 } 130 131 isl_pw_aff *PWA = CachedPair.second; 132 BasicBlock *BB = CachedPair.first.second; 133 isl_set *ExprDomain = BB ? S->getDomainConditions(BB) : nullptr; 134 135 isl_set *WPWACtx = 136 getWrappingContext(Flags, Expr->getType(), PWA, ExprDomain); 137 isl_set_free(ExprDomain); 138 139 WrappingCtx = WPWACtx ? isl_set_union(WrappingCtx, WPWACtx) : WrappingCtx; 140 } 141 142 return WrappingCtx; 143 } 144 145 __isl_give isl_pw_aff * 146 SCEVAffinator::addModuloSemantic(__isl_take isl_pw_aff *PWA, 147 Type *ExprType) const { 148 unsigned Width = TD.getTypeStoreSizeInBits(ExprType); 149 isl_ctx *Ctx = isl_pw_aff_get_ctx(PWA); 150 151 isl_val *ModVal = isl_val_int_from_ui(Ctx, Width); 152 ModVal = isl_val_2exp(ModVal); 153 154 isl_val *AddVal = isl_val_int_from_ui(Ctx, Width - 1); 155 AddVal = isl_val_2exp(AddVal); 156 157 isl_set *Domain = isl_pw_aff_domain(isl_pw_aff_copy(PWA)); 158 159 isl_pw_aff *AddPW = isl_pw_aff_val_on_domain(Domain, AddVal); 160 161 PWA = isl_pw_aff_add(PWA, isl_pw_aff_copy(AddPW)); 162 PWA = isl_pw_aff_mod_val(PWA, ModVal); 163 PWA = isl_pw_aff_sub(PWA, AddPW); 164 165 return PWA; 166 } 167 168 bool SCEVAffinator::hasNSWAddRecForLoop(Loop *L) const { 169 for (const auto &CachedPair : CachedExpressions) { 170 auto *AddRec = dyn_cast<SCEVAddRecExpr>(CachedPair.first.first); 171 if (!AddRec) 172 continue; 173 if (AddRec->getLoop() != L) 174 continue; 175 if (AddRec->getNoWrapFlags() & SCEV::FlagNSW) 176 return true; 177 } 178 179 return false; 180 } 181 182 __isl_give isl_pw_aff *SCEVAffinator::visit(const SCEV *Expr) { 183 184 auto Key = std::make_pair(Expr, BB); 185 isl_pw_aff *PWA = CachedExpressions[Key]; 186 if (PWA) 187 return isl_pw_aff_copy(PWA); 188 189 auto ConstantAndLeftOverPair = extractConstantFactor(Expr, *S->getSE()); 190 auto *Factor = ConstantAndLeftOverPair.first; 191 Expr = ConstantAndLeftOverPair.second; 192 193 // In case the scev is a valid parameter, we do not further analyze this 194 // expression, but create a new parameter in the isl_pw_aff. This allows us 195 // to treat subexpressions that we cannot translate into an piecewise affine 196 // expression, as constant parameters of the piecewise affine expression. 197 if (isl_id *Id = S->getIdForParam(Expr)) { 198 isl_space *Space = isl_space_set_alloc(Ctx, 1, NumIterators); 199 Space = isl_space_set_dim_id(Space, isl_dim_param, 0, Id); 200 201 isl_set *Domain = isl_set_universe(isl_space_copy(Space)); 202 isl_aff *Affine = isl_aff_zero_on_domain(isl_local_space_from_space(Space)); 203 Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1); 204 205 PWA = isl_pw_aff_alloc(Domain, Affine); 206 } else { 207 PWA = SCEVVisitor<SCEVAffinator, isl_pw_aff *>::visit(Expr); 208 } 209 210 PWA = isl_pw_aff_mul(visitConstant(Factor), PWA); 211 212 // For compile time reasons we need to simplify the PWA before we cache and 213 // return it. 214 PWA = isl_pw_aff_coalesce(PWA); 215 CachedExpressions[Key] = isl_pw_aff_copy(PWA); 216 return PWA; 217 } 218 219 __isl_give isl_pw_aff *SCEVAffinator::visitConstant(const SCEVConstant *Expr) { 220 ConstantInt *Value = Expr->getValue(); 221 isl_val *v; 222 223 // LLVM does not define if an integer value is interpreted as a signed or 224 // unsigned value. Hence, without further information, it is unknown how 225 // this value needs to be converted to GMP. At the moment, we only support 226 // signed operations. So we just interpret it as signed. Later, there are 227 // two options: 228 // 229 // 1. We always interpret any value as signed and convert the values on 230 // demand. 231 // 2. We pass down the signedness of the calculation and use it to interpret 232 // this constant correctly. 233 v = isl_valFromAPInt(Ctx, Value->getValue(), /* isSigned */ true); 234 235 isl_space *Space = isl_space_set_alloc(Ctx, 0, NumIterators); 236 isl_local_space *ls = isl_local_space_from_space(Space); 237 return isl_pw_aff_from_aff(isl_aff_val_on_domain(ls, v)); 238 } 239 240 __isl_give isl_pw_aff * 241 SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) { 242 llvm_unreachable("SCEVTruncateExpr not yet supported"); 243 } 244 245 __isl_give isl_pw_aff * 246 SCEVAffinator::visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) { 247 llvm_unreachable("SCEVZeroExtendExpr not yet supported"); 248 } 249 250 __isl_give isl_pw_aff * 251 SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) { 252 // Assuming the value is signed, a sign extension is basically a noop. 253 // TODO: Reconsider this as soon as we support unsigned values. 254 return visit(Expr->getOperand()); 255 } 256 257 __isl_give isl_pw_aff *SCEVAffinator::visitAddExpr(const SCEVAddExpr *Expr) { 258 isl_pw_aff *Sum = visit(Expr->getOperand(0)); 259 260 for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) { 261 isl_pw_aff *NextSummand = visit(Expr->getOperand(i)); 262 Sum = isl_pw_aff_add(Sum, NextSummand); 263 if (isToComplex(Sum)) 264 return nullptr; 265 } 266 267 return Sum; 268 } 269 270 __isl_give isl_pw_aff *SCEVAffinator::visitMulExpr(const SCEVMulExpr *Expr) { 271 llvm_unreachable("SCEVMulExpr should not be reached"); 272 } 273 274 __isl_give isl_pw_aff *SCEVAffinator::visitUDivExpr(const SCEVUDivExpr *Expr) { 275 llvm_unreachable("SCEVUDivExpr not yet supported"); 276 } 277 278 __isl_give isl_pw_aff * 279 SCEVAffinator::visitAddRecExpr(const SCEVAddRecExpr *Expr) { 280 assert(Expr->isAffine() && "Only affine AddRecurrences allowed"); 281 282 auto Flags = Expr->getNoWrapFlags(); 283 284 // Directly generate isl_pw_aff for Expr if 'start' is zero. 285 if (Expr->getStart()->isZero()) { 286 assert(S->getRegion().contains(Expr->getLoop()) && 287 "Scop does not contain the loop referenced in this AddRec"); 288 289 isl_pw_aff *Step = visit(Expr->getOperand(1)); 290 isl_space *Space = isl_space_set_alloc(Ctx, 0, NumIterators); 291 isl_local_space *LocalSpace = isl_local_space_from_space(Space); 292 293 unsigned loopDimension = S->getRelativeLoopDepth(Expr->getLoop()); 294 295 isl_aff *LAff = isl_aff_set_coefficient_si( 296 isl_aff_zero_on_domain(LocalSpace), isl_dim_in, loopDimension, 1); 297 isl_pw_aff *LPwAff = isl_pw_aff_from_aff(LAff); 298 299 return isl_pw_aff_mul(Step, LPwAff); 300 } 301 302 // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}' 303 // if 'start' is not zero. 304 // TODO: Using the original SCEV no-wrap flags is not always safe, however 305 // as our code generation is reordering the expression anyway it doesn't 306 // really matter. 307 ScalarEvolution &SE = *S->getSE(); 308 const SCEV *ZeroStartExpr = 309 SE.getAddRecExpr(SE.getConstant(Expr->getStart()->getType(), 0), 310 Expr->getStepRecurrence(SE), Expr->getLoop(), Flags); 311 312 isl_pw_aff *ZeroStartResult = visit(ZeroStartExpr); 313 isl_pw_aff *Start = visit(Expr->getStart()); 314 315 return isl_pw_aff_add(ZeroStartResult, Start); 316 } 317 318 __isl_give isl_pw_aff *SCEVAffinator::visitSMaxExpr(const SCEVSMaxExpr *Expr) { 319 isl_pw_aff *Max = visit(Expr->getOperand(0)); 320 321 for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) { 322 isl_pw_aff *NextOperand = visit(Expr->getOperand(i)); 323 Max = isl_pw_aff_max(Max, NextOperand); 324 if (isToComplex(Max)) 325 return nullptr; 326 } 327 328 return Max; 329 } 330 331 __isl_give isl_pw_aff *SCEVAffinator::visitUMaxExpr(const SCEVUMaxExpr *Expr) { 332 llvm_unreachable("SCEVUMaxExpr not yet supported"); 333 } 334 335 __isl_give isl_pw_aff *SCEVAffinator::visitSDivInstruction(Instruction *SDiv) { 336 assert(SDiv->getOpcode() == Instruction::SDiv && "Assumed SDiv instruction!"); 337 auto *SE = S->getSE(); 338 339 auto *Divisor = SDiv->getOperand(1); 340 auto *DivisorSCEV = SE->getSCEV(Divisor); 341 auto *DivisorPWA = visit(DivisorSCEV); 342 assert(isa<ConstantInt>(Divisor) && 343 "SDiv is no parameter but has a non-constant RHS."); 344 345 auto *Dividend = SDiv->getOperand(0); 346 auto *DividendSCEV = SE->getSCEV(Dividend); 347 auto *DividendPWA = visit(DividendSCEV); 348 return isl_pw_aff_tdiv_q(DividendPWA, DivisorPWA); 349 } 350 351 __isl_give isl_pw_aff *SCEVAffinator::visitSRemInstruction(Instruction *SRem) { 352 assert(SRem->getOpcode() == Instruction::SRem && "Assumed SRem instruction!"); 353 auto *SE = S->getSE(); 354 355 auto *Divisor = dyn_cast<ConstantInt>(SRem->getOperand(1)); 356 assert(Divisor && "SRem is no parameter but has a non-constant RHS."); 357 auto *DivisorVal = isl_valFromAPInt(Ctx, Divisor->getValue(), 358 /* isSigned */ true); 359 360 auto *Dividend = SRem->getOperand(0); 361 auto *DividendSCEV = SE->getSCEV(Dividend); 362 auto *DividendPWA = visit(DividendSCEV); 363 364 return isl_pw_aff_mod_val(DividendPWA, isl_val_abs(DivisorVal)); 365 } 366 367 __isl_give isl_pw_aff *SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) { 368 if (Instruction *I = dyn_cast<Instruction>(Expr->getValue())) { 369 switch (I->getOpcode()) { 370 case Instruction::SDiv: 371 return visitSDivInstruction(I); 372 case Instruction::SRem: 373 return visitSRemInstruction(I); 374 default: 375 break; // Fall through. 376 } 377 } 378 379 llvm_unreachable( 380 "Unknowns SCEV was neither parameter nor a valid instruction."); 381 } 382