blob: 3efa7c88389b0a92df3190f1096941aa7d56b97f [file] [log] [blame]
Tobias Grosser37c9b8e2014-03-04 14:59:00 +00001//===------ PollyIRBuilder.cpp --------------------------------------------===//
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// The Polly IRBuilder file contains Polly specific extensions for the IRBuilder
11// that are used e.g. to emit the llvm.loop.parallel metadata.
12//
13//===----------------------------------------------------------------------===//
14
15#include "polly/CodeGen/IRBuilder.h"
Johannes Doerfertecdf2632014-10-02 15:31:24 +000016#include "polly/ScopInfo.h"
17#include "polly/Support/ScopHelper.h"
Tobias Grosser4a07bbe2017-08-22 21:58:48 +000018#include "llvm/ADT/SmallVector.h"
Tobias Grosser37c9b8e2014-03-04 14:59:00 +000019#include "llvm/IR/Metadata.h"
20#include "llvm/Support/Debug.h"
21
22using namespace llvm;
23using namespace polly;
24
Tobias Grosser696a1ee2017-04-03 07:42:50 +000025static const int MaxArraysInAliasScops = 10;
26
Tobias Grosserc80d6972016-09-02 06:33:33 +000027/// Get a self referencing id metadata node.
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000028///
Johannes Doerfertecdf2632014-10-02 15:31:24 +000029/// The MDNode looks like this (if arg0/arg1 are not null):
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000030///
Johannes Doerfertecdf2632014-10-02 15:31:24 +000031/// '!n = metadata !{metadata !n, arg0, arg1}'
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000032///
Johannes Doerfertecdf2632014-10-02 15:31:24 +000033/// @return The self referencing id metadata node.
Tobias Grosserbd8f3c12014-12-09 22:02:16 +000034static MDNode *getID(LLVMContext &Ctx, Metadata *arg0 = nullptr,
35 Metadata *arg1 = nullptr) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000036 MDNode *ID;
Tobias Grosserbd8f3c12014-12-09 22:02:16 +000037 SmallVector<Metadata *, 3> Args;
David Peixottoa4817872014-11-07 21:44:18 +000038 // Use a temporary node to safely create a unique pointer for the first arg.
Duncan P. N. Exon Smithe566efe2015-01-19 21:31:48 +000039 auto TempNode = MDNode::getTemporary(Ctx, None);
David Peixottoa4817872014-11-07 21:44:18 +000040 // Reserve operand 0 for loop id self reference.
Duncan P. N. Exon Smithe566efe2015-01-19 21:31:48 +000041 Args.push_back(TempNode.get());
Johannes Doerfertecdf2632014-10-02 15:31:24 +000042
43 if (arg0)
44 Args.push_back(arg0);
45 if (arg1)
46 Args.push_back(arg1);
47
48 ID = MDNode::get(Ctx, Args);
49 ID->replaceOperandWith(0, ID);
50 return ID;
51}
52
Johannes Doerfert51d1c742014-10-02 15:32:17 +000053ScopAnnotator::ScopAnnotator() : SE(nullptr), AliasScopeDomain(nullptr) {}
Johannes Doerfertecdf2632014-10-02 15:31:24 +000054
Johannes Doerfert51d1c742014-10-02 15:32:17 +000055void ScopAnnotator::buildAliasScopes(Scop &S) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000056 SE = S.getSE();
57
58 LLVMContext &Ctx = SE->getContext();
59 AliasScopeDomain = getID(Ctx, MDString::get(Ctx, "polly.alias.scope.domain"));
60
61 AliasScopeMap.clear();
62 OtherAliasScopeListMap.clear();
63
Tobias Grosser4a07bbe2017-08-22 21:58:48 +000064 // We are only interested in arrays, but no scalar references. Scalars should
65 // be handled easily by basicaa.
66 SmallVector<ScopArrayInfo *, 10> Arrays;
67 for (ScopArrayInfo *Array : S.arrays())
68 if (Array->isArrayKind())
69 Arrays.push_back(Array);
70
Tobias Grosser696a1ee2017-04-03 07:42:50 +000071 // The construction of alias scopes is quadratic in the number of arrays
72 // involved. In case of too many arrays, skip the construction of alias
73 // information to avoid quadratic increases in compile time and code size.
Tobias Grosser4a07bbe2017-08-22 21:58:48 +000074 if (Arrays.size() > MaxArraysInAliasScops)
Tobias Grosser696a1ee2017-04-03 07:42:50 +000075 return;
76
Johannes Doerfertecdf2632014-10-02 15:31:24 +000077 std::string AliasScopeStr = "polly.alias.scope.";
Tobias Grosser4a07bbe2017-08-22 21:58:48 +000078 for (const ScopArrayInfo *Array : Arrays) {
Michael Kruse214deb72017-06-19 10:19:29 +000079 assert(Array->getBasePtr() && "Base pointer must be present");
Tobias Grosser45534632017-02-09 09:34:42 +000080 AliasScopeMap[Array->getBasePtr()] =
81 getID(Ctx, AliasScopeDomain,
82 MDString::get(Ctx, (AliasScopeStr + Array->getName()).c_str()));
Michael Kruse214deb72017-06-19 10:19:29 +000083 }
Johannes Doerfertecdf2632014-10-02 15:31:24 +000084
Tobias Grosser4a07bbe2017-08-22 21:58:48 +000085 for (const ScopArrayInfo *Array : Arrays) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000086 MDNode *AliasScopeList = MDNode::get(Ctx, {});
87 for (const auto &AliasScopePair : AliasScopeMap) {
Tobias Grosser45534632017-02-09 09:34:42 +000088 if (Array->getBasePtr() == AliasScopePair.first)
Johannes Doerfertecdf2632014-10-02 15:31:24 +000089 continue;
90
Tobias Grosserbd8f3c12014-12-09 22:02:16 +000091 Metadata *Args = {AliasScopePair.second};
Johannes Doerfertecdf2632014-10-02 15:31:24 +000092 AliasScopeList =
93 MDNode::concatenate(AliasScopeList, MDNode::get(Ctx, Args));
94 }
95
Tobias Grosser45534632017-02-09 09:34:42 +000096 OtherAliasScopeListMap[Array->getBasePtr()] = AliasScopeList;
Johannes Doerfertecdf2632014-10-02 15:31:24 +000097 }
Tobias Grosser37c9b8e2014-03-04 14:59:00 +000098}
99
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000100void ScopAnnotator::pushLoop(Loop *L, bool IsParallel) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000101
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000102 ActiveLoops.push_back(L);
103 if (!IsParallel)
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000104 return;
105
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000106 BasicBlock *Header = L->getHeader();
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000107 MDNode *Id = getID(Header->getContext());
Duncan P. N. Exon Smith16173b72014-12-07 21:12:10 +0000108 assert(Id->getOperand(0) == Id && "Expected Id to be a self-reference");
109 assert(Id->getNumOperands() == 1 && "Unexpected extra operands in Id");
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000110 MDNode *Ids = ParallelLoops.empty()
Duncan P. N. Exon Smith16173b72014-12-07 21:12:10 +0000111 ? Id
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000112 : MDNode::concatenate(ParallelLoops.back(), Id);
113 ParallelLoops.push_back(Ids);
114}
115
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000116void ScopAnnotator::popLoop(bool IsParallel) {
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000117 ActiveLoops.pop_back();
118 if (!IsParallel)
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000119 return;
120
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000121 assert(!ParallelLoops.empty() && "Expected a parallel loop to pop");
122 ParallelLoops.pop_back();
123}
124
Roman Gareev0956a602017-08-22 17:38:46 +0000125void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L, bool IsParallel,
126 bool IsLoopVectorizerDisabled) const {
127 MDNode *MData = nullptr;
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000128
Roman Gareev0956a602017-08-22 17:38:46 +0000129 if (IsLoopVectorizerDisabled) {
130 SmallVector<Metadata *, 3> Args;
131 LLVMContext &Ctx = SE->getContext();
132 Args.push_back(MDString::get(Ctx, "llvm.loop.vectorize.enable"));
133 auto *FalseValue = ConstantInt::get(Type::getInt1Ty(Ctx), 0);
134 Args.push_back(ValueAsMetadata::get(FalseValue));
135 MData = MDNode::concatenate(MData, getID(Ctx, MDNode::get(Ctx, Args)));
136 }
137
138 if (IsParallel) {
139 assert(!ParallelLoops.empty() && "Expected a parallel loop to annotate");
140 MDNode *Ids = ParallelLoops.back();
141 MDNode *Id = cast<MDNode>(Ids->getOperand(Ids->getNumOperands() - 1));
142 MData = MDNode::concatenate(MData, Id);
143 }
144
145 B->setMetadata("llvm.loop", MData);
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000146}
147
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000148/// Get the pointer operand
149///
150/// @param Inst The instruction to be analyzed.
151/// @return the pointer operand in case @p Inst is a memory access
152/// instruction and nullptr otherwise.
153static llvm::Value *getMemAccInstPointerOperand(Instruction *Inst) {
154 auto MemInst = MemAccInst::dyn_cast(Inst);
155 if (!MemInst)
156 return nullptr;
157
158 return MemInst.getPointerOperand();
159}
160
161void ScopAnnotator::annotateSecondLevel(llvm::Instruction *Inst,
162 llvm::Value *BasePtr) {
Roman Gareev1563f032017-08-08 16:50:28 +0000163 auto *PtrSCEV = SE->getSCEV(getMemAccInstPointerOperand(Inst));
164 auto *BasePtrSCEV = SE->getPointerBase(PtrSCEV);
165
166 if (!PtrSCEV)
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000167 return;
Roman Gareev1563f032017-08-08 16:50:28 +0000168 auto SecondLevelAliasScope = SecondLevelAliasScopeMap.lookup(PtrSCEV);
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000169 auto SecondLevelOtherAliasScopeList =
Roman Gareev1563f032017-08-08 16:50:28 +0000170 SecondLevelOtherAliasScopeListMap.lookup(PtrSCEV);
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000171 if (!SecondLevelAliasScope) {
172 auto AliasScope = AliasScopeMap.lookup(BasePtr);
173 if (!AliasScope)
174 return;
175 LLVMContext &Ctx = SE->getContext();
176 SecondLevelAliasScope = getID(
177 Ctx, AliasScope, MDString::get(Ctx, "second level alias metadata"));
Roman Gareev1563f032017-08-08 16:50:28 +0000178 SecondLevelAliasScopeMap[PtrSCEV] = SecondLevelAliasScope;
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000179 Metadata *Args = {SecondLevelAliasScope};
180 auto SecondLevelBasePtrAliasScopeList =
Roman Gareev1563f032017-08-08 16:50:28 +0000181 SecondLevelAliasScopeMap.lookup(BasePtrSCEV);
182 SecondLevelAliasScopeMap[BasePtrSCEV] = MDNode::concatenate(
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000183 SecondLevelBasePtrAliasScopeList, MDNode::get(Ctx, Args));
184 auto OtherAliasScopeList = OtherAliasScopeListMap.lookup(BasePtr);
185 SecondLevelOtherAliasScopeList = MDNode::concatenate(
186 OtherAliasScopeList, SecondLevelBasePtrAliasScopeList);
Roman Gareev1563f032017-08-08 16:50:28 +0000187 SecondLevelOtherAliasScopeListMap[PtrSCEV] = SecondLevelOtherAliasScopeList;
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000188 }
189 Inst->setMetadata("alias.scope", SecondLevelAliasScope);
190 Inst->setMetadata("noalias", SecondLevelOtherAliasScopeList);
191}
192
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000193void ScopAnnotator::annotate(Instruction *Inst) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000194 if (!Inst->mayReadOrWriteMemory())
195 return;
196
Tobias Grosser73725b82015-10-07 13:19:03 +0000197 if (!ParallelLoops.empty())
198 Inst->setMetadata("llvm.mem.parallel_loop_access", ParallelLoops.back());
199
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000200 // TODO: Use the ScopArrayInfo once available here.
Tobias Grosser73725b82015-10-07 13:19:03 +0000201 if (!AliasScopeDomain)
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000202 return;
203
Michael Kruse271deb12017-12-22 17:44:53 +0000204 // Do not apply annotations on memory operations that take more than one
205 // pointer. It would be ambiguous to which pointer the annotation applies.
206 // FIXME: How can we specify annotations for all pointer arguments?
207 if (isa<CallInst>(Inst) && !isa<MemSetInst>(Inst))
208 return;
209
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000210 auto *Ptr = getMemAccInstPointerOperand(Inst);
Johannes Doerferta7920982016-02-25 14:08:48 +0000211 if (!Ptr)
212 return;
213
214 auto *PtrSCEV = SE->getSCEV(Ptr);
Tobias Grosser73725b82015-10-07 13:19:03 +0000215 auto *BaseSCEV = SE->getPointerBase(PtrSCEV);
216 auto *SU = dyn_cast<SCEVUnknown>(BaseSCEV);
217
218 if (!SU)
219 return;
220
221 auto *BasePtr = SU->getValue();
222
223 if (!BasePtr)
224 return;
225
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000226 auto AliasScope = AliasScopeMap.lookup(BasePtr);
Tobias Grosser73725b82015-10-07 13:19:03 +0000227
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000228 if (!AliasScope) {
229 BasePtr = AlternativeAliasBases.lookup(BasePtr);
230 if (!BasePtr)
Tobias Grosserd79cb032015-10-07 13:19:06 +0000231 return;
Tobias Grosser73725b82015-10-07 13:19:03 +0000232
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000233 AliasScope = AliasScopeMap.lookup(BasePtr);
234 if (!AliasScope)
Tobias Grosserd79cb032015-10-07 13:19:06 +0000235 return;
236 }
237
Tobias Grosserd79cb032015-10-07 13:19:06 +0000238 assert(OtherAliasScopeListMap.count(BasePtr) &&
239 "BasePtr either expected in AliasScopeMap and OtherAlias...Map");
Tobias Grosser73725b82015-10-07 13:19:03 +0000240 auto *OtherAliasScopeList = OtherAliasScopeListMap[BasePtr];
241
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000242 if (InterIterationAliasFreeBasePtrs.count(BasePtr)) {
243 annotateSecondLevel(Inst, BasePtr);
244 return;
245 }
246
Tobias Grosser73725b82015-10-07 13:19:03 +0000247 Inst->setMetadata("alias.scope", AliasScope);
248 Inst->setMetadata("noalias", OtherAliasScopeList);
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000249}
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000250
251void ScopAnnotator::addInterIterationAliasFreeBasePtr(llvm::Value *BasePtr) {
252 if (!BasePtr)
253 return;
254
255 InterIterationAliasFreeBasePtrs.insert(BasePtr);
256}