blob: cbd162628eb788894ec909496c08e39476c8320e [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.
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.
38 MDNode *TempNode = MDNode::getTemporary(Ctx, None);
39 // Reserve operand 0 for loop id self reference.
40 Args.push_back(TempNode);
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);
David Peixottoa4817872014-11-07 21:44:18 +000049 MDNode::deleteTemporary(TempNode);
Johannes Doerfertecdf2632014-10-02 15:31:24 +000050 return ID;
51}
52
Johannes Doerfert51d1c742014-10-02 15:32:17 +000053ScopAnnotator::ScopAnnotator() : SE(nullptr), AliasScopeDomain(nullptr) {}
Johannes Doerfertecdf2632014-10-02 15:31:24 +000054
Johannes Doerfert51d1c742014-10-02 15:32:17 +000055void ScopAnnotator::buildAliasScopes(Scop &S) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000056 SE = S.getSE();
57
58 LLVMContext &Ctx = SE->getContext();
59 AliasScopeDomain = getID(Ctx, MDString::get(Ctx, "polly.alias.scope.domain"));
60
61 AliasScopeMap.clear();
62 OtherAliasScopeListMap.clear();
63
64 SetVector<Value *> BasePtrs;
65 for (ScopStmt *Stmt : S)
66 for (MemoryAccess *MA : *Stmt)
67 BasePtrs.insert(MA->getBaseAddr());
68
69 std::string AliasScopeStr = "polly.alias.scope.";
70 for (Value *BasePtr : BasePtrs)
71 AliasScopeMap[BasePtr] = getID(
72 Ctx, AliasScopeDomain,
73 MDString::get(Ctx, (AliasScopeStr + BasePtr->getName()).str().c_str()));
74
75 for (Value *BasePtr : BasePtrs) {
76 MDNode *AliasScopeList = MDNode::get(Ctx, {});
77 for (const auto &AliasScopePair : AliasScopeMap) {
78 if (BasePtr == AliasScopePair.first)
79 continue;
80
Tobias Grosserbd8f3c12014-12-09 22:02:16 +000081 Metadata *Args = {AliasScopePair.second};
Johannes Doerfertecdf2632014-10-02 15:31:24 +000082 AliasScopeList =
83 MDNode::concatenate(AliasScopeList, MDNode::get(Ctx, Args));
84 }
85
86 OtherAliasScopeListMap[BasePtr] = AliasScopeList;
87 }
Tobias Grosser37c9b8e2014-03-04 14:59:00 +000088}
89
Johannes Doerfert51d1c742014-10-02 15:32:17 +000090void ScopAnnotator::pushLoop(Loop *L, bool IsParallel) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +000091
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000092 ActiveLoops.push_back(L);
93 if (!IsParallel)
Tobias Grosser37c9b8e2014-03-04 14:59:00 +000094 return;
95
Johannes Doerfertc7b719f2014-10-01 20:10:44 +000096 BasicBlock *Header = L->getHeader();
Johannes Doerfertecdf2632014-10-02 15:31:24 +000097 MDNode *Id = getID(Header->getContext());
Duncan P. N. Exon Smith16173b72014-12-07 21:12:10 +000098 assert(Id->getOperand(0) == Id && "Expected Id to be a self-reference");
99 assert(Id->getNumOperands() == 1 && "Unexpected extra operands in Id");
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000100 MDNode *Ids = ParallelLoops.empty()
Duncan P. N. Exon Smith16173b72014-12-07 21:12:10 +0000101 ? Id
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000102 : MDNode::concatenate(ParallelLoops.back(), Id);
103 ParallelLoops.push_back(Ids);
104}
105
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000106void ScopAnnotator::popLoop(bool IsParallel) {
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000107 ActiveLoops.pop_back();
108 if (!IsParallel)
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000109 return;
110
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000111 assert(!ParallelLoops.empty() && "Expected a parallel loop to pop");
112 ParallelLoops.pop_back();
113}
114
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000115void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L,
116 bool IsParallel) const {
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000117 if (!IsParallel)
118 return;
119
120 assert(!ParallelLoops.empty() && "Expected a parallel loop to annotate");
121 MDNode *Ids = ParallelLoops.back();
122 MDNode *Id = cast<MDNode>(Ids->getOperand(Ids->getNumOperands() - 1));
123 B->setMetadata("llvm.loop", Id);
124}
125
Johannes Doerfert51d1c742014-10-02 15:32:17 +0000126void ScopAnnotator::annotate(Instruction *Inst) {
Johannes Doerfertecdf2632014-10-02 15:31:24 +0000127 if (!Inst->mayReadOrWriteMemory())
128 return;
129
130 // TODO: Use the ScopArrayInfo once available here.
131 if (AliasScopeDomain) {
132 Value *BasePtr = nullptr;
133 if (isa<StoreInst>(Inst) || isa<LoadInst>(Inst)) {
134 const SCEV *PtrSCEV = SE->getSCEV(getPointerOperand(*Inst));
135 const SCEV *BaseSCEV = SE->getPointerBase(PtrSCEV);
136 if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(BaseSCEV))
137 BasePtr = SU->getValue();
138 }
139
140 if (BasePtr) {
141 Inst->setMetadata("alias.scope", AliasScopeMap[BasePtr]);
142 Inst->setMetadata("noalias", OtherAliasScopeListMap[BasePtr]);
143 }
144 }
145
146 if (ParallelLoops.empty())
Johannes Doerfertc7b719f2014-10-01 20:10:44 +0000147 return;
148
149 Inst->setMetadata("llvm.mem.parallel_loop_access", ParallelLoops.back());
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000150}