blob: 9b3602d01384f95bbd60fafc0e7817faf7a8e053 [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 Grosserc80d6972016-09-02 06:33:33 +000024/// Get a self referencing id metadata node.
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000025///
Johannes Doerfertecdf2632014-10-02 15:31:24 +000026/// The MDNode looks like this (if arg0/arg1 are not null):
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000027///
Johannes Doerfertecdf2632014-10-02 15:31:24 +000028/// '!n = metadata !{metadata !n, arg0, arg1}'
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000029///
Johannes Doerfertecdf2632014-10-02 15:31:24 +000030/// @return The self referencing id metadata node.
Tobias Grosserbd8f3c12014-12-09 22:02:16 +000031static MDNode *getID(LLVMContext &Ctx, Metadata *arg0 = nullptr,
32 Metadata *arg1 = nullptr) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000033 MDNode *ID;
Tobias Grosserbd8f3c12014-12-09 22:02:16 +000034 SmallVector<Metadata *, 3> Args;
David Peixottoa4817872014-11-07 21:44:18 +000035 // Use a temporary node to safely create a unique pointer for the first arg.
Duncan P. N. Exon Smithe566efe2015-01-19 21:31:48 +000036 auto TempNode = MDNode::getTemporary(Ctx, None);
David Peixottoa4817872014-11-07 21:44:18 +000037 // Reserve operand 0 for loop id self reference.
Duncan P. N. Exon Smithe566efe2015-01-19 21:31:48 +000038 Args.push_back(TempNode.get());
Johannes Doerfertecdf2632014-10-02 15:31:24 +000039
40 if (arg0)
41 Args.push_back(arg0);
42 if (arg1)
43 Args.push_back(arg1);
44
45 ID = MDNode::get(Ctx, Args);
46 ID->replaceOperandWith(0, ID);
47 return ID;
48}
49
Johannes Doerfert51d1c742014-10-02 15:32:17 +000050ScopAnnotator::ScopAnnotator() : SE(nullptr), AliasScopeDomain(nullptr) {}
Johannes Doerfertecdf2632014-10-02 15:31:24 +000051
Johannes Doerfert51d1c742014-10-02 15:32:17 +000052void ScopAnnotator::buildAliasScopes(Scop &S) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000053 SE = S.getSE();
54
55 LLVMContext &Ctx = SE->getContext();
56 AliasScopeDomain = getID(Ctx, MDString::get(Ctx, "polly.alias.scope.domain"));
57
58 AliasScopeMap.clear();
59 OtherAliasScopeListMap.clear();
60
Johannes Doerfertecdf2632014-10-02 15:31:24 +000061 std::string AliasScopeStr = "polly.alias.scope.";
Tobias Grosser45534632017-02-09 09:34:42 +000062 for (const ScopArrayInfo *Array : S.arrays())
63 AliasScopeMap[Array->getBasePtr()] =
64 getID(Ctx, AliasScopeDomain,
65 MDString::get(Ctx, (AliasScopeStr + Array->getName()).c_str()));
Johannes Doerfertecdf2632014-10-02 15:31:24 +000066
Tobias Grosser45534632017-02-09 09:34:42 +000067 for (const ScopArrayInfo *Array : S.arrays()) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000068 MDNode *AliasScopeList = MDNode::get(Ctx, {});
69 for (const auto &AliasScopePair : AliasScopeMap) {
Tobias Grosser45534632017-02-09 09:34:42 +000070 if (Array->getBasePtr() == AliasScopePair.first)
Johannes Doerfertecdf2632014-10-02 15:31:24 +000071 continue;
72
Tobias Grosserbd8f3c12014-12-09 22:02:16 +000073 Metadata *Args = {AliasScopePair.second};
Johannes Doerfertecdf2632014-10-02 15:31:24 +000074 AliasScopeList =
75 MDNode::concatenate(AliasScopeList, MDNode::get(Ctx, Args));
76 }
77
Tobias Grosser45534632017-02-09 09:34:42 +000078 OtherAliasScopeListMap[Array->getBasePtr()] = AliasScopeList;
Johannes Doerfertecdf2632014-10-02 15:31:24 +000079 }
Tobias Grosser37c9b8e2014-03-04 14:59:00 +000080}
81
Johannes Doerfert51d1c742014-10-02 15:32:17 +000082void ScopAnnotator::pushLoop(Loop *L, bool IsParallel) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000083
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000084 ActiveLoops.push_back(L);
85 if (!IsParallel)
Tobias Grosser37c9b8e2014-03-04 14:59:00 +000086 return;
87
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000088 BasicBlock *Header = L->getHeader();
Johannes Doerfertecdf2632014-10-02 15:31:24 +000089 MDNode *Id = getID(Header->getContext());
Duncan P. N. Exon Smith16173b72014-12-07 21:12:10 +000090 assert(Id->getOperand(0) == Id && "Expected Id to be a self-reference");
91 assert(Id->getNumOperands() == 1 && "Unexpected extra operands in Id");
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000092 MDNode *Ids = ParallelLoops.empty()
Duncan P. N. Exon Smith16173b72014-12-07 21:12:10 +000093 ? Id
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000094 : MDNode::concatenate(ParallelLoops.back(), Id);
95 ParallelLoops.push_back(Ids);
96}
97
Johannes Doerfert51d1c742014-10-02 15:32:17 +000098void ScopAnnotator::popLoop(bool IsParallel) {
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000099 ActiveLoops.pop_back();
100 if (!IsParallel)
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000101 return;
102
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000103 assert(!ParallelLoops.empty() && "Expected a parallel loop to pop");
104 ParallelLoops.pop_back();
105}
106
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000107void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L,
108 bool IsParallel) const {
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000109 if (!IsParallel)
110 return;
111
112 assert(!ParallelLoops.empty() && "Expected a parallel loop to annotate");
113 MDNode *Ids = ParallelLoops.back();
114 MDNode *Id = cast<MDNode>(Ids->getOperand(Ids->getNumOperands() - 1));
115 B->setMetadata("llvm.loop", Id);
116}
117
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000118void ScopAnnotator::annotate(Instruction *Inst) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000119 if (!Inst->mayReadOrWriteMemory())
120 return;
121
Tobias Grosser73725b82015-10-07 13:19:03 +0000122 if (!ParallelLoops.empty())
123 Inst->setMetadata("llvm.mem.parallel_loop_access", ParallelLoops.back());
124
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000125 // TODO: Use the ScopArrayInfo once available here.
Tobias Grosser73725b82015-10-07 13:19:03 +0000126 if (!AliasScopeDomain)
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000127 return;
128
Michael Kruse70131d32016-01-27 17:09:17 +0000129 auto MemInst = MemAccInst::dyn_cast(Inst);
130 if (!MemInst)
Tobias Grosser73725b82015-10-07 13:19:03 +0000131 return;
132
Johannes Doerferta7920982016-02-25 14:08:48 +0000133 auto *Ptr = MemInst.getPointerOperand();
134 if (!Ptr)
135 return;
136
137 auto *PtrSCEV = SE->getSCEV(Ptr);
Tobias Grosser73725b82015-10-07 13:19:03 +0000138 auto *BaseSCEV = SE->getPointerBase(PtrSCEV);
139 auto *SU = dyn_cast<SCEVUnknown>(BaseSCEV);
140
141 if (!SU)
142 return;
143
144 auto *BasePtr = SU->getValue();
145
146 if (!BasePtr)
147 return;
148
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000149 auto AliasScope = AliasScopeMap.lookup(BasePtr);
Tobias Grosser73725b82015-10-07 13:19:03 +0000150
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000151 if (!AliasScope) {
152 BasePtr = AlternativeAliasBases.lookup(BasePtr);
153 if (!BasePtr)
Tobias Grosserd79cb032015-10-07 13:19:06 +0000154 return;
Tobias Grosser73725b82015-10-07 13:19:03 +0000155
Tobias Grosser6bab9f82015-10-07 13:35:20 +0000156 AliasScope = AliasScopeMap.lookup(BasePtr);
157 if (!AliasScope)
Tobias Grosserd79cb032015-10-07 13:19:06 +0000158 return;
159 }
160
Tobias Grosserd79cb032015-10-07 13:19:06 +0000161 assert(OtherAliasScopeListMap.count(BasePtr) &&
162 "BasePtr either expected in AliasScopeMap and OtherAlias...Map");
Tobias Grosser73725b82015-10-07 13:19:03 +0000163 auto *OtherAliasScopeList = OtherAliasScopeListMap[BasePtr];
164
165 Inst->setMetadata("alias.scope", AliasScope);
166 Inst->setMetadata("noalias", OtherAliasScopeList);
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000167}