]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/CodeGen/CGLoopInfo.cpp
Merge latest (commit c8c1b3a77934768c7f7a4a9c10140c8bec529059) files
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / CodeGen / CGLoopInfo.cpp
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.interleave.count"),
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 }