1 //===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "CGLoopInfo.h" 11 #include "clang/AST/Attr.h" 12 #include "clang/Sema/LoopHint.h" 13 #include "llvm/IR/BasicBlock.h" 14 #include "llvm/IR/Constants.h" 15 #include "llvm/IR/InstrTypes.h" 16 #include "llvm/IR/Instructions.h" 17 #include "llvm/IR/Metadata.h" 18 using namespace clang::CodeGen; 19 using namespace llvm; 20 21 static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) { 22 23 if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 && 24 Attrs.InterleaveCount == 0 && 25 Attrs.VectorizeEnable == LoopAttributes::Unspecified) 26 return nullptr; 27 28 SmallVector<Metadata *, 4> Args; 29 // Reserve operand 0 for loop id self reference. 30 auto TempNode = MDNode::getTemporary(Ctx, None); 31 Args.push_back(TempNode.get()); 32 33 // Setting vectorize.width 34 if (Attrs.VectorizeWidth > 0) { 35 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"), 36 ConstantAsMetadata::get(ConstantInt::get( 37 Type::getInt32Ty(Ctx), Attrs.VectorizeWidth))}; 38 Args.push_back(MDNode::get(Ctx, Vals)); 39 } 40 41 // Setting interleave.count 42 if (Attrs.InterleaveCount > 0) { 43 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"), 44 ConstantAsMetadata::get(ConstantInt::get( 45 Type::getInt32Ty(Ctx), Attrs.InterleaveCount))}; 46 Args.push_back(MDNode::get(Ctx, Vals)); 47 } 48 49 // Setting vectorize.enable 50 if (Attrs.VectorizeEnable != LoopAttributes::Unspecified) { 51 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.enable"), 52 ConstantAsMetadata::get(ConstantInt::get( 53 Type::getInt1Ty(Ctx), (Attrs.VectorizeEnable == 54 LoopAttributes::Enable)))}; 55 Args.push_back(MDNode::get(Ctx, Vals)); 56 } 57 58 // Set the first operand to itself. 59 MDNode *LoopID = MDNode::get(Ctx, Args); 60 LoopID->replaceOperandWith(0, LoopID); 61 return LoopID; 62 } 63 64 LoopAttributes::LoopAttributes(bool IsParallel) 65 : IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified), 66 VectorizeWidth(0), InterleaveCount(0) {} 67 68 void LoopAttributes::clear() { 69 IsParallel = false; 70 VectorizeWidth = 0; 71 InterleaveCount = 0; 72 VectorizeEnable = LoopAttributes::Unspecified; 73 } 74 75 LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs) 76 : LoopID(nullptr), Header(Header), Attrs(Attrs) { 77 LoopID = createMetadata(Header->getContext(), Attrs); 78 } 79 80 void LoopInfoStack::push(BasicBlock *Header, 81 ArrayRef<const clang::Attr *> Attrs) { 82 for (const auto *Attr : Attrs) { 83 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr); 84 85 // Skip non loop hint attributes 86 if (!LH) 87 continue; 88 89 LoopHintAttr::OptionType Option = LH->getOption(); 90 LoopHintAttr::LoopHintState State = LH->getState(); 91 switch (Option) { 92 case LoopHintAttr::Vectorize: 93 case LoopHintAttr::Interleave: 94 if (State == LoopHintAttr::AssumeSafety) { 95 // Apply "llvm.mem.parallel_loop_access" metadata to load/stores. 96 setParallel(true); 97 } 98 break; 99 case LoopHintAttr::VectorizeWidth: 100 case LoopHintAttr::InterleaveCount: 101 case LoopHintAttr::Unroll: 102 case LoopHintAttr::UnrollCount: 103 // Nothing to do here for these loop hints. 104 break; 105 } 106 } 107 108 Active.push_back(LoopInfo(Header, StagedAttrs)); 109 // Clear the attributes so nested loops do not inherit them. 110 StagedAttrs.clear(); 111 } 112 113 void LoopInfoStack::pop() { 114 assert(!Active.empty() && "No active loops to pop"); 115 Active.pop_back(); 116 } 117 118 void LoopInfoStack::InsertHelper(Instruction *I) const { 119 if (!hasInfo()) 120 return; 121 122 const LoopInfo &L = getInfo(); 123 if (!L.getLoopID()) 124 return; 125 126 if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) { 127 for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i) 128 if (TI->getSuccessor(i) == L.getHeader()) { 129 TI->setMetadata("llvm.loop", L.getLoopID()); 130 break; 131 } 132 return; 133 } 134 135 if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory()) 136 I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID()); 137 } 138