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 "llvm/IR/BasicBlock.h" 12 #include "llvm/IR/Constants.h" 13 #include "llvm/IR/InstrTypes.h" 14 #include "llvm/IR/Instructions.h" 15 #include "llvm/IR/Metadata.h" 16 using namespace clang; 17 using namespace CodeGen; 18 using namespace llvm; 19 20 static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) { 21 22 if (!Attrs.IsParallel && Attrs.VectorizerWidth == 0 && 23 Attrs.VectorizerUnroll == 0 && 24 Attrs.VectorizerEnable == LoopAttributes::VecUnspecified) 25 return nullptr; 26 27 SmallVector<Metadata *, 4> Args; 28 // Reserve operand 0 for loop id self reference. 29 auto TempNode = MDNode::getTemporary(Ctx, None); 30 Args.push_back(TempNode.get()); 31 32 // Setting vectorizer.width 33 if (Attrs.VectorizerWidth > 0) { 34 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"), 35 ConstantAsMetadata::get(ConstantInt::get( 36 Type::getInt32Ty(Ctx), Attrs.VectorizerWidth))}; 37 Args.push_back(MDNode::get(Ctx, Vals)); 38 } 39 40 // Setting vectorizer.unroll 41 if (Attrs.VectorizerUnroll > 0) { 42 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"), 43 ConstantAsMetadata::get(ConstantInt::get( 44 Type::getInt32Ty(Ctx), Attrs.VectorizerUnroll))}; 45 Args.push_back(MDNode::get(Ctx, Vals)); 46 } 47 48 // Setting vectorizer.enable 49 if (Attrs.VectorizerEnable != LoopAttributes::VecUnspecified) { 50 Metadata *Vals[] = { 51 MDString::get(Ctx, "llvm.loop.vectorize.enable"), 52 ConstantAsMetadata::get(ConstantInt::get( 53 Type::getInt1Ty(Ctx), 54 (Attrs.VectorizerEnable == LoopAttributes::VecEnable)))}; 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), VectorizerEnable(LoopAttributes::VecUnspecified), 66 VectorizerWidth(0), VectorizerUnroll(0) {} 67 68 void LoopAttributes::clear() { 69 IsParallel = false; 70 VectorizerWidth = 0; 71 VectorizerUnroll = 0; 72 VectorizerEnable = LoopAttributes::VecUnspecified; 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 Active.push_back(LoopInfo(Header, StagedAttrs)); 82 // Clear the attributes so nested loops do not inherit them. 83 StagedAttrs.clear(); 84 } 85 86 void LoopInfoStack::pop() { 87 assert(!Active.empty() && "No active loops to pop"); 88 Active.pop_back(); 89 } 90 91 void LoopInfoStack::InsertHelper(Instruction *I) const { 92 if (!hasInfo()) 93 return; 94 95 const LoopInfo &L = getInfo(); 96 if (!L.getLoopID()) 97 return; 98 99 if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) { 100 for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i) 101 if (TI->getSuccessor(i) == L.getHeader()) { 102 TI->setMetadata("llvm.loop", L.getLoopID()); 103 break; 104 } 105 return; 106 } 107 108 if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory()) 109 I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID()); 110 } 111