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" 16using namespace clang; 17using namespace CodeGen; 18using namespace llvm; 19 20static 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<Value *, 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 Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.width"), 35 ConstantInt::get(Type::getInt32Ty(Ctx), 36 Attrs.VectorizerWidth) }; 37 Args.push_back(MDNode::get(Ctx, Vals)); 38 } 39 40 // Setting vectorizer.unroll 41 if (Attrs.VectorizerUnroll > 0) { 42 Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.unroll"), 43 ConstantInt::get(Type::getInt32Ty(Ctx), 44 Attrs.VectorizerUnroll) }; 45 Args.push_back(MDNode::get(Ctx, Vals)); 46 } 47 48 // Setting vectorizer.enable 49 if (Attrs.VectorizerEnable != LoopAttributes::VecUnspecified) { 50 Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.enable"), 51 ConstantInt::get(Type::getInt1Ty(Ctx), 52 (Attrs.VectorizerEnable == 53 LoopAttributes::VecEnable)) }; 54 Args.push_back(MDNode::get(Ctx, Vals)); 55 } 56 57 MDNode *LoopID = MDNode::get(Ctx, Args); 58 assert(LoopID->use_empty() && "LoopID should not be used"); 59 60 // Set the first operand to itself. 61 LoopID->replaceOperandWith(0, LoopID); 62 MDNode::deleteTemporary(TempNode); 63 return LoopID; 64} 65 66LoopAttributes::LoopAttributes(bool IsParallel) 67 : IsParallel(IsParallel), VectorizerEnable(LoopAttributes::VecUnspecified), 68 VectorizerWidth(0), VectorizerUnroll(0) {} 69 70void LoopAttributes::clear() { 71 IsParallel = false; 72 VectorizerWidth = 0; 73 VectorizerUnroll = 0; 74 VectorizerEnable = LoopAttributes::VecUnspecified; 75} 76 77LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs) 78 : LoopID(nullptr), Header(Header), Attrs(Attrs) { 79 LoopID = createMetadata(Header->getContext(), Attrs); 80} 81 82void LoopInfoStack::push(BasicBlock *Header) { 83 Active.push_back(LoopInfo(Header, StagedAttrs)); 84 // Clear the attributes so nested loops do not inherit them. 85 StagedAttrs.clear(); 86} 87 88void LoopInfoStack::pop() { 89 assert(!Active.empty() && "No active loops to pop"); 90 Active.pop_back(); 91} 92 93void LoopInfoStack::InsertHelper(Instruction *I) const { 94 if (!hasInfo()) 95 return; 96 97 const LoopInfo &L = getInfo(); 98 if (!L.getLoopID()) 99 return; 100 101 if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) { 102 for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i) 103 if (TI->getSuccessor(i) == L.getHeader()) { 104 TI->setMetadata("llvm.loop", L.getLoopID()); 105 break; 106 } 107 return; 108 } 109 110 if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory()) 111 I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID()); 112} 113