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 MDNode *TempNode = MDNode::getTemporary(Ctx, None); 30 Args.push_back(TempNode); 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 MDNode::deleteTemporary(TempNode); 62 return LoopID; 63 } 64 65 LoopAttributes::LoopAttributes(bool IsParallel) 66 : IsParallel(IsParallel), VectorizerEnable(LoopAttributes::VecUnspecified), 67 VectorizerWidth(0), VectorizerUnroll(0) {} 68 69 void LoopAttributes::clear() { 70 IsParallel = false; 71 VectorizerWidth = 0; 72 VectorizerUnroll = 0; 73 VectorizerEnable = LoopAttributes::VecUnspecified; 74 } 75 76 LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs) 77 : LoopID(nullptr), Header(Header), Attrs(Attrs) { 78 LoopID = createMetadata(Header->getContext(), Attrs); 79 } 80 81 void LoopInfoStack::push(BasicBlock *Header) { 82 Active.push_back(LoopInfo(Header, StagedAttrs)); 83 // Clear the attributes so nested loops do not inherit them. 84 StagedAttrs.clear(); 85 } 86 87 void LoopInfoStack::pop() { 88 assert(!Active.empty() && "No active loops to pop"); 89 Active.pop_back(); 90 } 91 92 void LoopInfoStack::InsertHelper(Instruction *I) const { 93 if (!hasInfo()) 94 return; 95 96 const LoopInfo &L = getInfo(); 97 if (!L.getLoopID()) 98 return; 99 100 if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) { 101 for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i) 102 if (TI->getSuccessor(i) == L.getHeader()) { 103 TI->setMetadata("llvm.loop", L.getLoopID()); 104 break; 105 } 106 return; 107 } 108 109 if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory()) 110 I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID()); 111 } 112