[PowerPC][NFC] Cleanup PPCCTRLoopsVerify pass
[llvm-project.git] / polly / lib / CodeGen / IRBuilder.cpp
blob001a907a834f2efbcc430a7259b75536689f812a
1 //===------ PollyIRBuilder.cpp --------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // The Polly IRBuilder file contains Polly specific extensions for the IRBuilder
10 // that are used e.g. to emit the llvm.loop.parallel metadata.
12 //===----------------------------------------------------------------------===//
14 #include "polly/CodeGen/IRBuilder.h"
15 #include "polly/ScopInfo.h"
16 #include "polly/Support/ScopHelper.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/IR/Metadata.h"
20 using namespace llvm;
21 using namespace polly;
23 static const int MaxArraysInAliasScops = 10;
25 /// Get a self referencing id metadata node.
26 ///
27 /// The MDNode looks like this (if arg0/arg1 are not null):
28 ///
29 /// '!n = distinct !{!n, arg0, arg1}'
30 ///
31 /// @return The self referencing id metadata node.
32 static MDNode *getID(LLVMContext &Ctx, Metadata *arg0 = nullptr,
33 Metadata *arg1 = nullptr) {
34 MDNode *ID;
35 SmallVector<Metadata *, 3> Args;
36 // Reserve operand 0 for loop id self reference.
37 Args.push_back(nullptr);
39 if (arg0)
40 Args.push_back(arg0);
41 if (arg1)
42 Args.push_back(arg1);
44 ID = MDNode::getDistinct(Ctx, Args);
45 ID->replaceOperandWith(0, ID);
46 return ID;
49 ScopAnnotator::ScopAnnotator() : SE(nullptr), AliasScopeDomain(nullptr) {}
51 void ScopAnnotator::buildAliasScopes(Scop &S) {
52 SE = S.getSE();
54 LLVMContext &Ctx = SE->getContext();
55 AliasScopeDomain = getID(Ctx, MDString::get(Ctx, "polly.alias.scope.domain"));
57 AliasScopeMap.clear();
58 OtherAliasScopeListMap.clear();
60 // We are only interested in arrays, but no scalar references. Scalars should
61 // be handled easily by basicaa.
62 SmallVector<ScopArrayInfo *, 10> Arrays;
63 for (ScopArrayInfo *Array : S.arrays())
64 if (Array->isArrayKind())
65 Arrays.push_back(Array);
67 // The construction of alias scopes is quadratic in the number of arrays
68 // involved. In case of too many arrays, skip the construction of alias
69 // information to avoid quadratic increases in compile time and code size.
70 if (Arrays.size() > MaxArraysInAliasScops)
71 return;
73 std::string AliasScopeStr = "polly.alias.scope.";
74 for (const ScopArrayInfo *Array : Arrays) {
75 assert(Array->getBasePtr() && "Base pointer must be present");
76 AliasScopeMap[Array->getBasePtr()] =
77 getID(Ctx, AliasScopeDomain,
78 MDString::get(Ctx, (AliasScopeStr + Array->getName()).c_str()));
81 for (const ScopArrayInfo *Array : Arrays) {
82 MDNode *AliasScopeList = MDNode::get(Ctx, {});
83 for (const auto &AliasScopePair : AliasScopeMap) {
84 if (Array->getBasePtr() == AliasScopePair.first)
85 continue;
87 Metadata *Args = {AliasScopePair.second};
88 AliasScopeList =
89 MDNode::concatenate(AliasScopeList, MDNode::get(Ctx, Args));
92 OtherAliasScopeListMap[Array->getBasePtr()] = AliasScopeList;
96 void ScopAnnotator::pushLoop(Loop *L, bool IsParallel) {
98 ActiveLoops.push_back(L);
99 if (!IsParallel)
100 return;
102 BasicBlock *Header = L->getHeader();
103 MDNode *Id = getID(Header->getContext());
104 assert(Id->getOperand(0) == Id && "Expected Id to be a self-reference");
105 assert(Id->getNumOperands() == 1 && "Unexpected extra operands in Id");
106 MDNode *Ids = ParallelLoops.empty()
107 ? Id
108 : MDNode::concatenate(ParallelLoops.back(), Id);
109 ParallelLoops.push_back(Ids);
112 void ScopAnnotator::popLoop(bool IsParallel) {
113 ActiveLoops.pop_back();
114 if (!IsParallel)
115 return;
117 assert(!ParallelLoops.empty() && "Expected a parallel loop to pop");
118 ParallelLoops.pop_back();
121 void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L, bool IsParallel,
122 bool IsLoopVectorizerDisabled) const {
123 MDNode *MData = nullptr;
125 if (IsLoopVectorizerDisabled) {
126 SmallVector<Metadata *, 3> Args;
127 LLVMContext &Ctx = SE->getContext();
128 Args.push_back(MDString::get(Ctx, "llvm.loop.vectorize.enable"));
129 auto *FalseValue = ConstantInt::get(Type::getInt1Ty(Ctx), 0);
130 Args.push_back(ValueAsMetadata::get(FalseValue));
131 MData = MDNode::concatenate(MData, getID(Ctx, MDNode::get(Ctx, Args)));
134 if (IsParallel) {
135 assert(!ParallelLoops.empty() && "Expected a parallel loop to annotate");
136 MDNode *Ids = ParallelLoops.back();
137 MDNode *Id = cast<MDNode>(Ids->getOperand(Ids->getNumOperands() - 1));
138 MData = MDNode::concatenate(MData, Id);
141 B->setMetadata("llvm.loop", MData);
144 /// Get the pointer operand
146 /// @param Inst The instruction to be analyzed.
147 /// @return the pointer operand in case @p Inst is a memory access
148 /// instruction and nullptr otherwise.
149 static llvm::Value *getMemAccInstPointerOperand(Instruction *Inst) {
150 auto MemInst = MemAccInst::dyn_cast(Inst);
151 if (!MemInst)
152 return nullptr;
154 return MemInst.getPointerOperand();
157 void ScopAnnotator::annotateSecondLevel(llvm::Instruction *Inst,
158 llvm::Value *BasePtr) {
159 Value *Ptr = getMemAccInstPointerOperand(Inst);
160 if (!Ptr)
161 return;
163 auto *PtrSCEV = SE->getSCEV(Ptr);
164 auto *BasePtrSCEV = SE->getPointerBase(PtrSCEV);
166 auto SecondLevelAliasScope = SecondLevelAliasScopeMap.lookup(PtrSCEV);
167 auto SecondLevelOtherAliasScopeList =
168 SecondLevelOtherAliasScopeListMap.lookup(PtrSCEV);
169 if (!SecondLevelAliasScope) {
170 auto AliasScope = AliasScopeMap.lookup(BasePtr);
171 if (!AliasScope)
172 return;
173 LLVMContext &Ctx = SE->getContext();
174 SecondLevelAliasScope = getID(
175 Ctx, AliasScope, MDString::get(Ctx, "second level alias metadata"));
176 SecondLevelAliasScopeMap[PtrSCEV] = SecondLevelAliasScope;
177 Metadata *Args = {SecondLevelAliasScope};
178 auto SecondLevelBasePtrAliasScopeList =
179 SecondLevelAliasScopeMap.lookup(BasePtrSCEV);
180 SecondLevelAliasScopeMap[BasePtrSCEV] = MDNode::concatenate(
181 SecondLevelBasePtrAliasScopeList, MDNode::get(Ctx, Args));
182 auto OtherAliasScopeList = OtherAliasScopeListMap.lookup(BasePtr);
183 SecondLevelOtherAliasScopeList = MDNode::concatenate(
184 OtherAliasScopeList, SecondLevelBasePtrAliasScopeList);
185 SecondLevelOtherAliasScopeListMap[PtrSCEV] = SecondLevelOtherAliasScopeList;
187 Inst->setMetadata("alias.scope", SecondLevelAliasScope);
188 Inst->setMetadata("noalias", SecondLevelOtherAliasScopeList);
191 /// Find the base pointer of an array access.
193 /// This should be equivalent to ScalarEvolution::getPointerBase, which we
194 /// cannot use here the IR is still under construction which ScalarEvolution
195 /// assumes to not be modified.
196 static Value *findBasePtr(Value *Val) {
197 while (true) {
198 if (auto *Gep = dyn_cast<GEPOperator>(Val)) {
199 Val = Gep->getPointerOperand();
200 continue;
202 if (auto *Cast = dyn_cast<BitCastOperator>(Val)) {
203 Val = Cast->getOperand(0);
204 continue;
207 break;
210 return Val;
213 void ScopAnnotator::annotate(Instruction *Inst) {
214 if (!Inst->mayReadOrWriteMemory())
215 return;
217 if (!ParallelLoops.empty())
218 Inst->setMetadata("llvm.mem.parallel_loop_access", ParallelLoops.back());
220 // TODO: Use the ScopArrayInfo once available here.
221 if (!AliasScopeDomain)
222 return;
224 // Do not apply annotations on memory operations that take more than one
225 // pointer. It would be ambiguous to which pointer the annotation applies.
226 // FIXME: How can we specify annotations for all pointer arguments?
227 if (isa<CallInst>(Inst) && !isa<MemSetInst>(Inst))
228 return;
230 auto *Ptr = getMemAccInstPointerOperand(Inst);
231 if (!Ptr)
232 return;
234 Value *BasePtr = findBasePtr(Ptr);
235 if (!BasePtr)
236 return;
238 auto AliasScope = AliasScopeMap.lookup(BasePtr);
240 if (!AliasScope) {
241 BasePtr = AlternativeAliasBases.lookup(BasePtr);
242 if (!BasePtr)
243 return;
245 AliasScope = AliasScopeMap.lookup(BasePtr);
246 if (!AliasScope)
247 return;
250 assert(OtherAliasScopeListMap.count(BasePtr) &&
251 "BasePtr either expected in AliasScopeMap and OtherAlias...Map");
252 auto *OtherAliasScopeList = OtherAliasScopeListMap[BasePtr];
254 if (InterIterationAliasFreeBasePtrs.count(BasePtr)) {
255 annotateSecondLevel(Inst, BasePtr);
256 return;
259 Inst->setMetadata("alias.scope", AliasScope);
260 Inst->setMetadata("noalias", OtherAliasScopeList);
263 void ScopAnnotator::addInterIterationAliasFreeBasePtr(llvm::Value *BasePtr) {
264 if (!BasePtr)
265 return;
267 InterIterationAliasFreeBasePtrs.insert(BasePtr);