clang API Documentation
00001 //===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "CGLoopInfo.h" 00011 #include "llvm/IR/BasicBlock.h" 00012 #include "llvm/IR/Constants.h" 00013 #include "llvm/IR/InstrTypes.h" 00014 #include "llvm/IR/Instructions.h" 00015 #include "llvm/IR/Metadata.h" 00016 using namespace clang; 00017 using namespace CodeGen; 00018 using namespace llvm; 00019 00020 static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) { 00021 00022 if (!Attrs.IsParallel && Attrs.VectorizerWidth == 0 && 00023 Attrs.VectorizerUnroll == 0 && 00024 Attrs.VectorizerEnable == LoopAttributes::VecUnspecified) 00025 return nullptr; 00026 00027 SmallVector<Value *, 4> Args; 00028 // Reserve operand 0 for loop id self reference. 00029 MDNode *TempNode = MDNode::getTemporary(Ctx, None); 00030 Args.push_back(TempNode); 00031 00032 // Setting vectorizer.width 00033 if (Attrs.VectorizerWidth > 0) { 00034 Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.width"), 00035 ConstantInt::get(Type::getInt32Ty(Ctx), 00036 Attrs.VectorizerWidth) }; 00037 Args.push_back(MDNode::get(Ctx, Vals)); 00038 } 00039 00040 // Setting vectorizer.unroll 00041 if (Attrs.VectorizerUnroll > 0) { 00042 Value *Vals[] = { MDString::get(Ctx, "llvm.loop.interleave.count"), 00043 ConstantInt::get(Type::getInt32Ty(Ctx), 00044 Attrs.VectorizerUnroll) }; 00045 Args.push_back(MDNode::get(Ctx, Vals)); 00046 } 00047 00048 // Setting vectorizer.enable 00049 if (Attrs.VectorizerEnable != LoopAttributes::VecUnspecified) { 00050 Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.enable"), 00051 ConstantInt::get(Type::getInt1Ty(Ctx), 00052 (Attrs.VectorizerEnable == 00053 LoopAttributes::VecEnable)) }; 00054 Args.push_back(MDNode::get(Ctx, Vals)); 00055 } 00056 00057 MDNode *LoopID = MDNode::get(Ctx, Args); 00058 assert(LoopID->use_empty() && "LoopID should not be used"); 00059 00060 // Set the first operand to itself. 00061 LoopID->replaceOperandWith(0, LoopID); 00062 MDNode::deleteTemporary(TempNode); 00063 return LoopID; 00064 } 00065 00066 LoopAttributes::LoopAttributes(bool IsParallel) 00067 : IsParallel(IsParallel), VectorizerEnable(LoopAttributes::VecUnspecified), 00068 VectorizerWidth(0), VectorizerUnroll(0) {} 00069 00070 void LoopAttributes::clear() { 00071 IsParallel = false; 00072 VectorizerWidth = 0; 00073 VectorizerUnroll = 0; 00074 VectorizerEnable = LoopAttributes::VecUnspecified; 00075 } 00076 00077 LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs) 00078 : LoopID(nullptr), Header(Header), Attrs(Attrs) { 00079 LoopID = createMetadata(Header->getContext(), Attrs); 00080 } 00081 00082 void LoopInfoStack::push(BasicBlock *Header) { 00083 Active.push_back(LoopInfo(Header, StagedAttrs)); 00084 // Clear the attributes so nested loops do not inherit them. 00085 StagedAttrs.clear(); 00086 } 00087 00088 void LoopInfoStack::pop() { 00089 assert(!Active.empty() && "No active loops to pop"); 00090 Active.pop_back(); 00091 } 00092 00093 void LoopInfoStack::InsertHelper(Instruction *I) const { 00094 if (!hasInfo()) 00095 return; 00096 00097 const LoopInfo &L = getInfo(); 00098 if (!L.getLoopID()) 00099 return; 00100 00101 if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) { 00102 for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i) 00103 if (TI->getSuccessor(i) == L.getHeader()) { 00104 TI->setMetadata("llvm.loop", L.getLoopID()); 00105 break; 00106 } 00107 return; 00108 } 00109 00110 if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory()) 00111 I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID()); 00112 }