Home | History | Annotate | Line # | Download | only in CodeGen
      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