1 //=- IslNodeBuilder.cpp - Translate an isl AST into a LLVM-IR AST -*- C++ -*-=// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the IslNodeBuilder, a class to translate an isl AST into 10 // a LLVM-IR AST. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef POLLY_ISLNODEBUILDER_H 15 #define POLLY_ISLNODEBUILDER_H 16 17 #include "polly/CodeGen/BlockGenerators.h" 18 #include "polly/CodeGen/IslExprBuilder.h" 19 #include "polly/ScopDetectionDiagnostic.h" 20 #include "llvm/ADT/ArrayRef.h" 21 #include "llvm/ADT/SmallSet.h" 22 #include "llvm/IR/InstrTypes.h" 23 #include "isl/ctx.h" 24 #include "isl/isl-noexceptions.h" 25 26 using namespace llvm; 27 using namespace polly; 28 29 namespace polly { 30 31 struct InvariantEquivClassTy; 32 } // namespace polly 33 34 struct SubtreeReferences { 35 LoopInfo &LI; 36 ScalarEvolution &SE; 37 Scop &S; 38 ValueMapT &GlobalMap; 39 SetVector<Value *> &Values; 40 SetVector<const SCEV *> &SCEVs; 41 BlockGenerator &BlockGen; 42 // In case an (optional) parameter space location is provided, parameter space 43 // information is collected as well. 44 isl::space *ParamSpace; 45 }; 46 47 /// Extract the out-of-scop values and SCEVs referenced from a ScopStmt. 48 /// 49 /// This includes the SCEVUnknowns referenced by the SCEVs used in the 50 /// statement and the base pointers of the memory accesses. For scalar 51 /// statements we force the generation of alloca memory locations and list 52 /// these locations in the set of out-of-scop values as well. 53 /// 54 /// We also collect an isl::space that includes all parameter dimensions 55 /// used in the statement's memory accesses, in case the ParamSpace pointer 56 /// is non-null. 57 /// 58 /// @param Stmt The statement for which to extract the information. 59 /// @param UserPtr A void pointer that can be casted to a 60 /// SubtreeReferences structure. 61 /// @param CreateScalarRefs Should the result include allocas of scalar 62 /// references? 63 void addReferencesFromStmt(const ScopStmt *Stmt, void *UserPtr, 64 bool CreateScalarRefs = true); 65 66 class IslNodeBuilder { 67 public: IslNodeBuilder(PollyIRBuilder & Builder,ScopAnnotator & Annotator,const DataLayout & DL,LoopInfo & LI,ScalarEvolution & SE,DominatorTree & DT,Scop & S,BasicBlock * StartBlock)68 IslNodeBuilder(PollyIRBuilder &Builder, ScopAnnotator &Annotator, 69 const DataLayout &DL, LoopInfo &LI, ScalarEvolution &SE, 70 DominatorTree &DT, Scop &S, BasicBlock *StartBlock) 71 : S(S), Builder(Builder), Annotator(Annotator), 72 ExprBuilder(S, Builder, IDToValue, ValueMap, DL, SE, DT, LI, 73 StartBlock), 74 BlockGen(Builder, LI, SE, DT, ScalarMap, EscapeMap, ValueMap, 75 &ExprBuilder, StartBlock), 76 RegionGen(BlockGen), DL(DL), LI(LI), SE(SE), DT(DT), 77 StartBlock(StartBlock) {} 78 79 virtual ~IslNodeBuilder() = default; 80 81 void addParameters(__isl_take isl_set *Context); 82 83 /// Create Values which hold the sizes of the outermost dimension of all 84 /// Fortran arrays in the current scop. 85 /// 86 /// @returns False, if a problem occurred and a Fortran array was not 87 /// materialized. True otherwise. 88 bool materializeFortranArrayOutermostDimension(); 89 90 /// Generate code that evaluates @p Condition at run-time. 91 /// 92 /// This function is typically called to generate the LLVM-IR for the 93 /// run-time condition of the scop, that verifies that all the optimistic 94 /// assumptions we have taken during scop modeling and transformation 95 /// hold at run-time. 96 /// 97 /// @param Condition The condition to evaluate 98 /// 99 /// @result An llvm::Value that is true if the condition holds and false 100 /// otherwise. 101 Value *createRTC(isl_ast_expr *Condition); 102 103 void create(__isl_take isl_ast_node *Node); 104 105 /// Allocate memory for all new arrays created by Polly. 106 void allocateNewArrays(BBPair StartExitBlocks); 107 108 /// Preload all memory loads that are invariant. 109 bool preloadInvariantLoads(); 110 111 /// Finalize code generation. 112 /// 113 /// @see BlockGenerator::finalizeSCoP(Scop &S) finalize()114 virtual void finalize() { BlockGen.finalizeSCoP(S); } 115 getExprBuilder()116 IslExprBuilder &getExprBuilder() { return ExprBuilder; } 117 118 /// Get the associated block generator. 119 /// 120 /// @return A reference to the associated block generator. getBlockGenerator()121 BlockGenerator &getBlockGenerator() { return BlockGen; } 122 123 /// Return the parallel subfunctions that have been created. getParallelSubfunctions()124 const ArrayRef<Function *> getParallelSubfunctions() const { 125 return ParallelSubfunctions; 126 } 127 128 protected: 129 Scop &S; 130 PollyIRBuilder &Builder; 131 ScopAnnotator &Annotator; 132 133 IslExprBuilder ExprBuilder; 134 135 /// Maps used by the block and region generator to demote scalars. 136 /// 137 ///@{ 138 139 /// See BlockGenerator::ScalarMap. 140 BlockGenerator::AllocaMapTy ScalarMap; 141 142 /// See BlockGenerator::EscapeMap. 143 BlockGenerator::EscapeUsersAllocaMapTy EscapeMap; 144 145 ///@} 146 147 /// The generator used to copy a basic block. 148 BlockGenerator BlockGen; 149 150 /// The generator used to copy a non-affine region. 151 RegionGenerator RegionGen; 152 153 const DataLayout &DL; 154 LoopInfo &LI; 155 ScalarEvolution &SE; 156 DominatorTree &DT; 157 BasicBlock *StartBlock; 158 159 /// The current iteration of out-of-scop loops 160 /// 161 /// This map provides for a given loop a llvm::Value that contains the current 162 /// loop iteration. 163 MapVector<const Loop *, const SCEV *> OutsideLoopIterations; 164 165 // This maps an isl_id* to the Value* it has in the generated program. For now 166 // on, the only isl_ids that are stored here are the newly calculated loop 167 // ivs. 168 IslExprBuilder::IDToValueTy IDToValue; 169 170 /// A collection of all parallel subfunctions that have been created. 171 SmallVector<Function *, 8> ParallelSubfunctions; 172 173 /// Generate code for a given SCEV* 174 /// 175 /// This function generates code for a given SCEV expression. It generated 176 /// code is emitted at the end of the basic block our Builder currently 177 /// points to and the resulting value is returned. 178 /// 179 /// @param Expr The expression to code generate. 180 Value *generateSCEV(const SCEV *Expr); 181 182 /// A set of Value -> Value remappings to apply when generating new code. 183 /// 184 /// When generating new code for a ScopStmt this map is used to map certain 185 /// llvm::Values to new llvm::Values. 186 ValueMapT ValueMap; 187 188 /// Materialize code for @p Id if it was not done before. 189 /// 190 /// @returns False, iff a problem occurred and the value was not materialized. 191 bool materializeValue(__isl_take isl_id *Id); 192 193 /// Materialize parameters of @p Set. 194 /// 195 /// @returns False, iff a problem occurred and the value was not materialized. 196 bool materializeParameters(__isl_take isl_set *Set); 197 198 /// Materialize all parameters in the current scop. 199 /// 200 /// @returns False, iff a problem occurred and the value was not materialized. 201 bool materializeParameters(); 202 203 // Extract the upper bound of this loop 204 // 205 // The isl code generation can generate arbitrary expressions to check if the 206 // upper bound of a loop is reached, but it provides an option to enforce 207 // 'atomic' upper bounds. An 'atomic upper bound is always of the form 208 // iv <= expr, where expr is an (arbitrary) expression not containing iv. 209 // 210 // This function extracts 'atomic' upper bounds. Polly, in general, requires 211 // atomic upper bounds for the following reasons: 212 // 213 // 1. An atomic upper bound is loop invariant 214 // 215 // It must not be calculated at each loop iteration and can often even be 216 // hoisted out further by the loop invariant code motion. 217 // 218 // 2. OpenMP needs a loop invariant upper bound to calculate the number 219 // of loop iterations. 220 // 221 // 3. With the existing code, upper bounds have been easier to implement. 222 isl::ast_expr getUpperBound(isl::ast_node For, CmpInst::Predicate &Predicate); 223 224 /// Return non-negative number of iterations in case of the following form 225 /// of a loop and -1 otherwise. 226 /// 227 /// for (i = 0; i <= NumIter; i++) { 228 /// loop body; 229 /// } 230 /// 231 /// NumIter is a non-negative integer value. Condition can have 232 /// isl_ast_op_lt type. 233 int getNumberOfIterations(isl::ast_node For); 234 235 /// Compute the values and loops referenced in this subtree. 236 /// 237 /// This function looks at all ScopStmts scheduled below the provided For node 238 /// and finds the llvm::Value[s] and llvm::Loops[s] which are referenced but 239 /// not locally defined. 240 /// 241 /// Values that can be synthesized or that are available as globals are 242 /// considered locally defined. 243 /// 244 /// Loops that contain the scop or that are part of the scop are considered 245 /// locally defined. Loops that are before the scop, but do not contain the 246 /// scop itself are considered not locally defined. 247 /// 248 /// @param For The node defining the subtree. 249 /// @param Values A vector that will be filled with the Values referenced in 250 /// this subtree. 251 /// @param Loops A vector that will be filled with the Loops referenced in 252 /// this subtree. 253 void getReferencesInSubtree(__isl_keep isl_ast_node *For, 254 SetVector<Value *> &Values, 255 SetVector<const Loop *> &Loops); 256 257 /// Change the llvm::Value(s) used for code generation. 258 /// 259 /// When generating code certain values (e.g., references to induction 260 /// variables or array base pointers) in the original code may be replaced by 261 /// new values. This function allows to (partially) update the set of values 262 /// used. A typical use case for this function is the case when we continue 263 /// code generation in a subfunction/kernel function and need to explicitly 264 /// pass down certain values. 265 /// 266 /// @param NewValues A map that maps certain llvm::Values to new llvm::Values. 267 void updateValues(ValueMapT &NewValues); 268 269 /// Return the most up-to-date version of the llvm::Value for code generation. 270 /// @param Original The Value to check for an up to date version. 271 /// @returns A remapped `Value` from ValueMap, or `Original` if no mapping 272 /// exists. 273 /// @see IslNodeBuilder::updateValues 274 /// @see IslNodeBuilder::ValueMap 275 Value *getLatestValue(Value *Original) const; 276 277 /// Generate code for a marker now. 278 /// 279 /// For mark nodes with an unknown name, we just forward the code generation 280 /// to its child. This is currently the only behavior implemented, as there is 281 /// currently not special handling for marker nodes implemented. 282 /// 283 /// @param Mark The node we generate code for. 284 virtual void createMark(__isl_take isl_ast_node *Marker); 285 286 virtual void createFor(__isl_take isl_ast_node *For); 287 288 /// Set to remember materialized invariant loads. 289 /// 290 /// An invariant load is identified by its pointer (the SCEV) and its type. 291 SmallSet<std::pair<const SCEV *, Type *>, 16> PreloadedPtrs; 292 293 /// Preload the memory access at @p AccessRange with @p Build. 294 /// 295 /// @returns The preloaded value casted to type @p Ty 296 Value *preloadUnconditionally(__isl_take isl_set *AccessRange, 297 isl_ast_build *Build, Instruction *AccInst); 298 299 /// Preload the memory load access @p MA. 300 /// 301 /// If @p MA is not always executed it will be conditionally loaded and 302 /// merged with undef from the same type. Hence, if @p MA is executed only 303 /// under condition C then the preload code will look like this: 304 /// 305 /// MA_preload = undef; 306 /// if (C) 307 /// MA_preload = load MA; 308 /// use MA_preload 309 Value *preloadInvariantLoad(const MemoryAccess &MA, 310 __isl_take isl_set *Domain); 311 312 /// Preload the invariant access equivalence class @p IAClass 313 /// 314 /// This function will preload the representing load from @p IAClass and 315 /// map all members of @p IAClass to that preloaded value, potentially casted 316 /// to the required type. 317 /// 318 /// @returns False, iff a problem occurred and the load was not preloaded. 319 bool preloadInvariantEquivClass(InvariantEquivClassTy &IAClass); 320 321 void createForVector(__isl_take isl_ast_node *For, int VectorWidth); 322 void createForSequential(isl::ast_node For, bool MarkParallel); 323 324 /// Create LLVM-IR that executes a for node thread parallel. 325 /// 326 /// @param For The FOR isl_ast_node for which code is generated. 327 void createForParallel(__isl_take isl_ast_node *For); 328 329 /// Create new access functions for modified memory accesses. 330 /// 331 /// In case the access function of one of the memory references in the Stmt 332 /// has been modified, we generate a new isl_ast_expr that reflects the 333 /// newly modified access function and return a map that maps from the 334 /// individual memory references in the statement (identified by their id) 335 /// to these newly generated ast expressions. 336 /// 337 /// @param Stmt The statement for which to (possibly) generate new access 338 /// functions. 339 /// @param Node The ast node corresponding to the statement for us to extract 340 /// the local schedule from. 341 /// @return A new hash table that contains remappings from memory ids to new 342 /// access expressions. 343 __isl_give isl_id_to_ast_expr * 344 createNewAccesses(ScopStmt *Stmt, __isl_keep isl_ast_node *Node); 345 346 /// Generate LLVM-IR that computes the values of the original induction 347 /// variables in function of the newly generated loop induction variables. 348 /// 349 /// Example: 350 /// 351 /// // Original 352 /// for i 353 /// for j 354 /// S(i) 355 /// 356 /// Schedule: [i,j] -> [i+j, j] 357 /// 358 /// // New 359 /// for c0 360 /// for c1 361 /// S(c0 - c1, c1) 362 /// 363 /// Assuming the original code consists of two loops which are 364 /// transformed according to a schedule [i,j] -> [c0=i+j,c1=j]. The resulting 365 /// ast models the original statement as a call expression where each argument 366 /// is an expression that computes the old induction variables from the new 367 /// ones, ordered such that the first argument computes the value of induction 368 /// variable that was outermost in the original code. 369 /// 370 /// @param Expr The call expression that represents the statement. 371 /// @param Stmt The statement that is called. 372 /// @param LTS The loop to SCEV map in which the mapping from the original 373 /// loop to a SCEV representing the new loop iv is added. This 374 /// mapping does not require an explicit induction variable. 375 /// Instead, we think in terms of an implicit induction variable 376 /// that counts the number of times a loop is executed. For each 377 /// original loop this count, expressed in function of the new 378 /// induction variables, is added to the LTS map. 379 void createSubstitutions(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt, 380 LoopToScevMapT <S); 381 void createSubstitutionsVector(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt, 382 std::vector<LoopToScevMapT> &VLTS, 383 std::vector<Value *> &IVS, 384 __isl_take isl_id *IteratorID); 385 virtual void createIf(__isl_take isl_ast_node *If); 386 void createUserVector(__isl_take isl_ast_node *User, 387 std::vector<Value *> &IVS, 388 __isl_take isl_id *IteratorID, 389 __isl_take isl_union_map *Schedule); 390 virtual void createUser(__isl_take isl_ast_node *User); 391 virtual void createBlock(__isl_take isl_ast_node *Block); 392 393 /// Get the schedule for a given AST node. 394 /// 395 /// This information is used to reason about parallelism of loops or the 396 /// locality of memory accesses under a given schedule. 397 /// 398 /// @param Node The node we want to obtain the schedule for. 399 /// @return Return an isl_union_map that maps from the statements executed 400 /// below this ast node to the scheduling vectors used to enumerate 401 /// them. 402 /// 403 virtual __isl_give isl_union_map * 404 getScheduleForAstNode(__isl_take isl_ast_node *Node); 405 406 private: 407 /// Create code for a copy statement. 408 /// 409 /// A copy statement is expected to have one read memory access and one write 410 /// memory access (in this very order). Data is loaded from the location 411 /// described by the read memory access and written to the location described 412 /// by the write memory access. @p NewAccesses contains for each access 413 /// the isl ast expression that describes the location accessed. 414 /// 415 /// @param Stmt The copy statement that contains the accesses. 416 /// @param NewAccesses The hash table that contains remappings from memory 417 /// ids to new access expressions. 418 void generateCopyStmt(ScopStmt *Stmt, 419 __isl_keep isl_id_to_ast_expr *NewAccesses); 420 421 /// Materialize a canonical loop induction variable for `L`, which is a loop 422 /// that is *not* present in the Scop. 423 /// 424 /// Note that this is materialized at the point where the `Builder` is 425 /// currently pointing. 426 /// We also populate the `OutsideLoopIterations` map with `L`s SCEV to keep 427 /// track of the induction variable. 428 /// See [Code generation of induction variables of loops outside Scops] 429 Value *materializeNonScopLoopInductionVariable(const Loop *L); 430 }; 431 432 #endif // POLLY_ISLNODEBUILDER_H 433