xref: /minix3/external/bsd/llvm/dist/clang/lib/CodeGen/CGLoopInfo.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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 
createMetadata(LLVMContext & Ctx,const LoopAttributes & Attrs)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 
LoopAttributes(bool IsParallel)65 LoopAttributes::LoopAttributes(bool IsParallel)
66     : IsParallel(IsParallel), VectorizerEnable(LoopAttributes::VecUnspecified),
67       VectorizerWidth(0), VectorizerUnroll(0) {}
68 
clear()69 void LoopAttributes::clear() {
70   IsParallel = false;
71   VectorizerWidth = 0;
72   VectorizerUnroll = 0;
73   VectorizerEnable = LoopAttributes::VecUnspecified;
74 }
75 
LoopInfo(BasicBlock * Header,const LoopAttributes & Attrs)76 LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs)
77     : LoopID(nullptr), Header(Header), Attrs(Attrs) {
78   LoopID = createMetadata(Header->getContext(), Attrs);
79 }
80 
push(BasicBlock * Header)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 
pop()87 void LoopInfoStack::pop() {
88   assert(!Active.empty() && "No active loops to pop");
89   Active.pop_back();
90 }
91 
InsertHelper(Instruction * I) const92 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