blob: b7e03decf3f00781bf2f6bd438999da2c102bff1 [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 Doerfertc7b719f2014-10-01 20:10:44 +000016
Johannes Doerfertecdf2632014-10-02 15:31:24 +000017#include "polly/ScopInfo.h"
18#include "polly/Support/ScopHelper.h"
19
Tobias Grosser37c9b8e2014-03-04 14:59:00 +000020#include "llvm/IR/Metadata.h"
21#include "llvm/Support/Debug.h"
22
23using namespace llvm;
24using namespace polly;
25
Johannes Doerfertecdf2632014-10-02 15:31:24 +000026/// @brief 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.
33static MDNode *getID(LLVMContext &Ctx, Value *arg0 = nullptr,
34 Value *arg1 = nullptr) {
35 MDNode *ID;
36 SmallVector<Value *, 3> Args;
37 Args.push_back(nullptr);
38
39 if (arg0)
40 Args.push_back(arg0);
41 if (arg1)
42 Args.push_back(arg1);
43
44 ID = MDNode::get(Ctx, Args);
45 ID->replaceOperandWith(0, ID);
46 return ID;
47}
48
Johannes Doerfert51d1c742014-10-02 15:32:17 +000049ScopAnnotator::ScopAnnotator() : SE(nullptr), AliasScopeDomain(nullptr) {}
Johannes Doerfertecdf2632014-10-02 15:31:24 +000050
Johannes Doerfert51d1c742014-10-02 15:32:17 +000051void ScopAnnotator::buildAliasScopes(Scop &S) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000052 SE = S.getSE();
53
54 LLVMContext &Ctx = SE->getContext();
55 AliasScopeDomain = getID(Ctx, MDString::get(Ctx, "polly.alias.scope.domain"));
56
57 AliasScopeMap.clear();
58 OtherAliasScopeListMap.clear();
59
60 SetVector<Value *> BasePtrs;
61 for (ScopStmt *Stmt : S)
62 for (MemoryAccess *MA : *Stmt)
63 BasePtrs.insert(MA->getBaseAddr());
64
65 std::string AliasScopeStr = "polly.alias.scope.";
66 for (Value *BasePtr : BasePtrs)
67 AliasScopeMap[BasePtr] = getID(
68 Ctx, AliasScopeDomain,
69 MDString::get(Ctx, (AliasScopeStr + BasePtr->getName()).str().c_str()));
70
71 for (Value *BasePtr : BasePtrs) {
72 MDNode *AliasScopeList = MDNode::get(Ctx, {});
73 for (const auto &AliasScopePair : AliasScopeMap) {
74 if (BasePtr == AliasScopePair.first)
75 continue;
76
77 Value *Args = {AliasScopePair.second};
78 AliasScopeList =
79 MDNode::concatenate(AliasScopeList, MDNode::get(Ctx, Args));
80 }
81
82 OtherAliasScopeListMap[BasePtr] = AliasScopeList;
83 }
Tobias Grosser37c9b8e2014-03-04 14:59:00 +000084}
85
Johannes Doerfert51d1c742014-10-02 15:32:17 +000086void ScopAnnotator::pushLoop(Loop *L, bool IsParallel) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000087
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000088 ActiveLoops.push_back(L);
89 if (!IsParallel)
Tobias Grosser37c9b8e2014-03-04 14:59:00 +000090 return;
91
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000092 BasicBlock *Header = L->getHeader();
Johannes Doerfertecdf2632014-10-02 15:31:24 +000093 MDNode *Id = getID(Header->getContext());
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000094 Value *Args[] = {Id};
95 MDNode *Ids = ParallelLoops.empty()
96 ? MDNode::get(Header->getContext(), Args)
97 : MDNode::concatenate(ParallelLoops.back(), Id);
98 ParallelLoops.push_back(Ids);
99}
100
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000101void ScopAnnotator::popLoop(bool IsParallel) {
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000102 ActiveLoops.pop_back();
103 if (!IsParallel)
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000104 return;
105
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000106 assert(!ParallelLoops.empty() && "Expected a parallel loop to pop");
107 ParallelLoops.pop_back();
108}
109
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000110void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L,
111 bool IsParallel) const {
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000112 if (!IsParallel)
113 return;
114
115 assert(!ParallelLoops.empty() && "Expected a parallel loop to annotate");
116 MDNode *Ids = ParallelLoops.back();
117 MDNode *Id = cast<MDNode>(Ids->getOperand(Ids->getNumOperands() - 1));
118 B->setMetadata("llvm.loop", Id);
119}
120
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000121void ScopAnnotator::annotate(Instruction *Inst) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000122 if (!Inst->mayReadOrWriteMemory())
123 return;
124
125 // TODO: Use the ScopArrayInfo once available here.
126 if (AliasScopeDomain) {
127 Value *BasePtr = nullptr;
128 if (isa<StoreInst>(Inst) || isa<LoadInst>(Inst)) {
129 const SCEV *PtrSCEV = SE->getSCEV(getPointerOperand(*Inst));
130 const SCEV *BaseSCEV = SE->getPointerBase(PtrSCEV);
131 if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(BaseSCEV))
132 BasePtr = SU->getValue();
133 }
134
135 if (BasePtr) {
136 Inst->setMetadata("alias.scope", AliasScopeMap[BasePtr]);
137 Inst->setMetadata("noalias", OtherAliasScopeListMap[BasePtr]);
138 }
139 }
140
141 if (ParallelLoops.empty())
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000142 return;
143
144 Inst->setMetadata("llvm.mem.parallel_loop_access", ParallelLoops.back());
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000145}