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