blob: 4c94b9bae879938c5c9d7f2b4879bcf720d52f94 [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) {
Michael Kruse9f305372018-07-05 13:44:50 +0000163 Value *Ptr = getMemAccInstPointerOperand(Inst);
164 if (!Ptr)
165 return;
166
167 auto *PtrSCEV = SE->getSCEV(Ptr);
Roman Gareev1563f032017-08-08 16:50:28 +0000168 auto *BasePtrSCEV = SE->getPointerBase(PtrSCEV);
169
Roman Gareev1563f032017-08-08 16:50:28 +0000170 auto SecondLevelAliasScope = SecondLevelAliasScopeMap.lookup(PtrSCEV);
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000171 auto SecondLevelOtherAliasScopeList =
Roman Gareev1563f032017-08-08 16:50:28 +0000172 SecondLevelOtherAliasScopeListMap.lookup(PtrSCEV);
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000173 if (!SecondLevelAliasScope) {
174 auto AliasScope = AliasScopeMap.lookup(BasePtr);
175 if (!AliasScope)
176 return;
177 LLVMContext &Ctx = SE->getContext();
178 SecondLevelAliasScope = getID(
179 Ctx, AliasScope, MDString::get(Ctx, "second level alias metadata"));
Roman Gareev1563f032017-08-08 16:50:28 +0000180 SecondLevelAliasScopeMap[PtrSCEV] = SecondLevelAliasScope;
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000181 Metadata *Args = {SecondLevelAliasScope};
182 auto SecondLevelBasePtrAliasScopeList =
Roman Gareev1563f032017-08-08 16:50:28 +0000183 SecondLevelAliasScopeMap.lookup(BasePtrSCEV);
184 SecondLevelAliasScopeMap[BasePtrSCEV] = MDNode::concatenate(
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000185 SecondLevelBasePtrAliasScopeList, MDNode::get(Ctx, Args));
186 auto OtherAliasScopeList = OtherAliasScopeListMap.lookup(BasePtr);
187 SecondLevelOtherAliasScopeList = MDNode::concatenate(
188 OtherAliasScopeList, SecondLevelBasePtrAliasScopeList);
Roman Gareev1563f032017-08-08 16:50:28 +0000189 SecondLevelOtherAliasScopeListMap[PtrSCEV] = SecondLevelOtherAliasScopeList;
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000190 }
191 Inst->setMetadata("alias.scope", SecondLevelAliasScope);
192 Inst->setMetadata("noalias", SecondLevelOtherAliasScopeList);
193}
194
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000195void ScopAnnotator::annotate(Instruction *Inst) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000196 if (!Inst->mayReadOrWriteMemory())
197 return;
198
Tobias Grosser73725b82015-10-07 13:19:03 +0000199 if (!ParallelLoops.empty())
200 Inst->setMetadata("llvm.mem.parallel_loop_access", ParallelLoops.back());
201
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000202 // TODO: Use the ScopArrayInfo once available here.
Tobias Grosser73725b82015-10-07 13:19:03 +0000203 if (!AliasScopeDomain)
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000204 return;
205
Michael Kruse271deb12017-12-22 17:44:53 +0000206 // Do not apply annotations on memory operations that take more than one
207 // pointer. It would be ambiguous to which pointer the annotation applies.
208 // FIXME: How can we specify annotations for all pointer arguments?
209 if (isa<CallInst>(Inst) && !isa<MemSetInst>(Inst))
210 return;
211
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000212 auto *Ptr = getMemAccInstPointerOperand(Inst);
Johannes Doerferta7920982016-02-25 14:08:48 +0000213 if (!Ptr)
214 return;
215
216 auto *PtrSCEV = SE->getSCEV(Ptr);
Tobias Grosser73725b82015-10-07 13:19:03 +0000217 auto *BaseSCEV = SE->getPointerBase(PtrSCEV);
218 auto *SU = dyn_cast<SCEVUnknown>(BaseSCEV);
219
220 if (!SU)
221 return;
222
223 auto *BasePtr = SU->getValue();
224
225 if (!BasePtr)
226 return;
227
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000228 auto AliasScope = AliasScopeMap.lookup(BasePtr);
Tobias Grosser73725b82015-10-07 13:19:03 +0000229
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000230 if (!AliasScope) {
231 BasePtr = AlternativeAliasBases.lookup(BasePtr);
232 if (!BasePtr)
Tobias Grosserd79cb032015-10-07 13:19:06 +0000233 return;
Tobias Grosser73725b82015-10-07 13:19:03 +0000234
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000235 AliasScope = AliasScopeMap.lookup(BasePtr);
236 if (!AliasScope)
Tobias Grosserd79cb032015-10-07 13:19:06 +0000237 return;
238 }
239
Tobias Grosserd79cb032015-10-07 13:19:06 +0000240 assert(OtherAliasScopeListMap.count(BasePtr) &&
241 "BasePtr either expected in AliasScopeMap and OtherAlias...Map");
Tobias Grosser73725b82015-10-07 13:19:03 +0000242 auto *OtherAliasScopeList = OtherAliasScopeListMap[BasePtr];
243
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000244 if (InterIterationAliasFreeBasePtrs.count(BasePtr)) {
245 annotateSecondLevel(Inst, BasePtr);
246 return;
247 }
248
Tobias Grosser73725b82015-10-07 13:19:03 +0000249 Inst->setMetadata("alias.scope", AliasScope);
250 Inst->setMetadata("noalias", OtherAliasScopeList);
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000251}
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000252
253void ScopAnnotator::addInterIterationAliasFreeBasePtr(llvm::Value *BasePtr) {
254 if (!BasePtr)
255 return;
256
257 InterIterationAliasFreeBasePtrs.insert(BasePtr);
258}