Home | History | Annotate | Download | only in CodeGen
      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<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 
     66 LoopAttributes::LoopAttributes(bool IsParallel)
     67     : IsParallel(IsParallel), VectorizerEnable(LoopAttributes::VecUnspecified),
     68       VectorizerWidth(0), VectorizerUnroll(0) {}
     69 
     70 void LoopAttributes::clear() {
     71   IsParallel = false;
     72   VectorizerWidth = 0;
     73   VectorizerUnroll = 0;
     74   VectorizerEnable = LoopAttributes::VecUnspecified;
     75 }
     76 
     77 LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs)
     78     : LoopID(nullptr), Header(Header), Attrs(Attrs) {
     79   LoopID = createMetadata(Header->getContext(), Attrs);
     80 }
     81 
     82 void 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 
     88 void LoopInfoStack::pop() {
     89   assert(!Active.empty() && "No active loops to pop");
     90   Active.pop_back();
     91 }
     92 
     93 void 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