blob: 011ae7e836aeef26275c35f901c175849d5ae942 [file] [log] [blame]
Alexander Musman515ad8c2014-05-22 08:54:05 +00001//===---- 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"
16using namespace clang;
17using namespace CodeGen;
18using namespace llvm;
19
20static 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
Duncan P. N. Exon Smithfb494912014-12-09 18:39:32 +000027 SmallVector<Metadata *, 4> Args;
Alexander Musman515ad8c2014-05-22 08:54:05 +000028 // Reserve operand 0 for loop id self reference.
Duncan P. N. Exon Smith7fd74ac2015-01-19 21:30:48 +000029 auto TempNode = MDNode::getTemporary(Ctx, None);
30 Args.push_back(TempNode.get());
Alexander Musman515ad8c2014-05-22 08:54:05 +000031
32 // Setting vectorizer.width
33 if (Attrs.VectorizerWidth > 0) {
Duncan P. N. Exon Smithfb494912014-12-09 18:39:32 +000034 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"),
35 ConstantAsMetadata::get(ConstantInt::get(
36 Type::getInt32Ty(Ctx), Attrs.VectorizerWidth))};
Alexander Musman515ad8c2014-05-22 08:54:05 +000037 Args.push_back(MDNode::get(Ctx, Vals));
38 }
39
40 // Setting vectorizer.unroll
41 if (Attrs.VectorizerUnroll > 0) {
Duncan P. N. Exon Smithfb494912014-12-09 18:39:32 +000042 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"),
43 ConstantAsMetadata::get(ConstantInt::get(
44 Type::getInt32Ty(Ctx), Attrs.VectorizerUnroll))};
Alexander Musman515ad8c2014-05-22 08:54:05 +000045 Args.push_back(MDNode::get(Ctx, Vals));
46 }
47
48 // Setting vectorizer.enable
49 if (Attrs.VectorizerEnable != LoopAttributes::VecUnspecified) {
Duncan P. N. Exon Smithfb494912014-12-09 18:39:32 +000050 Metadata *Vals[] = {
51 MDString::get(Ctx, "llvm.loop.vectorize.enable"),
52 ConstantAsMetadata::get(ConstantInt::get(
53 Type::getInt1Ty(Ctx),
54 (Attrs.VectorizerEnable == LoopAttributes::VecEnable)))};
Alexander Musman515ad8c2014-05-22 08:54:05 +000055 Args.push_back(MDNode::get(Ctx, Vals));
56 }
57
Alexander Musman515ad8c2014-05-22 08:54:05 +000058 // Set the first operand to itself.
Duncan P. N. Exon Smithfb494912014-12-09 18:39:32 +000059 MDNode *LoopID = MDNode::get(Ctx, Args);
Alexander Musman515ad8c2014-05-22 08:54:05 +000060 LoopID->replaceOperandWith(0, LoopID);
Alexander Musman515ad8c2014-05-22 08:54:05 +000061 return LoopID;
62}
63
64LoopAttributes::LoopAttributes(bool IsParallel)
65 : IsParallel(IsParallel), VectorizerEnable(LoopAttributes::VecUnspecified),
66 VectorizerWidth(0), VectorizerUnroll(0) {}
67
68void LoopAttributes::clear() {
69 IsParallel = false;
70 VectorizerWidth = 0;
71 VectorizerUnroll = 0;
72 VectorizerEnable = LoopAttributes::VecUnspecified;
73}
74
75LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs)
76 : LoopID(nullptr), Header(Header), Attrs(Attrs) {
77 LoopID = createMetadata(Header->getContext(), Attrs);
78}
79
80void LoopInfoStack::push(BasicBlock *Header) {
81 Active.push_back(LoopInfo(Header, StagedAttrs));
82 // Clear the attributes so nested loops do not inherit them.
83 StagedAttrs.clear();
84}
85
86void LoopInfoStack::pop() {
87 assert(!Active.empty() && "No active loops to pop");
88 Active.pop_back();
89}
90
91void LoopInfoStack::InsertHelper(Instruction *I) const {
92 if (!hasInfo())
93 return;
94
95 const LoopInfo &L = getInfo();
96 if (!L.getLoopID())
97 return;
98
99 if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) {
100 for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i)
101 if (TI->getSuccessor(i) == L.getHeader()) {
102 TI->setMetadata("llvm.loop", L.getLoopID());
103 break;
104 }
105 return;
106 }
107
108 if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory())
109 I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID());
110}