clang API Documentation

CGLoopInfo.cpp
Go to the documentation of this file.
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 }