137c9b8e0STobias Grosser //===------ PollyIRBuilder.cpp --------------------------------------------===//
237c9b8e0STobias Grosser //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
637c9b8e0STobias Grosser //
737c9b8e0STobias Grosser //===----------------------------------------------------------------------===//
837c9b8e0STobias Grosser //
937c9b8e0STobias Grosser // The Polly IRBuilder file contains Polly specific extensions for the IRBuilder
1037c9b8e0STobias Grosser // that are used e.g. to emit the llvm.loop.parallel metadata.
1137c9b8e0STobias Grosser //
1237c9b8e0STobias Grosser //===----------------------------------------------------------------------===//
1337c9b8e0STobias Grosser 
1437c9b8e0STobias Grosser #include "polly/CodeGen/IRBuilder.h"
15ecdf263cSJohannes Doerfert #include "polly/ScopInfo.h"
16ecdf263cSJohannes Doerfert #include "polly/Support/ScopHelper.h"
174a07bbe3STobias Grosser #include "llvm/ADT/SmallVector.h"
1837c9b8e0STobias Grosser #include "llvm/IR/Metadata.h"
1937c9b8e0STobias Grosser 
2037c9b8e0STobias Grosser using namespace llvm;
2137c9b8e0STobias Grosser using namespace polly;
2237c9b8e0STobias Grosser 
23696a1ee9STobias Grosser static const int MaxArraysInAliasScops = 10;
24696a1ee9STobias Grosser 
25c80d6979STobias Grosser /// Get a self referencing id metadata node.
26c7b719fcSJohannes Doerfert ///
27ecdf263cSJohannes Doerfert /// The MDNode looks like this (if arg0/arg1 are not null):
28c7b719fcSJohannes Doerfert ///
29d4c667c9SDuncan P. N. Exon Smith ///    '!n = distinct !{!n, arg0, arg1}'
30c7b719fcSJohannes Doerfert ///
31ecdf263cSJohannes Doerfert /// @return The self referencing id metadata node.
getID(LLVMContext & Ctx,Metadata * arg0=nullptr,Metadata * arg1=nullptr)32bd8f3c1fSTobias Grosser static MDNode *getID(LLVMContext &Ctx, Metadata *arg0 = nullptr,
33bd8f3c1fSTobias Grosser                      Metadata *arg1 = nullptr) {
34ecdf263cSJohannes Doerfert   MDNode *ID;
35bd8f3c1fSTobias Grosser   SmallVector<Metadata *, 3> Args;
36a4817871SDavid Peixotto   // Reserve operand 0 for loop id self reference.
37d4c667c9SDuncan P. N. Exon Smith   Args.push_back(nullptr);
38ecdf263cSJohannes Doerfert 
39ecdf263cSJohannes Doerfert   if (arg0)
40ecdf263cSJohannes Doerfert     Args.push_back(arg0);
41ecdf263cSJohannes Doerfert   if (arg1)
42ecdf263cSJohannes Doerfert     Args.push_back(arg1);
43ecdf263cSJohannes Doerfert 
44d4c667c9SDuncan P. N. Exon Smith   ID = MDNode::getDistinct(Ctx, Args);
45ecdf263cSJohannes Doerfert   ID->replaceOperandWith(0, ID);
46ecdf263cSJohannes Doerfert   return ID;
47ecdf263cSJohannes Doerfert }
48ecdf263cSJohannes Doerfert 
ScopAnnotator()493f170eb1SMichael Kruse ScopAnnotator::ScopAnnotator() : SE(nullptr), AliasScopeDomain(nullptr) {
503f170eb1SMichael Kruse   // Push an empty staging BandAttr.
513f170eb1SMichael Kruse   LoopAttrEnv.emplace_back();
523f170eb1SMichael Kruse }
533f170eb1SMichael Kruse 
~ScopAnnotator()543f170eb1SMichael Kruse ScopAnnotator::~ScopAnnotator() {
553f170eb1SMichael Kruse   assert(LoopAttrEnv.size() == 1 && "Loop stack imbalance");
563f170eb1SMichael Kruse   assert(!getStagingAttrEnv() && "Forgot to clear staging attr env");
573f170eb1SMichael Kruse }
58ecdf263cSJohannes Doerfert 
buildAliasScopes(Scop & S)5951d1c74dSJohannes Doerfert void ScopAnnotator::buildAliasScopes(Scop &S) {
60ecdf263cSJohannes Doerfert   SE = S.getSE();
61ecdf263cSJohannes Doerfert 
62ecdf263cSJohannes Doerfert   LLVMContext &Ctx = SE->getContext();
63ecdf263cSJohannes Doerfert   AliasScopeDomain = getID(Ctx, MDString::get(Ctx, "polly.alias.scope.domain"));
64ecdf263cSJohannes Doerfert 
65ecdf263cSJohannes Doerfert   AliasScopeMap.clear();
66ecdf263cSJohannes Doerfert   OtherAliasScopeListMap.clear();
67ecdf263cSJohannes Doerfert 
684a07bbe3STobias Grosser   // We are only interested in arrays, but no scalar references. Scalars should
694a07bbe3STobias Grosser   // be handled easily by basicaa.
704a07bbe3STobias Grosser   SmallVector<ScopArrayInfo *, 10> Arrays;
714a07bbe3STobias Grosser   for (ScopArrayInfo *Array : S.arrays())
724a07bbe3STobias Grosser     if (Array->isArrayKind())
734a07bbe3STobias Grosser       Arrays.push_back(Array);
744a07bbe3STobias Grosser 
75696a1ee9STobias Grosser   // The construction of alias scopes is quadratic in the number of arrays
76696a1ee9STobias Grosser   // involved. In case of too many arrays, skip the construction of alias
77696a1ee9STobias Grosser   // information to avoid quadratic increases in compile time and code size.
784a07bbe3STobias Grosser   if (Arrays.size() > MaxArraysInAliasScops)
79696a1ee9STobias Grosser     return;
80696a1ee9STobias Grosser 
81ecdf263cSJohannes Doerfert   std::string AliasScopeStr = "polly.alias.scope.";
824a07bbe3STobias Grosser   for (const ScopArrayInfo *Array : Arrays) {
83214deb79SMichael Kruse     assert(Array->getBasePtr() && "Base pointer must be present");
844553463bSTobias Grosser     AliasScopeMap[Array->getBasePtr()] =
854553463bSTobias Grosser         getID(Ctx, AliasScopeDomain,
864553463bSTobias Grosser               MDString::get(Ctx, (AliasScopeStr + Array->getName()).c_str()));
87214deb79SMichael Kruse   }
88ecdf263cSJohannes Doerfert 
894a07bbe3STobias Grosser   for (const ScopArrayInfo *Array : Arrays) {
90ecdf263cSJohannes Doerfert     MDNode *AliasScopeList = MDNode::get(Ctx, {});
91ecdf263cSJohannes Doerfert     for (const auto &AliasScopePair : AliasScopeMap) {
924553463bSTobias Grosser       if (Array->getBasePtr() == AliasScopePair.first)
93ecdf263cSJohannes Doerfert         continue;
94ecdf263cSJohannes Doerfert 
95bd8f3c1fSTobias Grosser       Metadata *Args = {AliasScopePair.second};
96ecdf263cSJohannes Doerfert       AliasScopeList =
97ecdf263cSJohannes Doerfert           MDNode::concatenate(AliasScopeList, MDNode::get(Ctx, Args));
98ecdf263cSJohannes Doerfert     }
99ecdf263cSJohannes Doerfert 
1004553463bSTobias Grosser     OtherAliasScopeListMap[Array->getBasePtr()] = AliasScopeList;
101ecdf263cSJohannes Doerfert   }
10237c9b8e0STobias Grosser }
10337c9b8e0STobias Grosser 
pushLoop(Loop * L,bool IsParallel)10451d1c74dSJohannes Doerfert void ScopAnnotator::pushLoop(Loop *L, bool IsParallel) {
105c7b719fcSJohannes Doerfert   ActiveLoops.push_back(L);
10637c9b8e0STobias Grosser 
107b85c98b4SMichael Kruse   if (IsParallel) {
108b85c98b4SMichael Kruse     LLVMContext &Ctx = SE->getContext();
109b85c98b4SMichael Kruse     MDNode *AccessGroup = MDNode::getDistinct(Ctx, {});
110b85c98b4SMichael Kruse     ParallelLoops.push_back(AccessGroup);
111b85c98b4SMichael Kruse   }
1123f170eb1SMichael Kruse 
1133f170eb1SMichael Kruse   // Open an empty BandAttr context for loops nested in this one.
1143f170eb1SMichael Kruse   LoopAttrEnv.emplace_back();
115c7b719fcSJohannes Doerfert }
116c7b719fcSJohannes Doerfert 
popLoop(bool IsParallel)11751d1c74dSJohannes Doerfert void ScopAnnotator::popLoop(bool IsParallel) {
118c7b719fcSJohannes Doerfert   ActiveLoops.pop_back();
11937c9b8e0STobias Grosser 
120b85c98b4SMichael Kruse   if (IsParallel) {
121c7b719fcSJohannes Doerfert     assert(!ParallelLoops.empty() && "Expected a parallel loop to pop");
122c7b719fcSJohannes Doerfert     ParallelLoops.pop_back();
12337c9b8e0STobias Grosser   }
1243f170eb1SMichael Kruse 
1253f170eb1SMichael Kruse   // Exit the subloop context.
1263f170eb1SMichael Kruse   assert(!getStagingAttrEnv() && "Forgot to clear staging attr env");
1273f170eb1SMichael Kruse   assert(LoopAttrEnv.size() >= 2 && "Popped too many");
1283f170eb1SMichael Kruse   LoopAttrEnv.pop_back();
129b85c98b4SMichael Kruse }
130c7b719fcSJohannes Doerfert 
annotateLoopLatch(BranchInst * B,Loop * L,bool IsParallel,bool IsLoopVectorizerDisabled) const1310956a606SRoman Gareev void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L, bool IsParallel,
1320956a606SRoman Gareev                                       bool IsLoopVectorizerDisabled) const {
133b85c98b4SMichael Kruse   LLVMContext &Ctx = SE->getContext();
134b85c98b4SMichael Kruse   SmallVector<Metadata *, 3> Args;
135b85c98b4SMichael Kruse 
136b85c98b4SMichael Kruse   // For the LoopID self-reference.
137b85c98b4SMichael Kruse   Args.push_back(nullptr);
138c7b719fcSJohannes Doerfert 
1393f170eb1SMichael Kruse   // Add the user-defined loop properties to the annotation, if any. Any
1403f170eb1SMichael Kruse   // additional properties are appended.
1413f170eb1SMichael Kruse   // FIXME: What to do if these conflict?
1423f170eb1SMichael Kruse   MDNode *MData = nullptr;
1433f170eb1SMichael Kruse   if (BandAttr *AttrEnv = getActiveAttrEnv()) {
1443f170eb1SMichael Kruse     MData = AttrEnv->Metadata;
1453f170eb1SMichael Kruse     if (MData)
1463f170eb1SMichael Kruse       llvm::append_range(Args, drop_begin(MData->operands(), 1));
1473f170eb1SMichael Kruse   }
1483f170eb1SMichael Kruse 
1490956a606SRoman Gareev   if (IsLoopVectorizerDisabled) {
150b85c98b4SMichael Kruse     MDString *PropName = MDString::get(Ctx, "llvm.loop.vectorize.enable");
151b85c98b4SMichael Kruse     ConstantInt *FalseValue = ConstantInt::get(Type::getInt1Ty(Ctx), 0);
152b85c98b4SMichael Kruse     ValueAsMetadata *PropValue = ValueAsMetadata::get(FalseValue);
153b85c98b4SMichael Kruse     Args.push_back(MDNode::get(Ctx, {PropName, PropValue}));
1540956a606SRoman Gareev   }
1550956a606SRoman Gareev 
1560956a606SRoman Gareev   if (IsParallel) {
157b85c98b4SMichael Kruse     MDString *PropName = MDString::get(Ctx, "llvm.loop.parallel_accesses");
158b85c98b4SMichael Kruse     MDNode *AccGroup = ParallelLoops.back();
159b85c98b4SMichael Kruse     Args.push_back(MDNode::get(Ctx, {PropName, AccGroup}));
1600956a606SRoman Gareev   }
1610956a606SRoman Gareev 
162b85c98b4SMichael Kruse   // No metadata to annotate.
1633f170eb1SMichael Kruse   if (!MData && Args.size() <= 1)
164b85c98b4SMichael Kruse     return;
165b85c98b4SMichael Kruse 
1663f170eb1SMichael Kruse   // Reuse the MData node if possible, this will avoid having to create another
1673f170eb1SMichael Kruse   // one that cannot be merged because LoopIDs are 'distinct'. However, we have
1683f170eb1SMichael Kruse   // to create a new one if we add properties.
1693f170eb1SMichael Kruse   if (!MData || Args.size() > MData->getNumOperands()) {
1703f170eb1SMichael Kruse     MData = MDNode::getDistinct(Ctx, Args);
171b85c98b4SMichael Kruse     MData->replaceOperandWith(0, MData);
1723f170eb1SMichael Kruse   }
173b85c98b4SMichael Kruse   B->setMetadata(LLVMContext::MD_loop, MData);
17437c9b8e0STobias Grosser }
175c7b719fcSJohannes Doerfert 
176cdfb57dcSRoman Gareev /// Get the pointer operand
177cdfb57dcSRoman Gareev ///
178cdfb57dcSRoman Gareev /// @param Inst The instruction to be analyzed.
179cdfb57dcSRoman Gareev /// @return the pointer operand in case @p Inst is a memory access
180cdfb57dcSRoman Gareev ///         instruction and nullptr otherwise.
getMemAccInstPointerOperand(Instruction * Inst)181cdfb57dcSRoman Gareev static llvm::Value *getMemAccInstPointerOperand(Instruction *Inst) {
182cdfb57dcSRoman Gareev   auto MemInst = MemAccInst::dyn_cast(Inst);
183cdfb57dcSRoman Gareev   if (!MemInst)
184cdfb57dcSRoman Gareev     return nullptr;
185cdfb57dcSRoman Gareev 
186cdfb57dcSRoman Gareev   return MemInst.getPointerOperand();
187cdfb57dcSRoman Gareev }
188cdfb57dcSRoman Gareev 
1896249bfeeSMichael Kruse /// Find the base pointer of an array access.
1906249bfeeSMichael Kruse ///
1916249bfeeSMichael Kruse /// This should be equivalent to ScalarEvolution::getPointerBase, which we
1926249bfeeSMichael Kruse /// cannot use here the IR is still under construction which ScalarEvolution
1936249bfeeSMichael Kruse /// assumes to not be modified.
findBasePtr(Value * Val)1946249bfeeSMichael Kruse static Value *findBasePtr(Value *Val) {
1956249bfeeSMichael Kruse   while (true) {
1966249bfeeSMichael Kruse     if (auto *Gep = dyn_cast<GEPOperator>(Val)) {
1976249bfeeSMichael Kruse       Val = Gep->getPointerOperand();
1986249bfeeSMichael Kruse       continue;
1996249bfeeSMichael Kruse     }
2006249bfeeSMichael Kruse     if (auto *Cast = dyn_cast<BitCastOperator>(Val)) {
2016249bfeeSMichael Kruse       Val = Cast->getOperand(0);
2026249bfeeSMichael Kruse       continue;
2036249bfeeSMichael Kruse     }
2046249bfeeSMichael Kruse 
2056249bfeeSMichael Kruse     break;
2066249bfeeSMichael Kruse   }
2076249bfeeSMichael Kruse 
2086249bfeeSMichael Kruse   return Val;
2096249bfeeSMichael Kruse }
2106249bfeeSMichael Kruse 
annotate(Instruction * Inst)21151d1c74dSJohannes Doerfert void ScopAnnotator::annotate(Instruction *Inst) {
212ecdf263cSJohannes Doerfert   if (!Inst->mayReadOrWriteMemory())
213ecdf263cSJohannes Doerfert     return;
214ecdf263cSJohannes Doerfert 
215b85c98b4SMichael Kruse   switch (ParallelLoops.size()) {
216b85c98b4SMichael Kruse   case 0:
217b85c98b4SMichael Kruse     // Not parallel to anything: no access group needed.
218b85c98b4SMichael Kruse     break;
219b85c98b4SMichael Kruse   case 1:
220b85c98b4SMichael Kruse     // Single parallel loop: use directly.
221b85c98b4SMichael Kruse     Inst->setMetadata(LLVMContext::MD_access_group,
222b85c98b4SMichael Kruse                       cast<MDNode>(ParallelLoops.front()));
223b85c98b4SMichael Kruse     break;
224b85c98b4SMichael Kruse   default:
225b85c98b4SMichael Kruse     // Parallel to multiple loops: refer to list of access groups.
226b85c98b4SMichael Kruse     Inst->setMetadata(LLVMContext::MD_access_group,
227b85c98b4SMichael Kruse                       MDNode::get(SE->getContext(),
228b85c98b4SMichael Kruse                                   ArrayRef<Metadata *>(
229b85c98b4SMichael Kruse                                       (Metadata *const *)ParallelLoops.data(),
230b85c98b4SMichael Kruse                                       ParallelLoops.size())));
231b85c98b4SMichael Kruse     break;
232b85c98b4SMichael Kruse   }
233ecdf263cSJohannes Doerfert 
23473725b8bSTobias Grosser   // TODO: Use the ScopArrayInfo once available here.
23573725b8bSTobias Grosser   if (!AliasScopeDomain)
23673725b8bSTobias Grosser     return;
23773725b8bSTobias Grosser 
238271deb17SMichael Kruse   // Do not apply annotations on memory operations that take more than one
239271deb17SMichael Kruse   // pointer. It would be ambiguous to which pointer the annotation applies.
240271deb17SMichael Kruse   // FIXME: How can we specify annotations for all pointer arguments?
241271deb17SMichael Kruse   if (isa<CallInst>(Inst) && !isa<MemSetInst>(Inst))
242271deb17SMichael Kruse     return;
243271deb17SMichael Kruse 
244cdfb57dcSRoman Gareev   auto *Ptr = getMemAccInstPointerOperand(Inst);
245a7920980SJohannes Doerfert   if (!Ptr)
246a7920980SJohannes Doerfert     return;
247a7920980SJohannes Doerfert 
2486249bfeeSMichael Kruse   Value *BasePtr = findBasePtr(Ptr);
24973725b8bSTobias Grosser   if (!BasePtr)
25073725b8bSTobias Grosser     return;
25173725b8bSTobias Grosser 
2526bab9f80STobias Grosser   auto AliasScope = AliasScopeMap.lookup(BasePtr);
253b0da42fbSTobias Grosser 
2546bab9f80STobias Grosser   if (!AliasScope) {
2556bab9f80STobias Grosser     BasePtr = AlternativeAliasBases.lookup(BasePtr);
2566bab9f80STobias Grosser     if (!BasePtr)
257d79cb037STobias Grosser       return;
258b0da42fbSTobias Grosser 
2596bab9f80STobias Grosser     AliasScope = AliasScopeMap.lookup(BasePtr);
2606bab9f80STobias Grosser     if (!AliasScope)
261d79cb037STobias Grosser       return;
262d79cb037STobias Grosser   }
263d79cb037STobias Grosser 
264d79cb037STobias Grosser   assert(OtherAliasScopeListMap.count(BasePtr) &&
265d79cb037STobias Grosser          "BasePtr either expected in AliasScopeMap and OtherAlias...Map");
266b0da42fbSTobias Grosser   auto *OtherAliasScopeList = OtherAliasScopeListMap[BasePtr];
267b0da42fbSTobias Grosser 
268*53720f74SNikita Popov   Inst->setMetadata("alias.scope", MDNode::get(SE->getContext(), AliasScope));
269b0da42fbSTobias Grosser   Inst->setMetadata("noalias", OtherAliasScopeList);
270ecdf263cSJohannes Doerfert }
271