Coverage Report

Created: 2017-03-27 23:01

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/polly/lib/CodeGen/IRBuilder.cpp
Line
Count
Source (jump to first uncovered line)
1
//===------ 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"
16
#include "polly/ScopInfo.h"
17
#include "polly/Support/ScopHelper.h"
18
#include "llvm/IR/Metadata.h"
19
#include "llvm/Support/Debug.h"
20
21
using namespace llvm;
22
using namespace polly;
23
24
/// Get a self referencing id metadata node.
25
///
26
/// The MDNode looks like this (if arg0/arg1 are not null):
27
///
28
///    '!n = metadata !{metadata !n, arg0, arg1}'
29
///
30
/// @return The self referencing id metadata node.
31
static MDNode *getID(LLVMContext &Ctx, Metadata *arg0 = nullptr,
32
820
                     Metadata *arg1 = nullptr) {
33
820
  MDNode *ID;
34
820
  SmallVector<Metadata *, 3> Args;
35
820
  // Use a temporary node to safely create a unique pointer for the first arg.
36
820
  auto TempNode = MDNode::getTemporary(Ctx, None);
37
820
  // Reserve operand 0 for loop id self reference.
38
820
  Args.push_back(TempNode.get());
39
820
40
820
  if (arg0)
41
804
    Args.push_back(arg0);
42
820
  if (arg1)
43
546
    Args.push_back(arg1);
44
820
45
820
  ID = MDNode::get(Ctx, Args);
46
820
  ID->replaceOperandWith(0, ID);
47
820
  return ID;
48
820
}
49
50
258
ScopAnnotator::ScopAnnotator() : SE(nullptr), AliasScopeDomain(nullptr) {}
51
52
258
void ScopAnnotator::buildAliasScopes(Scop &S) {
53
258
  SE = S.getSE();
54
258
55
258
  LLVMContext &Ctx = SE->getContext();
56
258
  AliasScopeDomain = getID(Ctx, MDString::get(Ctx, "polly.alias.scope.domain"));
57
258
58
258
  AliasScopeMap.clear();
59
258
  OtherAliasScopeListMap.clear();
60
258
61
258
  std::string AliasScopeStr = "polly.alias.scope.";
62
258
  for (const ScopArrayInfo *Array : S.arrays())
63
542
    AliasScopeMap[Array->getBasePtr()] =
64
542
        getID(Ctx, AliasScopeDomain,
65
542
              MDString::get(Ctx, (AliasScopeStr + Array->getName()).c_str()));
66
258
67
542
  for (const ScopArrayInfo *Array : S.arrays()) {
68
542
    MDNode *AliasScopeList = MDNode::get(Ctx, {});
69
1.62k
    for (const auto &AliasScopePair : AliasScopeMap) {
70
1.62k
      if (Array->getBasePtr() == AliasScopePair.first)
71
542
        continue;
72
1.62k
73
1.08k
      Metadata *Args = {AliasScopePair.second};
74
1.08k
      AliasScopeList =
75
1.08k
          MDNode::concatenate(AliasScopeList, MDNode::get(Ctx, Args));
76
1.08k
    }
77
542
78
542
    OtherAliasScopeListMap[Array->getBasePtr()] = AliasScopeList;
79
542
  }
80
258
}
81
82
209
void ScopAnnotator::pushLoop(Loop *L, bool IsParallel) {
83
209
84
209
  ActiveLoops.push_back(L);
85
209
  if (!IsParallel)
86
193
    return;
87
209
88
16
  BasicBlock *Header = L->getHeader();
89
16
  MDNode *Id = getID(Header->getContext());
90
16
  assert(Id->getOperand(0) == Id && "Expected Id to be a self-reference");
91
16
  assert(Id->getNumOperands() == 1 && "Unexpected extra operands in Id");
92
16
  MDNode *Ids = ParallelLoops.empty()
93
15
                    ? Id
94
1
                    : MDNode::concatenate(ParallelLoops.back(), Id);
95
16
  ParallelLoops.push_back(Ids);
96
16
}
97
98
209
void ScopAnnotator::popLoop(bool IsParallel) {
99
209
  ActiveLoops.pop_back();
100
209
  if (!IsParallel)
101
193
    return;
102
209
103
16
  assert(!ParallelLoops.empty() && "Expected a parallel loop to pop");
104
16
  ParallelLoops.pop_back();
105
16
}
106
107
void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L,
108
209
                                      bool IsParallel) const {
109
209
  if (!IsParallel)
110
193
    return;
111
209
112
16
  assert(!ParallelLoops.empty() && "Expected a parallel loop to annotate");
113
16
  MDNode *Ids = ParallelLoops.back();
114
16
  MDNode *Id = cast<MDNode>(Ids->getOperand(Ids->getNumOperands() - 1));
115
16
  B->setMetadata("llvm.loop", Id);
116
16
}
117
118
/// Get the pointer operand
119
///
120
/// @param Inst The instruction to be analyzed.
121
/// @return the pointer operand in case @p Inst is a memory access
122
///         instruction and nullptr otherwise.
123
1.37k
static llvm::Value *getMemAccInstPointerOperand(Instruction *Inst) {
124
1.37k
  auto MemInst = MemAccInst::dyn_cast(Inst);
125
1.37k
  if (!MemInst)
126
0
    return nullptr;
127
1.37k
128
1.37k
  return MemInst.getPointerOperand();
129
1.37k
}
130
131
void ScopAnnotator::annotateSecondLevel(llvm::Instruction *Inst,
132
8
                                        llvm::Value *BasePtr) {
133
8
  auto *Ptr = getMemAccInstPointerOperand(Inst);
134
8
  if (!Ptr)
135
0
    return;
136
8
  auto SecondLevelAliasScope = SecondLevelAliasScopeMap.lookup(Ptr);
137
8
  auto SecondLevelOtherAliasScopeList =
138
8
      SecondLevelOtherAliasScopeListMap.lookup(Ptr);
139
8
  if (
!SecondLevelAliasScope8
)
{4
140
4
    auto AliasScope = AliasScopeMap.lookup(BasePtr);
141
4
    if (!AliasScope)
142
0
      return;
143
4
    LLVMContext &Ctx = SE->getContext();
144
4
    SecondLevelAliasScope = getID(
145
4
        Ctx, AliasScope, MDString::get(Ctx, "second level alias metadata"));
146
4
    SecondLevelAliasScopeMap[Ptr] = SecondLevelAliasScope;
147
4
    Metadata *Args = {SecondLevelAliasScope};
148
4
    auto SecondLevelBasePtrAliasScopeList =
149
4
        SecondLevelAliasScopeMap.lookup(BasePtr);
150
4
    SecondLevelAliasScopeMap[BasePtr] = MDNode::concatenate(
151
4
        SecondLevelBasePtrAliasScopeList, MDNode::get(Ctx, Args));
152
4
    auto OtherAliasScopeList = OtherAliasScopeListMap.lookup(BasePtr);
153
4
    SecondLevelOtherAliasScopeList = MDNode::concatenate(
154
4
        OtherAliasScopeList, SecondLevelBasePtrAliasScopeList);
155
4
    SecondLevelOtherAliasScopeListMap[Ptr] = SecondLevelOtherAliasScopeList;
156
4
  }
157
8
  Inst->setMetadata("alias.scope", SecondLevelAliasScope);
158
8
  Inst->setMetadata("noalias", SecondLevelOtherAliasScopeList);
159
8
}
160
161
7.60k
void ScopAnnotator::annotate(Instruction *Inst) {
162
7.60k
  if (!Inst->mayReadOrWriteMemory())
163
6.24k
    return;
164
7.60k
165
1.36k
  
if (1.36k
!ParallelLoops.empty()1.36k
)
166
43
    Inst->setMetadata("llvm.mem.parallel_loop_access", ParallelLoops.back());
167
1.36k
168
1.36k
  // TODO: Use the ScopArrayInfo once available here.
169
1.36k
  if (!AliasScopeDomain)
170
0
    return;
171
1.36k
172
1.36k
  auto *Ptr = getMemAccInstPointerOperand(Inst);
173
1.36k
  if (!Ptr)
174
146
    return;
175
1.36k
176
1.21k
  auto *PtrSCEV = SE->getSCEV(Ptr);
177
1.21k
  auto *BaseSCEV = SE->getPointerBase(PtrSCEV);
178
1.21k
  auto *SU = dyn_cast<SCEVUnknown>(BaseSCEV);
179
1.21k
180
1.21k
  if (!SU)
181
1
    return;
182
1.21k
183
1.21k
  auto *BasePtr = SU->getValue();
184
1.21k
185
1.21k
  if (!BasePtr)
186
0
    return;
187
1.21k
188
1.21k
  auto AliasScope = AliasScopeMap.lookup(BasePtr);
189
1.21k
190
1.21k
  if (
!AliasScope1.21k
)
{651
191
651
    BasePtr = AlternativeAliasBases.lookup(BasePtr);
192
651
    if (!BasePtr)
193
580
      return;
194
651
195
71
    AliasScope = AliasScopeMap.lookup(BasePtr);
196
71
    if (!AliasScope)
197
6
      return;
198
71
  }
199
1.21k
200
630
  assert(OtherAliasScopeListMap.count(BasePtr) &&
201
630
         "BasePtr either expected in AliasScopeMap and OtherAlias...Map");
202
630
  auto *OtherAliasScopeList = OtherAliasScopeListMap[BasePtr];
203
630
204
630
  if (
InterIterationAliasFreeBasePtrs.count(BasePtr)630
)
{8
205
8
    annotateSecondLevel(Inst, BasePtr);
206
8
    return;
207
8
  }
208
630
209
622
  Inst->setMetadata("alias.scope", AliasScope);
210
622
  Inst->setMetadata("noalias", OtherAliasScopeList);
211
622
}
212
213
1
void ScopAnnotator::addInterIterationAliasFreeBasePtr(llvm::Value *BasePtr) {
214
1
  if (!BasePtr)
215
0
    return;
216
1
217
1
  InterIterationAliasFreeBasePtrs.insert(BasePtr);
218
1
}