blob: 1ad01a4a98b63d70d0f7fbf8f5f1617a1889fb77 [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 Grosser37c9b8e2014-03-04 14:59:00 +000018#include "llvm/IR/Metadata.h"
19#include "llvm/Support/Debug.h"
20
21using namespace llvm;
22using namespace polly;
23
Tobias Grosser696a1ee2017-04-03 07:42:50 +000024static const int MaxArraysInAliasScops = 10;
25
Tobias Grosserc80d6972016-09-02 06:33:33 +000026/// Get a self referencing id metadata node.
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000027///
Johannes Doerfertecdf2632014-10-02 15:31:24 +000028/// The MDNode looks like this (if arg0/arg1 are not null):
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000029///
Johannes Doerfertecdf2632014-10-02 15:31:24 +000030/// '!n = metadata !{metadata !n, arg0, arg1}'
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000031///
Johannes Doerfertecdf2632014-10-02 15:31:24 +000032/// @return The self referencing id metadata node.
Tobias Grosserbd8f3c12014-12-09 22:02:16 +000033static MDNode *getID(LLVMContext &Ctx, Metadata *arg0 = nullptr,
34 Metadata *arg1 = nullptr) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000035 MDNode *ID;
Tobias Grosserbd8f3c12014-12-09 22:02:16 +000036 SmallVector<Metadata *, 3> Args;
David Peixottoa4817872014-11-07 21:44:18 +000037 // Use a temporary node to safely create a unique pointer for the first arg.
Duncan P. N. Exon Smithe566efe2015-01-19 21:31:48 +000038 auto TempNode = MDNode::getTemporary(Ctx, None);
David Peixottoa4817872014-11-07 21:44:18 +000039 // Reserve operand 0 for loop id self reference.
Duncan P. N. Exon Smithe566efe2015-01-19 21:31:48 +000040 Args.push_back(TempNode.get());
Johannes Doerfertecdf2632014-10-02 15:31:24 +000041
42 if (arg0)
43 Args.push_back(arg0);
44 if (arg1)
45 Args.push_back(arg1);
46
47 ID = MDNode::get(Ctx, Args);
48 ID->replaceOperandWith(0, ID);
49 return ID;
50}
51
Johannes Doerfert51d1c742014-10-02 15:32:17 +000052ScopAnnotator::ScopAnnotator() : SE(nullptr), AliasScopeDomain(nullptr) {}
Johannes Doerfertecdf2632014-10-02 15:31:24 +000053
Johannes Doerfert51d1c742014-10-02 15:32:17 +000054void ScopAnnotator::buildAliasScopes(Scop &S) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000055 SE = S.getSE();
56
57 LLVMContext &Ctx = SE->getContext();
58 AliasScopeDomain = getID(Ctx, MDString::get(Ctx, "polly.alias.scope.domain"));
59
60 AliasScopeMap.clear();
61 OtherAliasScopeListMap.clear();
62
Tobias Grosser696a1ee2017-04-03 07:42:50 +000063 // The construction of alias scopes is quadratic in the number of arrays
64 // involved. In case of too many arrays, skip the construction of alias
65 // information to avoid quadratic increases in compile time and code size.
66 if (std::distance(S.array_begin(), S.array_end()) > MaxArraysInAliasScops)
67 return;
68
Johannes Doerfertecdf2632014-10-02 15:31:24 +000069 std::string AliasScopeStr = "polly.alias.scope.";
Michael Kruse214deb72017-06-19 10:19:29 +000070 for (const ScopArrayInfo *Array : S.arrays()) {
71 assert(Array->getBasePtr() && "Base pointer must be present");
Tobias Grosser45534632017-02-09 09:34:42 +000072 AliasScopeMap[Array->getBasePtr()] =
73 getID(Ctx, AliasScopeDomain,
74 MDString::get(Ctx, (AliasScopeStr + Array->getName()).c_str()));
Michael Kruse214deb72017-06-19 10:19:29 +000075 }
Johannes Doerfertecdf2632014-10-02 15:31:24 +000076
Tobias Grosser45534632017-02-09 09:34:42 +000077 for (const ScopArrayInfo *Array : S.arrays()) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000078 MDNode *AliasScopeList = MDNode::get(Ctx, {});
79 for (const auto &AliasScopePair : AliasScopeMap) {
Tobias Grosser45534632017-02-09 09:34:42 +000080 if (Array->getBasePtr() == AliasScopePair.first)
Johannes Doerfertecdf2632014-10-02 15:31:24 +000081 continue;
82
Tobias Grosserbd8f3c12014-12-09 22:02:16 +000083 Metadata *Args = {AliasScopePair.second};
Johannes Doerfertecdf2632014-10-02 15:31:24 +000084 AliasScopeList =
85 MDNode::concatenate(AliasScopeList, MDNode::get(Ctx, Args));
86 }
87
Tobias Grosser45534632017-02-09 09:34:42 +000088 OtherAliasScopeListMap[Array->getBasePtr()] = AliasScopeList;
Johannes Doerfertecdf2632014-10-02 15:31:24 +000089 }
Tobias Grosser37c9b8e2014-03-04 14:59:00 +000090}
91
Johannes Doerfert51d1c742014-10-02 15:32:17 +000092void ScopAnnotator::pushLoop(Loop *L, bool IsParallel) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000093
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000094 ActiveLoops.push_back(L);
95 if (!IsParallel)
Tobias Grosser37c9b8e2014-03-04 14:59:00 +000096 return;
97
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000098 BasicBlock *Header = L->getHeader();
Johannes Doerfertecdf2632014-10-02 15:31:24 +000099 MDNode *Id = getID(Header->getContext());
Duncan P. N. Exon Smith16173b72014-12-07 21:12:10 +0000100 assert(Id->getOperand(0) == Id && "Expected Id to be a self-reference");
101 assert(Id->getNumOperands() == 1 && "Unexpected extra operands in Id");
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000102 MDNode *Ids = ParallelLoops.empty()
Duncan P. N. Exon Smith16173b72014-12-07 21:12:10 +0000103 ? Id
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000104 : MDNode::concatenate(ParallelLoops.back(), Id);
105 ParallelLoops.push_back(Ids);
106}
107
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000108void ScopAnnotator::popLoop(bool IsParallel) {
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000109 ActiveLoops.pop_back();
110 if (!IsParallel)
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000111 return;
112
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000113 assert(!ParallelLoops.empty() && "Expected a parallel loop to pop");
114 ParallelLoops.pop_back();
115}
116
Roman Gareev0956a602017-08-22 17:38:46 +0000117void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L, bool IsParallel,
118 bool IsLoopVectorizerDisabled) const {
119 MDNode *MData = nullptr;
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000120
Roman Gareev0956a602017-08-22 17:38:46 +0000121 if (IsLoopVectorizerDisabled) {
122 SmallVector<Metadata *, 3> Args;
123 LLVMContext &Ctx = SE->getContext();
124 Args.push_back(MDString::get(Ctx, "llvm.loop.vectorize.enable"));
125 auto *FalseValue = ConstantInt::get(Type::getInt1Ty(Ctx), 0);
126 Args.push_back(ValueAsMetadata::get(FalseValue));
127 MData = MDNode::concatenate(MData, getID(Ctx, MDNode::get(Ctx, Args)));
128 }
129
130 if (IsParallel) {
131 assert(!ParallelLoops.empty() && "Expected a parallel loop to annotate");
132 MDNode *Ids = ParallelLoops.back();
133 MDNode *Id = cast<MDNode>(Ids->getOperand(Ids->getNumOperands() - 1));
134 MData = MDNode::concatenate(MData, Id);
135 }
136
137 B->setMetadata("llvm.loop", MData);
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000138}
139
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000140/// Get the pointer operand
141///
142/// @param Inst The instruction to be analyzed.
143/// @return the pointer operand in case @p Inst is a memory access
144/// instruction and nullptr otherwise.
145static llvm::Value *getMemAccInstPointerOperand(Instruction *Inst) {
146 auto MemInst = MemAccInst::dyn_cast(Inst);
147 if (!MemInst)
148 return nullptr;
149
150 return MemInst.getPointerOperand();
151}
152
153void ScopAnnotator::annotateSecondLevel(llvm::Instruction *Inst,
154 llvm::Value *BasePtr) {
Roman Gareev1563f032017-08-08 16:50:28 +0000155 auto *PtrSCEV = SE->getSCEV(getMemAccInstPointerOperand(Inst));
156 auto *BasePtrSCEV = SE->getPointerBase(PtrSCEV);
157
158 if (!PtrSCEV)
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000159 return;
Roman Gareev1563f032017-08-08 16:50:28 +0000160 auto SecondLevelAliasScope = SecondLevelAliasScopeMap.lookup(PtrSCEV);
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000161 auto SecondLevelOtherAliasScopeList =
Roman Gareev1563f032017-08-08 16:50:28 +0000162 SecondLevelOtherAliasScopeListMap.lookup(PtrSCEV);
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000163 if (!SecondLevelAliasScope) {
164 auto AliasScope = AliasScopeMap.lookup(BasePtr);
165 if (!AliasScope)
166 return;
167 LLVMContext &Ctx = SE->getContext();
168 SecondLevelAliasScope = getID(
169 Ctx, AliasScope, MDString::get(Ctx, "second level alias metadata"));
Roman Gareev1563f032017-08-08 16:50:28 +0000170 SecondLevelAliasScopeMap[PtrSCEV] = SecondLevelAliasScope;
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000171 Metadata *Args = {SecondLevelAliasScope};
172 auto SecondLevelBasePtrAliasScopeList =
Roman Gareev1563f032017-08-08 16:50:28 +0000173 SecondLevelAliasScopeMap.lookup(BasePtrSCEV);
174 SecondLevelAliasScopeMap[BasePtrSCEV] = MDNode::concatenate(
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000175 SecondLevelBasePtrAliasScopeList, MDNode::get(Ctx, Args));
176 auto OtherAliasScopeList = OtherAliasScopeListMap.lookup(BasePtr);
177 SecondLevelOtherAliasScopeList = MDNode::concatenate(
178 OtherAliasScopeList, SecondLevelBasePtrAliasScopeList);
Roman Gareev1563f032017-08-08 16:50:28 +0000179 SecondLevelOtherAliasScopeListMap[PtrSCEV] = SecondLevelOtherAliasScopeList;
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000180 }
181 Inst->setMetadata("alias.scope", SecondLevelAliasScope);
182 Inst->setMetadata("noalias", SecondLevelOtherAliasScopeList);
183}
184
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000185void ScopAnnotator::annotate(Instruction *Inst) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000186 if (!Inst->mayReadOrWriteMemory())
187 return;
188
Tobias Grosser73725b82015-10-07 13:19:03 +0000189 if (!ParallelLoops.empty())
190 Inst->setMetadata("llvm.mem.parallel_loop_access", ParallelLoops.back());
191
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000192 // TODO: Use the ScopArrayInfo once available here.
Tobias Grosser73725b82015-10-07 13:19:03 +0000193 if (!AliasScopeDomain)
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000194 return;
195
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000196 auto *Ptr = getMemAccInstPointerOperand(Inst);
Johannes Doerferta7920982016-02-25 14:08:48 +0000197 if (!Ptr)
198 return;
199
200 auto *PtrSCEV = SE->getSCEV(Ptr);
Tobias Grosser73725b82015-10-07 13:19:03 +0000201 auto *BaseSCEV = SE->getPointerBase(PtrSCEV);
202 auto *SU = dyn_cast<SCEVUnknown>(BaseSCEV);
203
204 if (!SU)
205 return;
206
207 auto *BasePtr = SU->getValue();
208
209 if (!BasePtr)
210 return;
211
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000212 auto AliasScope = AliasScopeMap.lookup(BasePtr);
Tobias Grosser73725b82015-10-07 13:19:03 +0000213
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000214 if (!AliasScope) {
215 BasePtr = AlternativeAliasBases.lookup(BasePtr);
216 if (!BasePtr)
Tobias Grosserd79cb032015-10-07 13:19:06 +0000217 return;
Tobias Grosser73725b82015-10-07 13:19:03 +0000218
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000219 AliasScope = AliasScopeMap.lookup(BasePtr);
220 if (!AliasScope)
Tobias Grosserd79cb032015-10-07 13:19:06 +0000221 return;
222 }
223
Tobias Grosserd79cb032015-10-07 13:19:06 +0000224 assert(OtherAliasScopeListMap.count(BasePtr) &&
225 "BasePtr either expected in AliasScopeMap and OtherAlias...Map");
Tobias Grosser73725b82015-10-07 13:19:03 +0000226 auto *OtherAliasScopeList = OtherAliasScopeListMap[BasePtr];
227
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000228 if (InterIterationAliasFreeBasePtrs.count(BasePtr)) {
229 annotateSecondLevel(Inst, BasePtr);
230 return;
231 }
232
Tobias Grosser73725b82015-10-07 13:19:03 +0000233 Inst->setMetadata("alias.scope", AliasScope);
234 Inst->setMetadata("noalias", OtherAliasScopeList);
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000235}
Roman Gareevcdfb57d2017-03-22 14:25:24 +0000236
237void ScopAnnotator::addInterIterationAliasFreeBasePtr(llvm::Value *BasePtr) {
238 if (!BasePtr)
239 return;
240
241 InterIterationAliasFreeBasePtrs.insert(BasePtr);
242}