1 1.1 joerg //===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===// 2 1.1 joerg // 3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 joerg // 7 1.1 joerg //===----------------------------------------------------------------------===// 8 1.1 joerg 9 1.1 joerg #include "CGLoopInfo.h" 10 1.1 joerg #include "clang/AST/ASTContext.h" 11 1.1 joerg #include "clang/AST/Attr.h" 12 1.1.1.2 joerg #include "clang/AST/Expr.h" 13 1.1.1.2 joerg #include "clang/Basic/CodeGenOptions.h" 14 1.1 joerg #include "llvm/IR/BasicBlock.h" 15 1.1 joerg #include "llvm/IR/CFG.h" 16 1.1 joerg #include "llvm/IR/Constants.h" 17 1.1 joerg #include "llvm/IR/InstrTypes.h" 18 1.1 joerg #include "llvm/IR/Instructions.h" 19 1.1 joerg #include "llvm/IR/Metadata.h" 20 1.1 joerg using namespace clang::CodeGen; 21 1.1 joerg using namespace llvm; 22 1.1 joerg 23 1.1 joerg MDNode * 24 1.1 joerg LoopInfo::createLoopPropertiesMetadata(ArrayRef<Metadata *> LoopProperties) { 25 1.1 joerg LLVMContext &Ctx = Header->getContext(); 26 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties; 27 1.1.1.2 joerg NewLoopProperties.push_back(nullptr); 28 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end()); 29 1.1 joerg 30 1.1 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, NewLoopProperties); 31 1.1 joerg LoopID->replaceOperandWith(0, LoopID); 32 1.1 joerg return LoopID; 33 1.1 joerg } 34 1.1 joerg 35 1.1 joerg MDNode *LoopInfo::createPipeliningMetadata(const LoopAttributes &Attrs, 36 1.1 joerg ArrayRef<Metadata *> LoopProperties, 37 1.1 joerg bool &HasUserTransforms) { 38 1.1 joerg LLVMContext &Ctx = Header->getContext(); 39 1.1 joerg 40 1.1 joerg Optional<bool> Enabled; 41 1.1 joerg if (Attrs.PipelineDisabled) 42 1.1 joerg Enabled = false; 43 1.1 joerg else if (Attrs.PipelineInitiationInterval != 0) 44 1.1 joerg Enabled = true; 45 1.1 joerg 46 1.1 joerg if (Enabled != true) { 47 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties; 48 1.1 joerg if (Enabled == false) { 49 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end()); 50 1.1 joerg NewLoopProperties.push_back( 51 1.1 joerg MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.pipeline.disable"), 52 1.1 joerg ConstantAsMetadata::get(ConstantInt::get( 53 1.1 joerg llvm::Type::getInt1Ty(Ctx), 1))})); 54 1.1 joerg LoopProperties = NewLoopProperties; 55 1.1 joerg } 56 1.1 joerg return createLoopPropertiesMetadata(LoopProperties); 57 1.1 joerg } 58 1.1 joerg 59 1.1 joerg SmallVector<Metadata *, 4> Args; 60 1.1.1.2 joerg Args.push_back(nullptr); 61 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end()); 62 1.1 joerg 63 1.1 joerg if (Attrs.PipelineInitiationInterval > 0) { 64 1.1 joerg Metadata *Vals[] = { 65 1.1 joerg MDString::get(Ctx, "llvm.loop.pipeline.initiationinterval"), 66 1.1 joerg ConstantAsMetadata::get(ConstantInt::get( 67 1.1 joerg llvm::Type::getInt32Ty(Ctx), Attrs.PipelineInitiationInterval))}; 68 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals)); 69 1.1 joerg } 70 1.1 joerg 71 1.1 joerg // No follow-up: This is the last transformation. 72 1.1 joerg 73 1.1 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args); 74 1.1 joerg LoopID->replaceOperandWith(0, LoopID); 75 1.1 joerg HasUserTransforms = true; 76 1.1 joerg return LoopID; 77 1.1 joerg } 78 1.1 joerg 79 1.1 joerg MDNode * 80 1.1 joerg LoopInfo::createPartialUnrollMetadata(const LoopAttributes &Attrs, 81 1.1 joerg ArrayRef<Metadata *> LoopProperties, 82 1.1 joerg bool &HasUserTransforms) { 83 1.1 joerg LLVMContext &Ctx = Header->getContext(); 84 1.1 joerg 85 1.1 joerg Optional<bool> Enabled; 86 1.1 joerg if (Attrs.UnrollEnable == LoopAttributes::Disable) 87 1.1 joerg Enabled = false; 88 1.1 joerg else if (Attrs.UnrollEnable == LoopAttributes::Full) 89 1.1 joerg Enabled = None; 90 1.1 joerg else if (Attrs.UnrollEnable != LoopAttributes::Unspecified || 91 1.1 joerg Attrs.UnrollCount != 0) 92 1.1 joerg Enabled = true; 93 1.1 joerg 94 1.1 joerg if (Enabled != true) { 95 1.1 joerg // createFullUnrollMetadata will already have added llvm.loop.unroll.disable 96 1.1 joerg // if unrolling is disabled. 97 1.1 joerg return createPipeliningMetadata(Attrs, LoopProperties, HasUserTransforms); 98 1.1 joerg } 99 1.1 joerg 100 1.1 joerg SmallVector<Metadata *, 4> FollowupLoopProperties; 101 1.1 joerg 102 1.1 joerg // Apply all loop properties to the unrolled loop. 103 1.1 joerg FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end()); 104 1.1 joerg 105 1.1 joerg // Don't unroll an already unrolled loop. 106 1.1 joerg FollowupLoopProperties.push_back( 107 1.1 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.disable"))); 108 1.1 joerg 109 1.1 joerg bool FollowupHasTransforms = false; 110 1.1 joerg MDNode *Followup = createPipeliningMetadata(Attrs, FollowupLoopProperties, 111 1.1 joerg FollowupHasTransforms); 112 1.1 joerg 113 1.1 joerg SmallVector<Metadata *, 4> Args; 114 1.1.1.2 joerg Args.push_back(nullptr); 115 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end()); 116 1.1 joerg 117 1.1 joerg // Setting unroll.count 118 1.1 joerg if (Attrs.UnrollCount > 0) { 119 1.1 joerg Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.count"), 120 1.1 joerg ConstantAsMetadata::get(ConstantInt::get( 121 1.1 joerg llvm::Type::getInt32Ty(Ctx), Attrs.UnrollCount))}; 122 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals)); 123 1.1 joerg } 124 1.1 joerg 125 1.1 joerg // Setting unroll.full or unroll.disable 126 1.1 joerg if (Attrs.UnrollEnable == LoopAttributes::Enable) { 127 1.1 joerg Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.enable")}; 128 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals)); 129 1.1 joerg } 130 1.1 joerg 131 1.1 joerg if (FollowupHasTransforms) 132 1.1 joerg Args.push_back(MDNode::get( 133 1.1 joerg Ctx, {MDString::get(Ctx, "llvm.loop.unroll.followup_all"), Followup})); 134 1.1 joerg 135 1.1 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args); 136 1.1 joerg LoopID->replaceOperandWith(0, LoopID); 137 1.1 joerg HasUserTransforms = true; 138 1.1 joerg return LoopID; 139 1.1 joerg } 140 1.1 joerg 141 1.1 joerg MDNode * 142 1.1 joerg LoopInfo::createUnrollAndJamMetadata(const LoopAttributes &Attrs, 143 1.1 joerg ArrayRef<Metadata *> LoopProperties, 144 1.1 joerg bool &HasUserTransforms) { 145 1.1 joerg LLVMContext &Ctx = Header->getContext(); 146 1.1 joerg 147 1.1 joerg Optional<bool> Enabled; 148 1.1 joerg if (Attrs.UnrollAndJamEnable == LoopAttributes::Disable) 149 1.1 joerg Enabled = false; 150 1.1 joerg else if (Attrs.UnrollAndJamEnable == LoopAttributes::Enable || 151 1.1 joerg Attrs.UnrollAndJamCount != 0) 152 1.1 joerg Enabled = true; 153 1.1 joerg 154 1.1 joerg if (Enabled != true) { 155 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties; 156 1.1 joerg if (Enabled == false) { 157 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end()); 158 1.1 joerg NewLoopProperties.push_back(MDNode::get( 159 1.1 joerg Ctx, MDString::get(Ctx, "llvm.loop.unroll_and_jam.disable"))); 160 1.1 joerg LoopProperties = NewLoopProperties; 161 1.1 joerg } 162 1.1 joerg return createPartialUnrollMetadata(Attrs, LoopProperties, 163 1.1 joerg HasUserTransforms); 164 1.1 joerg } 165 1.1 joerg 166 1.1 joerg SmallVector<Metadata *, 4> FollowupLoopProperties; 167 1.1 joerg FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end()); 168 1.1 joerg FollowupLoopProperties.push_back( 169 1.1 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll_and_jam.disable"))); 170 1.1 joerg 171 1.1 joerg bool FollowupHasTransforms = false; 172 1.1 joerg MDNode *Followup = createPartialUnrollMetadata(Attrs, FollowupLoopProperties, 173 1.1 joerg FollowupHasTransforms); 174 1.1 joerg 175 1.1 joerg SmallVector<Metadata *, 4> Args; 176 1.1.1.2 joerg Args.push_back(nullptr); 177 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end()); 178 1.1 joerg 179 1.1 joerg // Setting unroll_and_jam.count 180 1.1 joerg if (Attrs.UnrollAndJamCount > 0) { 181 1.1 joerg Metadata *Vals[] = { 182 1.1 joerg MDString::get(Ctx, "llvm.loop.unroll_and_jam.count"), 183 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx), 184 1.1 joerg Attrs.UnrollAndJamCount))}; 185 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals)); 186 1.1 joerg } 187 1.1 joerg 188 1.1 joerg if (Attrs.UnrollAndJamEnable == LoopAttributes::Enable) { 189 1.1 joerg Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll_and_jam.enable")}; 190 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals)); 191 1.1 joerg } 192 1.1 joerg 193 1.1 joerg if (FollowupHasTransforms) 194 1.1 joerg Args.push_back(MDNode::get( 195 1.1 joerg Ctx, {MDString::get(Ctx, "llvm.loop.unroll_and_jam.followup_outer"), 196 1.1 joerg Followup})); 197 1.1 joerg 198 1.1 joerg if (UnrollAndJamInnerFollowup) 199 1.1 joerg Args.push_back(MDNode::get( 200 1.1 joerg Ctx, {MDString::get(Ctx, "llvm.loop.unroll_and_jam.followup_inner"), 201 1.1 joerg UnrollAndJamInnerFollowup})); 202 1.1 joerg 203 1.1 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args); 204 1.1 joerg LoopID->replaceOperandWith(0, LoopID); 205 1.1 joerg HasUserTransforms = true; 206 1.1 joerg return LoopID; 207 1.1 joerg } 208 1.1 joerg 209 1.1 joerg MDNode * 210 1.1 joerg LoopInfo::createLoopVectorizeMetadata(const LoopAttributes &Attrs, 211 1.1 joerg ArrayRef<Metadata *> LoopProperties, 212 1.1 joerg bool &HasUserTransforms) { 213 1.1 joerg LLVMContext &Ctx = Header->getContext(); 214 1.1 joerg 215 1.1 joerg Optional<bool> Enabled; 216 1.1 joerg if (Attrs.VectorizeEnable == LoopAttributes::Disable) 217 1.1 joerg Enabled = false; 218 1.1 joerg else if (Attrs.VectorizeEnable != LoopAttributes::Unspecified || 219 1.1 joerg Attrs.VectorizePredicateEnable != LoopAttributes::Unspecified || 220 1.1.1.2 joerg Attrs.InterleaveCount != 0 || Attrs.VectorizeWidth != 0 || 221 1.1.1.2 joerg Attrs.VectorizeScalable != LoopAttributes::Unspecified) 222 1.1 joerg Enabled = true; 223 1.1 joerg 224 1.1 joerg if (Enabled != true) { 225 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties; 226 1.1 joerg if (Enabled == false) { 227 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end()); 228 1.1 joerg NewLoopProperties.push_back( 229 1.1 joerg MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.vectorize.enable"), 230 1.1 joerg ConstantAsMetadata::get(ConstantInt::get( 231 1.1 joerg llvm::Type::getInt1Ty(Ctx), 0))})); 232 1.1 joerg LoopProperties = NewLoopProperties; 233 1.1 joerg } 234 1.1 joerg return createUnrollAndJamMetadata(Attrs, LoopProperties, HasUserTransforms); 235 1.1 joerg } 236 1.1 joerg 237 1.1 joerg // Apply all loop properties to the vectorized loop. 238 1.1 joerg SmallVector<Metadata *, 4> FollowupLoopProperties; 239 1.1 joerg FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end()); 240 1.1 joerg 241 1.1 joerg // Don't vectorize an already vectorized loop. 242 1.1 joerg FollowupLoopProperties.push_back( 243 1.1 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized"))); 244 1.1 joerg 245 1.1 joerg bool FollowupHasTransforms = false; 246 1.1 joerg MDNode *Followup = createUnrollAndJamMetadata(Attrs, FollowupLoopProperties, 247 1.1 joerg FollowupHasTransforms); 248 1.1 joerg 249 1.1 joerg SmallVector<Metadata *, 4> Args; 250 1.1.1.2 joerg Args.push_back(nullptr); 251 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end()); 252 1.1 joerg 253 1.1.1.2 joerg // Setting vectorize.predicate when it has been specified and vectorization 254 1.1.1.2 joerg // has not been disabled. 255 1.1 joerg bool IsVectorPredicateEnabled = false; 256 1.1.1.2 joerg if (Attrs.VectorizePredicateEnable != LoopAttributes::Unspecified) { 257 1.1 joerg IsVectorPredicateEnabled = 258 1.1 joerg (Attrs.VectorizePredicateEnable == LoopAttributes::Enable); 259 1.1 joerg 260 1.1 joerg Metadata *Vals[] = { 261 1.1 joerg MDString::get(Ctx, "llvm.loop.vectorize.predicate.enable"), 262 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt1Ty(Ctx), 263 1.1 joerg IsVectorPredicateEnabled))}; 264 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals)); 265 1.1 joerg } 266 1.1 joerg 267 1.1 joerg // Setting vectorize.width 268 1.1 joerg if (Attrs.VectorizeWidth > 0) { 269 1.1 joerg Metadata *Vals[] = { 270 1.1 joerg MDString::get(Ctx, "llvm.loop.vectorize.width"), 271 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx), 272 1.1 joerg Attrs.VectorizeWidth))}; 273 1.1.1.2 joerg 274 1.1.1.2 joerg Args.push_back(MDNode::get(Ctx, Vals)); 275 1.1.1.2 joerg } 276 1.1.1.2 joerg 277 1.1.1.2 joerg if (Attrs.VectorizeScalable != LoopAttributes::Unspecified) { 278 1.1.1.2 joerg bool IsScalable = Attrs.VectorizeScalable == LoopAttributes::Enable; 279 1.1.1.2 joerg Metadata *Vals[] = { 280 1.1.1.2 joerg MDString::get(Ctx, "llvm.loop.vectorize.scalable.enable"), 281 1.1.1.2 joerg ConstantAsMetadata::get( 282 1.1.1.2 joerg ConstantInt::get(llvm::Type::getInt1Ty(Ctx), IsScalable))}; 283 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals)); 284 1.1 joerg } 285 1.1 joerg 286 1.1 joerg // Setting interleave.count 287 1.1 joerg if (Attrs.InterleaveCount > 0) { 288 1.1 joerg Metadata *Vals[] = { 289 1.1 joerg MDString::get(Ctx, "llvm.loop.interleave.count"), 290 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx), 291 1.1 joerg Attrs.InterleaveCount))}; 292 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals)); 293 1.1 joerg } 294 1.1 joerg 295 1.1.1.2 joerg // vectorize.enable is set if: 296 1.1.1.2 joerg // 1) loop hint vectorize.enable is set, or 297 1.1.1.2 joerg // 2) it is implied when vectorize.predicate is set, or 298 1.1.1.2 joerg // 3) it is implied when vectorize.width is set to a value > 1 299 1.1.1.2 joerg // 4) it is implied when vectorize.scalable.enable is true 300 1.1.1.2 joerg // 5) it is implied when vectorize.width is unset (0) and the user 301 1.1.1.2 joerg // explicitly requested fixed-width vectorization, i.e. 302 1.1.1.2 joerg // vectorize.scalable.enable is false. 303 1.1 joerg if (Attrs.VectorizeEnable != LoopAttributes::Unspecified || 304 1.1.1.2 joerg (IsVectorPredicateEnabled && Attrs.VectorizeWidth != 1) || 305 1.1.1.2 joerg Attrs.VectorizeWidth > 1 || 306 1.1.1.2 joerg Attrs.VectorizeScalable == LoopAttributes::Enable || 307 1.1.1.2 joerg (Attrs.VectorizeScalable == LoopAttributes::Disable && 308 1.1.1.2 joerg Attrs.VectorizeWidth != 1)) { 309 1.1.1.2 joerg bool AttrVal = Attrs.VectorizeEnable != LoopAttributes::Disable; 310 1.1.1.2 joerg Args.push_back( 311 1.1.1.2 joerg MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.vectorize.enable"), 312 1.1.1.2 joerg ConstantAsMetadata::get(ConstantInt::get( 313 1.1.1.2 joerg llvm::Type::getInt1Ty(Ctx), AttrVal))})); 314 1.1 joerg } 315 1.1 joerg 316 1.1 joerg if (FollowupHasTransforms) 317 1.1 joerg Args.push_back(MDNode::get( 318 1.1 joerg Ctx, 319 1.1 joerg {MDString::get(Ctx, "llvm.loop.vectorize.followup_all"), Followup})); 320 1.1 joerg 321 1.1.1.2 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args); 322 1.1 joerg LoopID->replaceOperandWith(0, LoopID); 323 1.1 joerg HasUserTransforms = true; 324 1.1 joerg return LoopID; 325 1.1 joerg } 326 1.1 joerg 327 1.1 joerg MDNode * 328 1.1 joerg LoopInfo::createLoopDistributeMetadata(const LoopAttributes &Attrs, 329 1.1 joerg ArrayRef<Metadata *> LoopProperties, 330 1.1 joerg bool &HasUserTransforms) { 331 1.1 joerg LLVMContext &Ctx = Header->getContext(); 332 1.1 joerg 333 1.1 joerg Optional<bool> Enabled; 334 1.1 joerg if (Attrs.DistributeEnable == LoopAttributes::Disable) 335 1.1 joerg Enabled = false; 336 1.1 joerg if (Attrs.DistributeEnable == LoopAttributes::Enable) 337 1.1 joerg Enabled = true; 338 1.1 joerg 339 1.1 joerg if (Enabled != true) { 340 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties; 341 1.1 joerg if (Enabled == false) { 342 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end()); 343 1.1 joerg NewLoopProperties.push_back( 344 1.1 joerg MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.distribute.enable"), 345 1.1 joerg ConstantAsMetadata::get(ConstantInt::get( 346 1.1 joerg llvm::Type::getInt1Ty(Ctx), 0))})); 347 1.1 joerg LoopProperties = NewLoopProperties; 348 1.1 joerg } 349 1.1 joerg return createLoopVectorizeMetadata(Attrs, LoopProperties, 350 1.1 joerg HasUserTransforms); 351 1.1 joerg } 352 1.1 joerg 353 1.1 joerg bool FollowupHasTransforms = false; 354 1.1 joerg MDNode *Followup = 355 1.1 joerg createLoopVectorizeMetadata(Attrs, LoopProperties, FollowupHasTransforms); 356 1.1 joerg 357 1.1 joerg SmallVector<Metadata *, 4> Args; 358 1.1.1.2 joerg Args.push_back(nullptr); 359 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end()); 360 1.1 joerg 361 1.1 joerg Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.distribute.enable"), 362 1.1 joerg ConstantAsMetadata::get(ConstantInt::get( 363 1.1 joerg llvm::Type::getInt1Ty(Ctx), 364 1.1 joerg (Attrs.DistributeEnable == LoopAttributes::Enable)))}; 365 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals)); 366 1.1 joerg 367 1.1 joerg if (FollowupHasTransforms) 368 1.1 joerg Args.push_back(MDNode::get( 369 1.1 joerg Ctx, 370 1.1 joerg {MDString::get(Ctx, "llvm.loop.distribute.followup_all"), Followup})); 371 1.1 joerg 372 1.1.1.2 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args); 373 1.1 joerg LoopID->replaceOperandWith(0, LoopID); 374 1.1 joerg HasUserTransforms = true; 375 1.1 joerg return LoopID; 376 1.1 joerg } 377 1.1 joerg 378 1.1 joerg MDNode *LoopInfo::createFullUnrollMetadata(const LoopAttributes &Attrs, 379 1.1 joerg ArrayRef<Metadata *> LoopProperties, 380 1.1 joerg bool &HasUserTransforms) { 381 1.1 joerg LLVMContext &Ctx = Header->getContext(); 382 1.1 joerg 383 1.1 joerg Optional<bool> Enabled; 384 1.1 joerg if (Attrs.UnrollEnable == LoopAttributes::Disable) 385 1.1 joerg Enabled = false; 386 1.1 joerg else if (Attrs.UnrollEnable == LoopAttributes::Full) 387 1.1 joerg Enabled = true; 388 1.1 joerg 389 1.1 joerg if (Enabled != true) { 390 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties; 391 1.1 joerg if (Enabled == false) { 392 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end()); 393 1.1 joerg NewLoopProperties.push_back( 394 1.1 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.disable"))); 395 1.1 joerg LoopProperties = NewLoopProperties; 396 1.1 joerg } 397 1.1 joerg return createLoopDistributeMetadata(Attrs, LoopProperties, 398 1.1 joerg HasUserTransforms); 399 1.1 joerg } 400 1.1 joerg 401 1.1 joerg SmallVector<Metadata *, 4> Args; 402 1.1.1.2 joerg Args.push_back(nullptr); 403 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end()); 404 1.1 joerg Args.push_back(MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.full"))); 405 1.1 joerg 406 1.1 joerg // No follow-up: there is no loop after full unrolling. 407 1.1 joerg // TODO: Warn if there are transformations after full unrolling. 408 1.1 joerg 409 1.1 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args); 410 1.1 joerg LoopID->replaceOperandWith(0, LoopID); 411 1.1 joerg HasUserTransforms = true; 412 1.1 joerg return LoopID; 413 1.1 joerg } 414 1.1 joerg 415 1.1 joerg MDNode *LoopInfo::createMetadata( 416 1.1 joerg const LoopAttributes &Attrs, 417 1.1 joerg llvm::ArrayRef<llvm::Metadata *> AdditionalLoopProperties, 418 1.1 joerg bool &HasUserTransforms) { 419 1.1 joerg SmallVector<Metadata *, 3> LoopProperties; 420 1.1 joerg 421 1.1 joerg // If we have a valid start debug location for the loop, add it. 422 1.1 joerg if (StartLoc) { 423 1.1 joerg LoopProperties.push_back(StartLoc.getAsMDNode()); 424 1.1 joerg 425 1.1 joerg // If we also have a valid end debug location for the loop, add it. 426 1.1 joerg if (EndLoc) 427 1.1 joerg LoopProperties.push_back(EndLoc.getAsMDNode()); 428 1.1 joerg } 429 1.1 joerg 430 1.1.1.2 joerg LLVMContext &Ctx = Header->getContext(); 431 1.1.1.2 joerg if (Attrs.MustProgress) 432 1.1.1.2 joerg LoopProperties.push_back( 433 1.1.1.2 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.mustprogress"))); 434 1.1.1.2 joerg 435 1.1 joerg assert(!!AccGroup == Attrs.IsParallel && 436 1.1 joerg "There must be an access group iff the loop is parallel"); 437 1.1 joerg if (Attrs.IsParallel) { 438 1.1 joerg LoopProperties.push_back(MDNode::get( 439 1.1 joerg Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup})); 440 1.1 joerg } 441 1.1 joerg 442 1.1 joerg LoopProperties.insert(LoopProperties.end(), AdditionalLoopProperties.begin(), 443 1.1 joerg AdditionalLoopProperties.end()); 444 1.1 joerg return createFullUnrollMetadata(Attrs, LoopProperties, HasUserTransforms); 445 1.1 joerg } 446 1.1 joerg 447 1.1 joerg LoopAttributes::LoopAttributes(bool IsParallel) 448 1.1 joerg : IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified), 449 1.1 joerg UnrollEnable(LoopAttributes::Unspecified), 450 1.1 joerg UnrollAndJamEnable(LoopAttributes::Unspecified), 451 1.1 joerg VectorizePredicateEnable(LoopAttributes::Unspecified), VectorizeWidth(0), 452 1.1.1.2 joerg VectorizeScalable(LoopAttributes::Unspecified), InterleaveCount(0), 453 1.1.1.2 joerg UnrollCount(0), UnrollAndJamCount(0), 454 1.1 joerg DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false), 455 1.1.1.2 joerg PipelineInitiationInterval(0), MustProgress(false) {} 456 1.1 joerg 457 1.1 joerg void LoopAttributes::clear() { 458 1.1 joerg IsParallel = false; 459 1.1 joerg VectorizeWidth = 0; 460 1.1.1.2 joerg VectorizeScalable = LoopAttributes::Unspecified; 461 1.1 joerg InterleaveCount = 0; 462 1.1 joerg UnrollCount = 0; 463 1.1 joerg UnrollAndJamCount = 0; 464 1.1 joerg VectorizeEnable = LoopAttributes::Unspecified; 465 1.1 joerg UnrollEnable = LoopAttributes::Unspecified; 466 1.1 joerg UnrollAndJamEnable = LoopAttributes::Unspecified; 467 1.1 joerg VectorizePredicateEnable = LoopAttributes::Unspecified; 468 1.1 joerg DistributeEnable = LoopAttributes::Unspecified; 469 1.1 joerg PipelineDisabled = false; 470 1.1 joerg PipelineInitiationInterval = 0; 471 1.1.1.2 joerg MustProgress = false; 472 1.1 joerg } 473 1.1 joerg 474 1.1 joerg LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs, 475 1.1 joerg const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc, 476 1.1 joerg LoopInfo *Parent) 477 1.1 joerg : Header(Header), Attrs(Attrs), StartLoc(StartLoc), EndLoc(EndLoc), 478 1.1 joerg Parent(Parent) { 479 1.1 joerg 480 1.1 joerg if (Attrs.IsParallel) { 481 1.1 joerg // Create an access group for this loop. 482 1.1 joerg LLVMContext &Ctx = Header->getContext(); 483 1.1 joerg AccGroup = MDNode::getDistinct(Ctx, {}); 484 1.1 joerg } 485 1.1 joerg 486 1.1 joerg if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 && 487 1.1.1.2 joerg Attrs.VectorizeScalable == LoopAttributes::Unspecified && 488 1.1 joerg Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 && 489 1.1 joerg Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled && 490 1.1 joerg Attrs.PipelineInitiationInterval == 0 && 491 1.1 joerg Attrs.VectorizePredicateEnable == LoopAttributes::Unspecified && 492 1.1 joerg Attrs.VectorizeEnable == LoopAttributes::Unspecified && 493 1.1 joerg Attrs.UnrollEnable == LoopAttributes::Unspecified && 494 1.1 joerg Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified && 495 1.1 joerg Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc && 496 1.1.1.2 joerg !EndLoc && !Attrs.MustProgress) 497 1.1 joerg return; 498 1.1 joerg 499 1.1 joerg TempLoopID = MDNode::getTemporary(Header->getContext(), None); 500 1.1 joerg } 501 1.1 joerg 502 1.1 joerg void LoopInfo::finish() { 503 1.1 joerg // We did not annotate the loop body instructions because there are no 504 1.1 joerg // attributes for this loop. 505 1.1 joerg if (!TempLoopID) 506 1.1 joerg return; 507 1.1 joerg 508 1.1 joerg MDNode *LoopID; 509 1.1 joerg LoopAttributes CurLoopAttr = Attrs; 510 1.1 joerg LLVMContext &Ctx = Header->getContext(); 511 1.1 joerg 512 1.1 joerg if (Parent && (Parent->Attrs.UnrollAndJamEnable || 513 1.1 joerg Parent->Attrs.UnrollAndJamCount != 0)) { 514 1.1 joerg // Parent unroll-and-jams this loop. 515 1.1 joerg // Split the transformations in those that happens before the unroll-and-jam 516 1.1 joerg // and those after. 517 1.1 joerg 518 1.1 joerg LoopAttributes BeforeJam, AfterJam; 519 1.1 joerg 520 1.1 joerg BeforeJam.IsParallel = AfterJam.IsParallel = Attrs.IsParallel; 521 1.1 joerg 522 1.1 joerg BeforeJam.VectorizeWidth = Attrs.VectorizeWidth; 523 1.1.1.2 joerg BeforeJam.VectorizeScalable = Attrs.VectorizeScalable; 524 1.1 joerg BeforeJam.InterleaveCount = Attrs.InterleaveCount; 525 1.1 joerg BeforeJam.VectorizeEnable = Attrs.VectorizeEnable; 526 1.1 joerg BeforeJam.DistributeEnable = Attrs.DistributeEnable; 527 1.1 joerg BeforeJam.VectorizePredicateEnable = Attrs.VectorizePredicateEnable; 528 1.1 joerg 529 1.1 joerg switch (Attrs.UnrollEnable) { 530 1.1 joerg case LoopAttributes::Unspecified: 531 1.1 joerg case LoopAttributes::Disable: 532 1.1 joerg BeforeJam.UnrollEnable = Attrs.UnrollEnable; 533 1.1 joerg AfterJam.UnrollEnable = Attrs.UnrollEnable; 534 1.1 joerg break; 535 1.1 joerg case LoopAttributes::Full: 536 1.1 joerg BeforeJam.UnrollEnable = LoopAttributes::Full; 537 1.1 joerg break; 538 1.1 joerg case LoopAttributes::Enable: 539 1.1 joerg AfterJam.UnrollEnable = LoopAttributes::Enable; 540 1.1 joerg break; 541 1.1 joerg } 542 1.1 joerg 543 1.1 joerg AfterJam.VectorizePredicateEnable = Attrs.VectorizePredicateEnable; 544 1.1 joerg AfterJam.UnrollCount = Attrs.UnrollCount; 545 1.1 joerg AfterJam.PipelineDisabled = Attrs.PipelineDisabled; 546 1.1 joerg AfterJam.PipelineInitiationInterval = Attrs.PipelineInitiationInterval; 547 1.1 joerg 548 1.1 joerg // If this loop is subject of an unroll-and-jam by the parent loop, and has 549 1.1 joerg // an unroll-and-jam annotation itself, we have to decide whether to first 550 1.1 joerg // apply the parent's unroll-and-jam or this loop's unroll-and-jam. The 551 1.1 joerg // UnrollAndJam pass processes loops from inner to outer, so we apply the 552 1.1 joerg // inner first. 553 1.1 joerg BeforeJam.UnrollAndJamCount = Attrs.UnrollAndJamCount; 554 1.1 joerg BeforeJam.UnrollAndJamEnable = Attrs.UnrollAndJamEnable; 555 1.1 joerg 556 1.1 joerg // Set the inner followup metadata to process by the outer loop. Only 557 1.1 joerg // consider the first inner loop. 558 1.1 joerg if (!Parent->UnrollAndJamInnerFollowup) { 559 1.1 joerg // Splitting the attributes into a BeforeJam and an AfterJam part will 560 1.1 joerg // stop 'llvm.loop.isvectorized' (generated by vectorization in BeforeJam) 561 1.1 joerg // to be forwarded to the AfterJam part. We detect the situation here and 562 1.1 joerg // add it manually. 563 1.1 joerg SmallVector<Metadata *, 1> BeforeLoopProperties; 564 1.1 joerg if (BeforeJam.VectorizeEnable != LoopAttributes::Unspecified || 565 1.1 joerg BeforeJam.VectorizePredicateEnable != LoopAttributes::Unspecified || 566 1.1.1.2 joerg BeforeJam.InterleaveCount != 0 || BeforeJam.VectorizeWidth != 0 || 567 1.1.1.2 joerg BeforeJam.VectorizeScalable == LoopAttributes::Enable) 568 1.1 joerg BeforeLoopProperties.push_back( 569 1.1 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized"))); 570 1.1 joerg 571 1.1 joerg bool InnerFollowupHasTransform = false; 572 1.1 joerg MDNode *InnerFollowup = createMetadata(AfterJam, BeforeLoopProperties, 573 1.1 joerg InnerFollowupHasTransform); 574 1.1 joerg if (InnerFollowupHasTransform) 575 1.1 joerg Parent->UnrollAndJamInnerFollowup = InnerFollowup; 576 1.1 joerg } 577 1.1 joerg 578 1.1 joerg CurLoopAttr = BeforeJam; 579 1.1 joerg } 580 1.1 joerg 581 1.1 joerg bool HasUserTransforms = false; 582 1.1 joerg LoopID = createMetadata(CurLoopAttr, {}, HasUserTransforms); 583 1.1 joerg TempLoopID->replaceAllUsesWith(LoopID); 584 1.1 joerg } 585 1.1 joerg 586 1.1 joerg void LoopInfoStack::push(BasicBlock *Header, const llvm::DebugLoc &StartLoc, 587 1.1 joerg const llvm::DebugLoc &EndLoc) { 588 1.1 joerg Active.emplace_back( 589 1.1 joerg new LoopInfo(Header, StagedAttrs, StartLoc, EndLoc, 590 1.1 joerg Active.empty() ? nullptr : Active.back().get())); 591 1.1 joerg // Clear the attributes so nested loops do not inherit them. 592 1.1 joerg StagedAttrs.clear(); 593 1.1 joerg } 594 1.1 joerg 595 1.1 joerg void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, 596 1.1.1.2 joerg const clang::CodeGenOptions &CGOpts, 597 1.1 joerg ArrayRef<const clang::Attr *> Attrs, 598 1.1 joerg const llvm::DebugLoc &StartLoc, 599 1.1.1.2 joerg const llvm::DebugLoc &EndLoc, bool MustProgress) { 600 1.1 joerg // Identify loop hint attributes from Attrs. 601 1.1 joerg for (const auto *Attr : Attrs) { 602 1.1 joerg const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr); 603 1.1 joerg const OpenCLUnrollHintAttr *OpenCLHint = 604 1.1 joerg dyn_cast<OpenCLUnrollHintAttr>(Attr); 605 1.1 joerg 606 1.1 joerg // Skip non loop hint attributes 607 1.1 joerg if (!LH && !OpenCLHint) { 608 1.1 joerg continue; 609 1.1 joerg } 610 1.1 joerg 611 1.1 joerg LoopHintAttr::OptionType Option = LoopHintAttr::Unroll; 612 1.1 joerg LoopHintAttr::LoopHintState State = LoopHintAttr::Disable; 613 1.1 joerg unsigned ValueInt = 1; 614 1.1 joerg // Translate opencl_unroll_hint attribute argument to 615 1.1 joerg // equivalent LoopHintAttr enums. 616 1.1 joerg // OpenCL v2.0 s6.11.5: 617 1.1 joerg // 0 - enable unroll (no argument). 618 1.1 joerg // 1 - disable unroll. 619 1.1 joerg // other positive integer n - unroll by n. 620 1.1 joerg if (OpenCLHint) { 621 1.1 joerg ValueInt = OpenCLHint->getUnrollHint(); 622 1.1 joerg if (ValueInt == 0) { 623 1.1 joerg State = LoopHintAttr::Enable; 624 1.1 joerg } else if (ValueInt != 1) { 625 1.1 joerg Option = LoopHintAttr::UnrollCount; 626 1.1 joerg State = LoopHintAttr::Numeric; 627 1.1 joerg } 628 1.1 joerg } else if (LH) { 629 1.1 joerg auto *ValueExpr = LH->getValue(); 630 1.1 joerg if (ValueExpr) { 631 1.1 joerg llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx); 632 1.1 joerg ValueInt = ValueAPS.getSExtValue(); 633 1.1 joerg } 634 1.1 joerg 635 1.1 joerg Option = LH->getOption(); 636 1.1 joerg State = LH->getState(); 637 1.1 joerg } 638 1.1 joerg switch (State) { 639 1.1 joerg case LoopHintAttr::Disable: 640 1.1 joerg switch (Option) { 641 1.1 joerg case LoopHintAttr::Vectorize: 642 1.1 joerg // Disable vectorization by specifying a width of 1. 643 1.1 joerg setVectorizeWidth(1); 644 1.1.1.2 joerg setVectorizeScalable(LoopAttributes::Unspecified); 645 1.1 joerg break; 646 1.1 joerg case LoopHintAttr::Interleave: 647 1.1 joerg // Disable interleaving by speciyfing a count of 1. 648 1.1 joerg setInterleaveCount(1); 649 1.1 joerg break; 650 1.1 joerg case LoopHintAttr::Unroll: 651 1.1 joerg setUnrollState(LoopAttributes::Disable); 652 1.1 joerg break; 653 1.1 joerg case LoopHintAttr::UnrollAndJam: 654 1.1 joerg setUnrollAndJamState(LoopAttributes::Disable); 655 1.1 joerg break; 656 1.1 joerg case LoopHintAttr::VectorizePredicate: 657 1.1 joerg setVectorizePredicateState(LoopAttributes::Disable); 658 1.1 joerg break; 659 1.1 joerg case LoopHintAttr::Distribute: 660 1.1 joerg setDistributeState(false); 661 1.1 joerg break; 662 1.1 joerg case LoopHintAttr::PipelineDisabled: 663 1.1 joerg setPipelineDisabled(true); 664 1.1 joerg break; 665 1.1 joerg case LoopHintAttr::UnrollCount: 666 1.1 joerg case LoopHintAttr::UnrollAndJamCount: 667 1.1 joerg case LoopHintAttr::VectorizeWidth: 668 1.1 joerg case LoopHintAttr::InterleaveCount: 669 1.1 joerg case LoopHintAttr::PipelineInitiationInterval: 670 1.1 joerg llvm_unreachable("Options cannot be disabled."); 671 1.1 joerg break; 672 1.1 joerg } 673 1.1 joerg break; 674 1.1 joerg case LoopHintAttr::Enable: 675 1.1 joerg switch (Option) { 676 1.1 joerg case LoopHintAttr::Vectorize: 677 1.1 joerg case LoopHintAttr::Interleave: 678 1.1 joerg setVectorizeEnable(true); 679 1.1 joerg break; 680 1.1 joerg case LoopHintAttr::Unroll: 681 1.1 joerg setUnrollState(LoopAttributes::Enable); 682 1.1 joerg break; 683 1.1 joerg case LoopHintAttr::UnrollAndJam: 684 1.1 joerg setUnrollAndJamState(LoopAttributes::Enable); 685 1.1 joerg break; 686 1.1 joerg case LoopHintAttr::VectorizePredicate: 687 1.1 joerg setVectorizePredicateState(LoopAttributes::Enable); 688 1.1 joerg break; 689 1.1 joerg case LoopHintAttr::Distribute: 690 1.1 joerg setDistributeState(true); 691 1.1 joerg break; 692 1.1 joerg case LoopHintAttr::UnrollCount: 693 1.1 joerg case LoopHintAttr::UnrollAndJamCount: 694 1.1 joerg case LoopHintAttr::VectorizeWidth: 695 1.1 joerg case LoopHintAttr::InterleaveCount: 696 1.1 joerg case LoopHintAttr::PipelineDisabled: 697 1.1 joerg case LoopHintAttr::PipelineInitiationInterval: 698 1.1 joerg llvm_unreachable("Options cannot enabled."); 699 1.1 joerg break; 700 1.1 joerg } 701 1.1 joerg break; 702 1.1 joerg case LoopHintAttr::AssumeSafety: 703 1.1 joerg switch (Option) { 704 1.1 joerg case LoopHintAttr::Vectorize: 705 1.1 joerg case LoopHintAttr::Interleave: 706 1.1 joerg // Apply "llvm.mem.parallel_loop_access" metadata to load/stores. 707 1.1 joerg setParallel(true); 708 1.1 joerg setVectorizeEnable(true); 709 1.1 joerg break; 710 1.1 joerg case LoopHintAttr::Unroll: 711 1.1 joerg case LoopHintAttr::UnrollAndJam: 712 1.1 joerg case LoopHintAttr::VectorizePredicate: 713 1.1 joerg case LoopHintAttr::UnrollCount: 714 1.1 joerg case LoopHintAttr::UnrollAndJamCount: 715 1.1 joerg case LoopHintAttr::VectorizeWidth: 716 1.1 joerg case LoopHintAttr::InterleaveCount: 717 1.1 joerg case LoopHintAttr::Distribute: 718 1.1 joerg case LoopHintAttr::PipelineDisabled: 719 1.1 joerg case LoopHintAttr::PipelineInitiationInterval: 720 1.1 joerg llvm_unreachable("Options cannot be used to assume mem safety."); 721 1.1 joerg break; 722 1.1 joerg } 723 1.1 joerg break; 724 1.1 joerg case LoopHintAttr::Full: 725 1.1 joerg switch (Option) { 726 1.1 joerg case LoopHintAttr::Unroll: 727 1.1 joerg setUnrollState(LoopAttributes::Full); 728 1.1 joerg break; 729 1.1 joerg case LoopHintAttr::UnrollAndJam: 730 1.1 joerg setUnrollAndJamState(LoopAttributes::Full); 731 1.1 joerg break; 732 1.1 joerg case LoopHintAttr::Vectorize: 733 1.1 joerg case LoopHintAttr::Interleave: 734 1.1 joerg case LoopHintAttr::UnrollCount: 735 1.1 joerg case LoopHintAttr::UnrollAndJamCount: 736 1.1 joerg case LoopHintAttr::VectorizeWidth: 737 1.1 joerg case LoopHintAttr::InterleaveCount: 738 1.1 joerg case LoopHintAttr::Distribute: 739 1.1 joerg case LoopHintAttr::PipelineDisabled: 740 1.1 joerg case LoopHintAttr::PipelineInitiationInterval: 741 1.1 joerg case LoopHintAttr::VectorizePredicate: 742 1.1 joerg llvm_unreachable("Options cannot be used with 'full' hint."); 743 1.1 joerg break; 744 1.1 joerg } 745 1.1 joerg break; 746 1.1.1.2 joerg case LoopHintAttr::FixedWidth: 747 1.1.1.2 joerg case LoopHintAttr::ScalableWidth: 748 1.1 joerg switch (Option) { 749 1.1 joerg case LoopHintAttr::VectorizeWidth: 750 1.1.1.2 joerg setVectorizeScalable(State == LoopHintAttr::ScalableWidth 751 1.1.1.2 joerg ? LoopAttributes::Enable 752 1.1.1.2 joerg : LoopAttributes::Disable); 753 1.1.1.2 joerg if (LH->getValue()) 754 1.1.1.2 joerg setVectorizeWidth(ValueInt); 755 1.1.1.2 joerg break; 756 1.1.1.2 joerg default: 757 1.1.1.2 joerg llvm_unreachable("Options cannot be used with 'scalable' hint."); 758 1.1 joerg break; 759 1.1.1.2 joerg } 760 1.1.1.2 joerg break; 761 1.1.1.2 joerg case LoopHintAttr::Numeric: 762 1.1.1.2 joerg switch (Option) { 763 1.1 joerg case LoopHintAttr::InterleaveCount: 764 1.1 joerg setInterleaveCount(ValueInt); 765 1.1 joerg break; 766 1.1 joerg case LoopHintAttr::UnrollCount: 767 1.1 joerg setUnrollCount(ValueInt); 768 1.1 joerg break; 769 1.1 joerg case LoopHintAttr::UnrollAndJamCount: 770 1.1 joerg setUnrollAndJamCount(ValueInt); 771 1.1 joerg break; 772 1.1 joerg case LoopHintAttr::PipelineInitiationInterval: 773 1.1 joerg setPipelineInitiationInterval(ValueInt); 774 1.1 joerg break; 775 1.1 joerg case LoopHintAttr::Unroll: 776 1.1 joerg case LoopHintAttr::UnrollAndJam: 777 1.1 joerg case LoopHintAttr::VectorizePredicate: 778 1.1 joerg case LoopHintAttr::Vectorize: 779 1.1.1.2 joerg case LoopHintAttr::VectorizeWidth: 780 1.1 joerg case LoopHintAttr::Interleave: 781 1.1 joerg case LoopHintAttr::Distribute: 782 1.1 joerg case LoopHintAttr::PipelineDisabled: 783 1.1 joerg llvm_unreachable("Options cannot be assigned a value."); 784 1.1 joerg break; 785 1.1 joerg } 786 1.1 joerg break; 787 1.1 joerg } 788 1.1 joerg } 789 1.1 joerg 790 1.1.1.2 joerg setMustProgress(MustProgress); 791 1.1.1.2 joerg 792 1.1.1.2 joerg if (CGOpts.OptimizationLevel > 0) 793 1.1.1.2 joerg // Disable unrolling for the loop, if unrolling is disabled (via 794 1.1.1.2 joerg // -fno-unroll-loops) and no pragmas override the decision. 795 1.1.1.2 joerg if (!CGOpts.UnrollLoops && 796 1.1.1.2 joerg (StagedAttrs.UnrollEnable == LoopAttributes::Unspecified && 797 1.1.1.2 joerg StagedAttrs.UnrollCount == 0)) 798 1.1.1.2 joerg setUnrollState(LoopAttributes::Disable); 799 1.1.1.2 joerg 800 1.1 joerg /// Stage the attributes. 801 1.1 joerg push(Header, StartLoc, EndLoc); 802 1.1 joerg } 803 1.1 joerg 804 1.1 joerg void LoopInfoStack::pop() { 805 1.1 joerg assert(!Active.empty() && "No active loops to pop"); 806 1.1 joerg Active.back()->finish(); 807 1.1 joerg Active.pop_back(); 808 1.1 joerg } 809 1.1 joerg 810 1.1 joerg void LoopInfoStack::InsertHelper(Instruction *I) const { 811 1.1 joerg if (I->mayReadOrWriteMemory()) { 812 1.1 joerg SmallVector<Metadata *, 4> AccessGroups; 813 1.1 joerg for (const auto &AL : Active) { 814 1.1 joerg // Here we assume that every loop that has an access group is parallel. 815 1.1 joerg if (MDNode *Group = AL->getAccessGroup()) 816 1.1 joerg AccessGroups.push_back(Group); 817 1.1 joerg } 818 1.1 joerg MDNode *UnionMD = nullptr; 819 1.1 joerg if (AccessGroups.size() == 1) 820 1.1 joerg UnionMD = cast<MDNode>(AccessGroups[0]); 821 1.1 joerg else if (AccessGroups.size() >= 2) 822 1.1 joerg UnionMD = MDNode::get(I->getContext(), AccessGroups); 823 1.1 joerg I->setMetadata("llvm.access.group", UnionMD); 824 1.1 joerg } 825 1.1 joerg 826 1.1 joerg if (!hasInfo()) 827 1.1 joerg return; 828 1.1 joerg 829 1.1 joerg const LoopInfo &L = getInfo(); 830 1.1 joerg if (!L.getLoopID()) 831 1.1 joerg return; 832 1.1 joerg 833 1.1 joerg if (I->isTerminator()) { 834 1.1 joerg for (BasicBlock *Succ : successors(I)) 835 1.1 joerg if (Succ == L.getHeader()) { 836 1.1 joerg I->setMetadata(llvm::LLVMContext::MD_loop, L.getLoopID()); 837 1.1 joerg break; 838 1.1 joerg } 839 1.1 joerg return; 840 1.1 joerg } 841 1.1 joerg } 842