| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 1 | //===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===// | 
|  | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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 | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 |  | 
|  | 9 | #include "CGLoopInfo.h" | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 10 | #include "clang/AST/ASTContext.h" | 
| Tyler Nowicki | 9d268e1 | 2015-06-11 23:23:17 +0000 | [diff] [blame] | 11 | #include "clang/AST/Attr.h" | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 12 | #include "llvm/IR/BasicBlock.h" | 
| Chandler Carruth | 4aaaaab | 2018-10-18 08:16:20 +0000 | [diff] [blame] | 13 | #include "llvm/IR/CFG.h" | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 14 | #include "llvm/IR/Constants.h" | 
|  | 15 | #include "llvm/IR/InstrTypes.h" | 
|  | 16 | #include "llvm/IR/Instructions.h" | 
|  | 17 | #include "llvm/IR/Metadata.h" | 
| Tyler Nowicki | 4e8e900 | 2015-06-08 23:27:35 +0000 | [diff] [blame] | 18 | using namespace clang::CodeGen; | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 19 | using namespace llvm; | 
|  | 20 |  | 
| Hal Finkel | c07e19b | 2016-05-25 21:53:24 +0000 | [diff] [blame] | 21 | static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs, | 
| Benjamin Kramer | 81cb4b7 | 2016-11-24 16:01:20 +0000 | [diff] [blame] | 22 | const llvm::DebugLoc &StartLoc, | 
| Michael Kruse | 0535137 | 2018-12-20 21:24:54 +0000 | [diff] [blame] | 23 | const llvm::DebugLoc &EndLoc, MDNode *&AccGroup) { | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 24 |  | 
| Tyler Nowicki | da46d0e | 2015-07-14 23:03:09 +0000 | [diff] [blame] | 25 | if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 && | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 26 | Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 && | 
| Aaron Ballman | 9bdf515 | 2019-01-04 17:20:00 +0000 | [diff] [blame] | 27 | Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled && | 
|  | 28 | Attrs.PipelineInitiationInterval == 0 && | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 29 | Attrs.VectorizeEnable == LoopAttributes::Unspecified && | 
| Hal Finkel | c07e19b | 2016-05-25 21:53:24 +0000 | [diff] [blame] | 30 | Attrs.UnrollEnable == LoopAttributes::Unspecified && | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 31 | Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified && | 
|  | 32 | Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc && | 
|  | 33 | !EndLoc) | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 34 | return nullptr; | 
|  | 35 |  | 
| Duncan P. N. Exon Smith | fb49491 | 2014-12-09 18:39:32 +0000 | [diff] [blame] | 36 | SmallVector<Metadata *, 4> Args; | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 37 | // Reserve operand 0 for loop id self reference. | 
| Duncan P. N. Exon Smith | 7fd74ac | 2015-01-19 21:30:48 +0000 | [diff] [blame] | 38 | auto TempNode = MDNode::getTemporary(Ctx, None); | 
|  | 39 | Args.push_back(TempNode.get()); | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 40 |  | 
| Amara Emerson | 652795d | 2016-11-10 14:44:30 +0000 | [diff] [blame] | 41 | // If we have a valid start debug location for the loop, add it. | 
|  | 42 | if (StartLoc) { | 
|  | 43 | Args.push_back(StartLoc.getAsMDNode()); | 
|  | 44 |  | 
|  | 45 | // If we also have a valid end debug location for the loop, add it. | 
|  | 46 | if (EndLoc) | 
|  | 47 | Args.push_back(EndLoc.getAsMDNode()); | 
|  | 48 | } | 
| Hal Finkel | c07e19b | 2016-05-25 21:53:24 +0000 | [diff] [blame] | 49 |  | 
| Tyler Nowicki | da46d0e | 2015-07-14 23:03:09 +0000 | [diff] [blame] | 50 | // Setting vectorize.width | 
|  | 51 | if (Attrs.VectorizeWidth > 0) { | 
| Duncan P. N. Exon Smith | fb49491 | 2014-12-09 18:39:32 +0000 | [diff] [blame] | 52 | Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"), | 
|  | 53 | ConstantAsMetadata::get(ConstantInt::get( | 
| Tyler Nowicki | da46d0e | 2015-07-14 23:03:09 +0000 | [diff] [blame] | 54 | Type::getInt32Ty(Ctx), Attrs.VectorizeWidth))}; | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 55 | Args.push_back(MDNode::get(Ctx, Vals)); | 
|  | 56 | } | 
|  | 57 |  | 
| Tyler Nowicki | da46d0e | 2015-07-14 23:03:09 +0000 | [diff] [blame] | 58 | // Setting interleave.count | 
|  | 59 | if (Attrs.InterleaveCount > 0) { | 
| Duncan P. N. Exon Smith | fb49491 | 2014-12-09 18:39:32 +0000 | [diff] [blame] | 60 | Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"), | 
|  | 61 | ConstantAsMetadata::get(ConstantInt::get( | 
| Tyler Nowicki | da46d0e | 2015-07-14 23:03:09 +0000 | [diff] [blame] | 62 | Type::getInt32Ty(Ctx), Attrs.InterleaveCount))}; | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 63 | Args.push_back(MDNode::get(Ctx, Vals)); | 
|  | 64 | } | 
|  | 65 |  | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 66 | // Setting unroll.count | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 67 | if (Attrs.UnrollCount > 0) { | 
|  | 68 | Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.count"), | 
|  | 69 | ConstantAsMetadata::get(ConstantInt::get( | 
|  | 70 | Type::getInt32Ty(Ctx), Attrs.UnrollCount))}; | 
|  | 71 | Args.push_back(MDNode::get(Ctx, Vals)); | 
|  | 72 | } | 
|  | 73 |  | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 74 | // Setting unroll_and_jam.count | 
|  | 75 | if (Attrs.UnrollAndJamCount > 0) { | 
|  | 76 | Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll_and_jam.count"), | 
|  | 77 | ConstantAsMetadata::get(ConstantInt::get( | 
|  | 78 | Type::getInt32Ty(Ctx), Attrs.UnrollAndJamCount))}; | 
|  | 79 | Args.push_back(MDNode::get(Ctx, Vals)); | 
|  | 80 | } | 
|  | 81 |  | 
| Tyler Nowicki | da46d0e | 2015-07-14 23:03:09 +0000 | [diff] [blame] | 82 | // Setting vectorize.enable | 
|  | 83 | if (Attrs.VectorizeEnable != LoopAttributes::Unspecified) { | 
|  | 84 | Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.enable"), | 
|  | 85 | ConstantAsMetadata::get(ConstantInt::get( | 
|  | 86 | Type::getInt1Ty(Ctx), (Attrs.VectorizeEnable == | 
|  | 87 | LoopAttributes::Enable)))}; | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 88 | Args.push_back(MDNode::get(Ctx, Vals)); | 
|  | 89 | } | 
|  | 90 |  | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 91 | // Setting unroll.full or unroll.disable | 
|  | 92 | if (Attrs.UnrollEnable != LoopAttributes::Unspecified) { | 
| Mark Heffernan | 397a98d | 2015-08-10 17:29:39 +0000 | [diff] [blame] | 93 | std::string Name; | 
|  | 94 | if (Attrs.UnrollEnable == LoopAttributes::Enable) | 
|  | 95 | Name = "llvm.loop.unroll.enable"; | 
|  | 96 | else if (Attrs.UnrollEnable == LoopAttributes::Full) | 
|  | 97 | Name = "llvm.loop.unroll.full"; | 
|  | 98 | else | 
|  | 99 | Name = "llvm.loop.unroll.disable"; | 
|  | 100 | Metadata *Vals[] = {MDString::get(Ctx, Name)}; | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 101 | Args.push_back(MDNode::get(Ctx, Vals)); | 
|  | 102 | } | 
|  | 103 |  | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 104 | // Setting unroll_and_jam.full or unroll_and_jam.disable | 
|  | 105 | if (Attrs.UnrollAndJamEnable != LoopAttributes::Unspecified) { | 
|  | 106 | std::string Name; | 
|  | 107 | if (Attrs.UnrollAndJamEnable == LoopAttributes::Enable) | 
|  | 108 | Name = "llvm.loop.unroll_and_jam.enable"; | 
|  | 109 | else if (Attrs.UnrollAndJamEnable == LoopAttributes::Full) | 
|  | 110 | Name = "llvm.loop.unroll_and_jam.full"; | 
|  | 111 | else | 
|  | 112 | Name = "llvm.loop.unroll_and_jam.disable"; | 
|  | 113 | Metadata *Vals[] = {MDString::get(Ctx, Name)}; | 
|  | 114 | Args.push_back(MDNode::get(Ctx, Vals)); | 
|  | 115 | } | 
|  | 116 |  | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 117 | if (Attrs.DistributeEnable != LoopAttributes::Unspecified) { | 
|  | 118 | Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.distribute.enable"), | 
|  | 119 | ConstantAsMetadata::get(ConstantInt::get( | 
|  | 120 | Type::getInt1Ty(Ctx), (Attrs.DistributeEnable == | 
|  | 121 | LoopAttributes::Enable)))}; | 
|  | 122 | Args.push_back(MDNode::get(Ctx, Vals)); | 
|  | 123 | } | 
|  | 124 |  | 
| Michael Kruse | 0535137 | 2018-12-20 21:24:54 +0000 | [diff] [blame] | 125 | if (Attrs.IsParallel) { | 
|  | 126 | AccGroup = MDNode::getDistinct(Ctx, {}); | 
|  | 127 | Args.push_back(MDNode::get( | 
|  | 128 | Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup})); | 
|  | 129 | } | 
|  | 130 |  | 
| Aaron Ballman | 9bdf515 | 2019-01-04 17:20:00 +0000 | [diff] [blame] | 131 | if (Attrs.PipelineDisabled) { | 
|  | 132 | Metadata *Vals[] = { | 
|  | 133 | MDString::get(Ctx, "llvm.loop.pipeline.disable"), | 
|  | 134 | ConstantAsMetadata::get(ConstantInt::get( | 
|  | 135 | Type::getInt1Ty(Ctx), (Attrs.PipelineDisabled == true)))}; | 
|  | 136 | Args.push_back(MDNode::get(Ctx, Vals)); | 
|  | 137 | } | 
|  | 138 |  | 
|  | 139 | if (Attrs.PipelineInitiationInterval > 0) { | 
|  | 140 | Metadata *Vals[] = { | 
|  | 141 | MDString::get(Ctx, "llvm.loop.pipeline.initiationinterval"), | 
|  | 142 | ConstantAsMetadata::get(ConstantInt::get( | 
|  | 143 | Type::getInt32Ty(Ctx), Attrs.PipelineInitiationInterval))}; | 
|  | 144 | Args.push_back(MDNode::get(Ctx, Vals)); | 
|  | 145 | } | 
|  | 146 |  | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 147 | // Set the first operand to itself. | 
| Duncan P. N. Exon Smith | fb49491 | 2014-12-09 18:39:32 +0000 | [diff] [blame] | 148 | MDNode *LoopID = MDNode::get(Ctx, Args); | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 149 | LoopID->replaceOperandWith(0, LoopID); | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 150 | return LoopID; | 
|  | 151 | } | 
|  | 152 |  | 
|  | 153 | LoopAttributes::LoopAttributes(bool IsParallel) | 
| Tyler Nowicki | da46d0e | 2015-07-14 23:03:09 +0000 | [diff] [blame] | 154 | : IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified), | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 155 | UnrollEnable(LoopAttributes::Unspecified), | 
|  | 156 | UnrollAndJamEnable(LoopAttributes::Unspecified), VectorizeWidth(0), | 
|  | 157 | InterleaveCount(0), UnrollCount(0), UnrollAndJamCount(0), | 
| Aaron Ballman | 9bdf515 | 2019-01-04 17:20:00 +0000 | [diff] [blame] | 158 | DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false), | 
|  | 159 | PipelineInitiationInterval(0) {} | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 160 |  | 
|  | 161 | void LoopAttributes::clear() { | 
|  | 162 | IsParallel = false; | 
| Tyler Nowicki | da46d0e | 2015-07-14 23:03:09 +0000 | [diff] [blame] | 163 | VectorizeWidth = 0; | 
|  | 164 | InterleaveCount = 0; | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 165 | UnrollCount = 0; | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 166 | UnrollAndJamCount = 0; | 
| Tyler Nowicki | da46d0e | 2015-07-14 23:03:09 +0000 | [diff] [blame] | 167 | VectorizeEnable = LoopAttributes::Unspecified; | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 168 | UnrollEnable = LoopAttributes::Unspecified; | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 169 | UnrollAndJamEnable = LoopAttributes::Unspecified; | 
| Adam Nemet | 9c84859 | 2016-08-24 04:31:56 +0000 | [diff] [blame] | 170 | DistributeEnable = LoopAttributes::Unspecified; | 
| Aaron Ballman | 9bdf515 | 2019-01-04 17:20:00 +0000 | [diff] [blame] | 171 | PipelineDisabled = false; | 
|  | 172 | PipelineInitiationInterval = 0; | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 173 | } | 
|  | 174 |  | 
| Hal Finkel | c07e19b | 2016-05-25 21:53:24 +0000 | [diff] [blame] | 175 | LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs, | 
| Benjamin Kramer | 81cb4b7 | 2016-11-24 16:01:20 +0000 | [diff] [blame] | 176 | const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc) | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 177 | : LoopID(nullptr), Header(Header), Attrs(Attrs) { | 
| Michael Kruse | 0535137 | 2018-12-20 21:24:54 +0000 | [diff] [blame] | 178 | LoopID = | 
|  | 179 | createMetadata(Header->getContext(), Attrs, StartLoc, EndLoc, AccGroup); | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 180 | } | 
|  | 181 |  | 
| Benjamin Kramer | 81cb4b7 | 2016-11-24 16:01:20 +0000 | [diff] [blame] | 182 | void LoopInfoStack::push(BasicBlock *Header, const llvm::DebugLoc &StartLoc, | 
|  | 183 | const llvm::DebugLoc &EndLoc) { | 
| Amara Emerson | 652795d | 2016-11-10 14:44:30 +0000 | [diff] [blame] | 184 | Active.push_back(LoopInfo(Header, StagedAttrs, StartLoc, EndLoc)); | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 185 | // Clear the attributes so nested loops do not inherit them. | 
|  | 186 | StagedAttrs.clear(); | 
|  | 187 | } | 
|  | 188 |  | 
|  | 189 | void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, | 
| Hal Finkel | c07e19b | 2016-05-25 21:53:24 +0000 | [diff] [blame] | 190 | ArrayRef<const clang::Attr *> Attrs, | 
| Benjamin Kramer | 81cb4b7 | 2016-11-24 16:01:20 +0000 | [diff] [blame] | 191 | const llvm::DebugLoc &StartLoc, | 
|  | 192 | const llvm::DebugLoc &EndLoc) { | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 193 |  | 
|  | 194 | // Identify loop hint attributes from Attrs. | 
| Tyler Nowicki | 9d268e1 | 2015-06-11 23:23:17 +0000 | [diff] [blame] | 195 | for (const auto *Attr : Attrs) { | 
|  | 196 | const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr); | 
| Anastasia Stulova | 6bdbcbb | 2016-02-19 18:30:11 +0000 | [diff] [blame] | 197 | const OpenCLUnrollHintAttr *OpenCLHint = | 
|  | 198 | dyn_cast<OpenCLUnrollHintAttr>(Attr); | 
| Tyler Nowicki | 9d268e1 | 2015-06-11 23:23:17 +0000 | [diff] [blame] | 199 |  | 
|  | 200 | // Skip non loop hint attributes | 
| Anastasia Stulova | 6bdbcbb | 2016-02-19 18:30:11 +0000 | [diff] [blame] | 201 | if (!LH && !OpenCLHint) { | 
| Tyler Nowicki | 9d268e1 | 2015-06-11 23:23:17 +0000 | [diff] [blame] | 202 | continue; | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 203 | } | 
|  | 204 |  | 
| Anastasia Stulova | 6bdbcbb | 2016-02-19 18:30:11 +0000 | [diff] [blame] | 205 | LoopHintAttr::OptionType Option = LoopHintAttr::Unroll; | 
|  | 206 | LoopHintAttr::LoopHintState State = LoopHintAttr::Disable; | 
|  | 207 | unsigned ValueInt = 1; | 
|  | 208 | // Translate opencl_unroll_hint attribute argument to | 
|  | 209 | // equivalent LoopHintAttr enums. | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 210 | // OpenCL v2.0 s6.11.5: | 
| Anastasia Stulova | 6bdbcbb | 2016-02-19 18:30:11 +0000 | [diff] [blame] | 211 | // 0 - full unroll (no argument). | 
|  | 212 | // 1 - disable unroll. | 
|  | 213 | // other positive integer n - unroll by n. | 
|  | 214 | if (OpenCLHint) { | 
|  | 215 | ValueInt = OpenCLHint->getUnrollHint(); | 
|  | 216 | if (ValueInt == 0) { | 
|  | 217 | State = LoopHintAttr::Full; | 
|  | 218 | } else if (ValueInt != 1) { | 
|  | 219 | Option = LoopHintAttr::UnrollCount; | 
|  | 220 | State = LoopHintAttr::Numeric; | 
|  | 221 | } | 
|  | 222 | } else if (LH) { | 
|  | 223 | auto *ValueExpr = LH->getValue(); | 
|  | 224 | if (ValueExpr) { | 
|  | 225 | llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx); | 
|  | 226 | ValueInt = ValueAPS.getSExtValue(); | 
|  | 227 | } | 
|  | 228 |  | 
|  | 229 | Option = LH->getOption(); | 
|  | 230 | State = LH->getState(); | 
|  | 231 | } | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 232 | switch (State) { | 
|  | 233 | case LoopHintAttr::Disable: | 
|  | 234 | switch (Option) { | 
|  | 235 | case LoopHintAttr::Vectorize: | 
|  | 236 | // Disable vectorization by specifying a width of 1. | 
|  | 237 | setVectorizeWidth(1); | 
|  | 238 | break; | 
|  | 239 | case LoopHintAttr::Interleave: | 
|  | 240 | // Disable interleaving by speciyfing a count of 1. | 
|  | 241 | setInterleaveCount(1); | 
|  | 242 | break; | 
|  | 243 | case LoopHintAttr::Unroll: | 
| Mark Heffernan | 397a98d | 2015-08-10 17:29:39 +0000 | [diff] [blame] | 244 | setUnrollState(LoopAttributes::Disable); | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 245 | break; | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 246 | case LoopHintAttr::UnrollAndJam: | 
|  | 247 | setUnrollAndJamState(LoopAttributes::Disable); | 
|  | 248 | break; | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 249 | case LoopHintAttr::Distribute: | 
|  | 250 | setDistributeState(false); | 
|  | 251 | break; | 
| Aaron Ballman | 9bdf515 | 2019-01-04 17:20:00 +0000 | [diff] [blame] | 252 | case LoopHintAttr::PipelineDisabled: | 
|  | 253 | setPipelineDisabled(true); | 
|  | 254 | break; | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 255 | case LoopHintAttr::UnrollCount: | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 256 | case LoopHintAttr::UnrollAndJamCount: | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 257 | case LoopHintAttr::VectorizeWidth: | 
|  | 258 | case LoopHintAttr::InterleaveCount: | 
| Aaron Ballman | 9bdf515 | 2019-01-04 17:20:00 +0000 | [diff] [blame] | 259 | case LoopHintAttr::PipelineInitiationInterval: | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 260 | llvm_unreachable("Options cannot be disabled."); | 
|  | 261 | break; | 
| Tyler Nowicki | 9d268e1 | 2015-06-11 23:23:17 +0000 | [diff] [blame] | 262 | } | 
|  | 263 | break; | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 264 | case LoopHintAttr::Enable: | 
|  | 265 | switch (Option) { | 
|  | 266 | case LoopHintAttr::Vectorize: | 
|  | 267 | case LoopHintAttr::Interleave: | 
|  | 268 | setVectorizeEnable(true); | 
|  | 269 | break; | 
|  | 270 | case LoopHintAttr::Unroll: | 
| Mark Heffernan | 397a98d | 2015-08-10 17:29:39 +0000 | [diff] [blame] | 271 | setUnrollState(LoopAttributes::Enable); | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 272 | break; | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 273 | case LoopHintAttr::UnrollAndJam: | 
|  | 274 | setUnrollAndJamState(LoopAttributes::Enable); | 
|  | 275 | break; | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 276 | case LoopHintAttr::Distribute: | 
|  | 277 | setDistributeState(true); | 
|  | 278 | break; | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 279 | case LoopHintAttr::UnrollCount: | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 280 | case LoopHintAttr::UnrollAndJamCount: | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 281 | case LoopHintAttr::VectorizeWidth: | 
|  | 282 | case LoopHintAttr::InterleaveCount: | 
| Aaron Ballman | 9bdf515 | 2019-01-04 17:20:00 +0000 | [diff] [blame] | 283 | case LoopHintAttr::PipelineDisabled: | 
|  | 284 | case LoopHintAttr::PipelineInitiationInterval: | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 285 | llvm_unreachable("Options cannot enabled."); | 
|  | 286 | break; | 
|  | 287 | } | 
|  | 288 | break; | 
|  | 289 | case LoopHintAttr::AssumeSafety: | 
|  | 290 | switch (Option) { | 
|  | 291 | case LoopHintAttr::Vectorize: | 
|  | 292 | case LoopHintAttr::Interleave: | 
|  | 293 | // Apply "llvm.mem.parallel_loop_access" metadata to load/stores. | 
|  | 294 | setParallel(true); | 
|  | 295 | setVectorizeEnable(true); | 
|  | 296 | break; | 
|  | 297 | case LoopHintAttr::Unroll: | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 298 | case LoopHintAttr::UnrollAndJam: | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 299 | case LoopHintAttr::UnrollCount: | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 300 | case LoopHintAttr::UnrollAndJamCount: | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 301 | case LoopHintAttr::VectorizeWidth: | 
|  | 302 | case LoopHintAttr::InterleaveCount: | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 303 | case LoopHintAttr::Distribute: | 
| Aaron Ballman | 9bdf515 | 2019-01-04 17:20:00 +0000 | [diff] [blame] | 304 | case LoopHintAttr::PipelineDisabled: | 
|  | 305 | case LoopHintAttr::PipelineInitiationInterval: | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 306 | llvm_unreachable("Options cannot be used to assume mem safety."); | 
|  | 307 | break; | 
|  | 308 | } | 
|  | 309 | break; | 
| Mark Heffernan | 397a98d | 2015-08-10 17:29:39 +0000 | [diff] [blame] | 310 | case LoopHintAttr::Full: | 
|  | 311 | switch (Option) { | 
|  | 312 | case LoopHintAttr::Unroll: | 
|  | 313 | setUnrollState(LoopAttributes::Full); | 
|  | 314 | break; | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 315 | case LoopHintAttr::UnrollAndJam: | 
|  | 316 | setUnrollAndJamState(LoopAttributes::Full); | 
|  | 317 | break; | 
| Mark Heffernan | 397a98d | 2015-08-10 17:29:39 +0000 | [diff] [blame] | 318 | case LoopHintAttr::Vectorize: | 
|  | 319 | case LoopHintAttr::Interleave: | 
|  | 320 | case LoopHintAttr::UnrollCount: | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 321 | case LoopHintAttr::UnrollAndJamCount: | 
| Mark Heffernan | 397a98d | 2015-08-10 17:29:39 +0000 | [diff] [blame] | 322 | case LoopHintAttr::VectorizeWidth: | 
|  | 323 | case LoopHintAttr::InterleaveCount: | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 324 | case LoopHintAttr::Distribute: | 
| Aaron Ballman | 9bdf515 | 2019-01-04 17:20:00 +0000 | [diff] [blame] | 325 | case LoopHintAttr::PipelineDisabled: | 
|  | 326 | case LoopHintAttr::PipelineInitiationInterval: | 
| Mark Heffernan | 397a98d | 2015-08-10 17:29:39 +0000 | [diff] [blame] | 327 | llvm_unreachable("Options cannot be used with 'full' hint."); | 
|  | 328 | break; | 
|  | 329 | } | 
|  | 330 | break; | 
|  | 331 | case LoopHintAttr::Numeric: | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 332 | switch (Option) { | 
|  | 333 | case LoopHintAttr::VectorizeWidth: | 
|  | 334 | setVectorizeWidth(ValueInt); | 
|  | 335 | break; | 
|  | 336 | case LoopHintAttr::InterleaveCount: | 
|  | 337 | setInterleaveCount(ValueInt); | 
|  | 338 | break; | 
|  | 339 | case LoopHintAttr::UnrollCount: | 
|  | 340 | setUnrollCount(ValueInt); | 
|  | 341 | break; | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 342 | case LoopHintAttr::UnrollAndJamCount: | 
|  | 343 | setUnrollAndJamCount(ValueInt); | 
|  | 344 | break; | 
| Aaron Ballman | 9bdf515 | 2019-01-04 17:20:00 +0000 | [diff] [blame] | 345 | case LoopHintAttr::PipelineInitiationInterval: | 
|  | 346 | setPipelineInitiationInterval(ValueInt); | 
|  | 347 | break; | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 348 | case LoopHintAttr::Unroll: | 
| David Green | c8e3924 | 2018-08-01 14:36:12 +0000 | [diff] [blame] | 349 | case LoopHintAttr::UnrollAndJam: | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 350 | case LoopHintAttr::Vectorize: | 
|  | 351 | case LoopHintAttr::Interleave: | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 352 | case LoopHintAttr::Distribute: | 
| Aaron Ballman | 9bdf515 | 2019-01-04 17:20:00 +0000 | [diff] [blame] | 353 | case LoopHintAttr::PipelineDisabled: | 
| Mark Heffernan | 397a98d | 2015-08-10 17:29:39 +0000 | [diff] [blame] | 354 | llvm_unreachable("Options cannot be assigned a value."); | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 355 | break; | 
|  | 356 | } | 
| Tyler Nowicki | 9d268e1 | 2015-06-11 23:23:17 +0000 | [diff] [blame] | 357 | break; | 
|  | 358 | } | 
|  | 359 | } | 
|  | 360 |  | 
| Tyler Nowicki | 54c020d | 2015-07-27 20:10:20 +0000 | [diff] [blame] | 361 | /// Stage the attributes. | 
| Amara Emerson | 652795d | 2016-11-10 14:44:30 +0000 | [diff] [blame] | 362 | push(Header, StartLoc, EndLoc); | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 363 | } | 
|  | 364 |  | 
|  | 365 | void LoopInfoStack::pop() { | 
|  | 366 | assert(!Active.empty() && "No active loops to pop"); | 
|  | 367 | Active.pop_back(); | 
|  | 368 | } | 
|  | 369 |  | 
|  | 370 | void LoopInfoStack::InsertHelper(Instruction *I) const { | 
| Michael Kruse | 0535137 | 2018-12-20 21:24:54 +0000 | [diff] [blame] | 371 | if (I->mayReadOrWriteMemory()) { | 
|  | 372 | SmallVector<Metadata *, 4> AccessGroups; | 
|  | 373 | for (const LoopInfo &AL : Active) { | 
|  | 374 | // Here we assume that every loop that has an access group is parallel. | 
|  | 375 | if (MDNode *Group = AL.getAccessGroup()) | 
|  | 376 | AccessGroups.push_back(Group); | 
|  | 377 | } | 
|  | 378 | MDNode *UnionMD = nullptr; | 
|  | 379 | if (AccessGroups.size() == 1) | 
|  | 380 | UnionMD = cast<MDNode>(AccessGroups[0]); | 
|  | 381 | else if (AccessGroups.size() >= 2) | 
|  | 382 | UnionMD = MDNode::get(I->getContext(), AccessGroups); | 
|  | 383 | I->setMetadata("llvm.access.group", UnionMD); | 
|  | 384 | } | 
|  | 385 |  | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 386 | if (!hasInfo()) | 
|  | 387 | return; | 
|  | 388 |  | 
|  | 389 | const LoopInfo &L = getInfo(); | 
|  | 390 | if (!L.getLoopID()) | 
|  | 391 | return; | 
|  | 392 |  | 
| Chandler Carruth | 4aaaaab | 2018-10-18 08:16:20 +0000 | [diff] [blame] | 393 | if (I->isTerminator()) { | 
|  | 394 | for (BasicBlock *Succ : successors(I)) | 
|  | 395 | if (Succ == L.getHeader()) { | 
|  | 396 | I->setMetadata(llvm::LLVMContext::MD_loop, L.getLoopID()); | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 397 | break; | 
|  | 398 | } | 
|  | 399 | return; | 
|  | 400 | } | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 401 | } |