Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- NVPTXUtilities.cpp - Utility Functions -----------------------------===//
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
// This file contains miscellaneous utility functions
11
//===----------------------------------------------------------------------===//
12
13
#include "NVPTXUtilities.h"
14
#include "NVPTX.h"
15
#include "llvm/IR/Constants.h"
16
#include "llvm/IR/Function.h"
17
#include "llvm/IR/GlobalVariable.h"
18
#include "llvm/IR/InstIterator.h"
19
#include "llvm/IR/Module.h"
20
#include "llvm/IR/Operator.h"
21
#include "llvm/Support/ManagedStatic.h"
22
#include "llvm/Support/MutexGuard.h"
23
#include <algorithm>
24
#include <cstring>
25
#include <map>
26
#include <string>
27
#include <vector>
28
29
namespace llvm {
30
31
namespace {
32
typedef std::map<std::string, std::vector<unsigned> > key_val_pair_t;
33
typedef std::map<const GlobalValue *, key_val_pair_t> global_val_annot_t;
34
typedef std::map<const Module *, global_val_annot_t> per_module_annot_t;
35
} // anonymous namespace
36
37
static ManagedStatic<per_module_annot_t> annotationCache;
38
static sys::Mutex Lock;
39
40
224
void clearAnnotationCache(const Module *Mod) {
41
224
  MutexGuard Guard(Lock);
42
224
  annotationCache->erase(Mod);
43
224
}
44
45
122
static void cacheAnnotationFromMD(const MDNode *md, key_val_pair_t &retval) {
46
122
  MutexGuard Guard(Lock);
47
122
  assert(md && "Invalid mdnode for annotation");
48
122
  assert((md->getNumOperands() % 2) == 1 && "Invalid number of operands");
49
122
  // start index = 1, to skip the global variable key
50
122
  // increment = 2, to skip the value for each property-value pairs
51
254
  for (unsigned i = 1, e = md->getNumOperands(); 
i != e254
;
i += 2132
) {
52
132
    // property
53
132
    const MDString *prop = dyn_cast<MDString>(md->getOperand(i));
54
132
    assert(prop && "Annotation property not a string");
55
132
56
132
    // value
57
132
    ConstantInt *Val = mdconst::dyn_extract<ConstantInt>(md->getOperand(i + 1));
58
132
    assert(Val && "Value operand not a constant int");
59
132
60
132
    std::string keyname = prop->getString().str();
61
132
    if (retval.find(keyname) != retval.end())
62
0
      retval[keyname].push_back(Val->getZExtValue());
63
132
    else {
64
132
      std::vector<unsigned> tmp;
65
132
      tmp.push_back(Val->getZExtValue());
66
132
      retval[keyname] = tmp;
67
132
    }
68
132
  }
69
122
}
70
71
1.64k
static void cacheAnnotationFromMD(const Module *m, const GlobalValue *gv) {
72
1.64k
  MutexGuard Guard(Lock);
73
1.64k
  NamedMDNode *NMD = m->getNamedMetadata("nvvm.annotations");
74
1.64k
  if (!NMD)
75
1.48k
    return;
76
162
  key_val_pair_t tmp;
77
1.30k
  for (unsigned i = 0, e = NMD->getNumOperands(); 
i != e1.30k
;
++i1.13k
) {
78
1.13k
    const MDNode *elem = NMD->getOperand(i);
79
1.13k
80
1.13k
    GlobalValue *entity =
81
1.13k
        mdconst::dyn_extract_or_null<GlobalValue>(elem->getOperand(0));
82
1.13k
    // entity may be null due to DCE
83
1.13k
    if (!entity)
84
0
      continue;
85
1.13k
    
if (1.13k
entity != gv1.13k
)
86
1.01k
      continue;
87
122
88
122
    // accumulate annotations for entity in tmp
89
122
    cacheAnnotationFromMD(elem, tmp);
90
122
  }
91
162
92
162
  if (tmp.empty()) // no annotations for this gv
93
54
    return;
94
108
95
108
  
if (108
(*annotationCache).find(m) != (*annotationCache).end()108
)
96
80
    (*annotationCache)[m][gv] = std::move(tmp);
97
28
  else {
98
28
    global_val_annot_t tmp1;
99
28
    tmp1[gv] = std::move(tmp);
100
28
    (*annotationCache)[m] = std::move(tmp1);
101
28
  }
102
1.64k
}
103
104
bool findOneNVVMAnnotation(const GlobalValue *gv, const std::string &prop,
105
9.71k
                           unsigned &retval) {
106
9.71k
  MutexGuard Guard(Lock);
107
9.71k
  const Module *m = gv->getParent();
108
9.71k
  if ((*annotationCache).find(m) == (*annotationCache).end())
109
206
    cacheAnnotationFromMD(m, gv);
110
9.51k
  else 
if (9.51k
(*annotationCache)[m].find(gv) == (*annotationCache)[m].end()9.51k
)
111
1.42k
    cacheAnnotationFromMD(m, gv);
112
9.71k
  if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end())
113
9.13k
    return false;
114
581
  retval = (*annotationCache)[m][gv][prop][0];
115
581
  return true;
116
581
}
117
118
bool findAllNVVMAnnotation(const GlobalValue *gv, const std::string &prop,
119
1.26k
                           std::vector<unsigned> &retval) {
120
1.26k
  MutexGuard Guard(Lock);
121
1.26k
  const Module *m = gv->getParent();
122
1.26k
  if ((*annotationCache).find(m) == (*annotationCache).end())
123
0
    cacheAnnotationFromMD(m, gv);
124
1.26k
  else 
if (1.26k
(*annotationCache)[m].find(gv) == (*annotationCache)[m].end()1.26k
)
125
12
    cacheAnnotationFromMD(m, gv);
126
1.26k
  if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end())
127
1.24k
    return false;
128
26
  retval = (*annotationCache)[m][gv][prop];
129
26
  return true;
130
26
}
131
132
103
bool isTexture(const Value &val) {
133
103
  if (const GlobalValue *
gv103
= dyn_cast<GlobalValue>(&val)) {
134
103
    unsigned annot;
135
103
    if (
findOneNVVMAnnotation(gv, "texture", annot)103
) {
136
6
      assert((annot == 1) && "Unexpected annotation on a texture symbol");
137
6
      return true;
138
6
    }
139
97
  }
140
97
  return false;
141
97
}
142
143
97
bool isSurface(const Value &val) {
144
97
  if (const GlobalValue *
gv97
= dyn_cast<GlobalValue>(&val)) {
145
97
    unsigned annot;
146
97
    if (
findOneNVVMAnnotation(gv, "surface", annot)97
) {
147
8
      assert((annot == 1) && "Unexpected annotation on a surface symbol");
148
8
      return true;
149
8
    }
150
89
  }
151
89
  return false;
152
89
}
153
154
266
bool isSampler(const Value &val) {
155
266
  const char *AnnotationName = "sampler";
156
266
157
266
  if (const GlobalValue *
gv266
= dyn_cast<GlobalValue>(&val)) {
158
86
    unsigned annot;
159
86
    if (
findOneNVVMAnnotation(gv, AnnotationName, annot)86
) {
160
0
      assert((annot == 1) && "Unexpected annotation on a sampler symbol");
161
0
      return true;
162
0
    }
163
266
  }
164
266
  
if (const Argument *266
arg266
= dyn_cast<Argument>(&val)) {
165
180
    const Function *func = arg->getParent();
166
180
    std::vector<unsigned> annot;
167
180
    if (
findAllNVVMAnnotation(func, AnnotationName, annot)180
) {
168
7
      if (is_contained(annot, arg->getArgNo()))
169
2
        return true;
170
264
    }
171
180
  }
172
264
  return false;
173
264
}
174
175
184
bool isImageReadOnly(const Value &val) {
176
184
  if (const Argument *
arg184
= dyn_cast<Argument>(&val)) {
177
184
    const Function *func = arg->getParent();
178
184
    std::vector<unsigned> annot;
179
184
    if (
findAllNVVMAnnotation(func, "rdoimage", annot)184
) {
180
9
      if (is_contained(annot, arg->getArgNo()))
181
4
        return true;
182
180
    }
183
184
  }
184
180
  return false;
185
180
}
186
187
184
bool isImageWriteOnly(const Value &val) {
188
184
  if (const Argument *
arg184
= dyn_cast<Argument>(&val)) {
189
184
    const Function *func = arg->getParent();
190
184
    std::vector<unsigned> annot;
191
184
    if (
findAllNVVMAnnotation(func, "wroimage", annot)184
) {
192
5
      if (is_contained(annot, arg->getArgNo()))
193
3
        return true;
194
181
    }
195
184
  }
196
181
  return false;
197
181
}
198
199
181
bool isImageReadWrite(const Value &val) {
200
181
  if (const Argument *
arg181
= dyn_cast<Argument>(&val)) {
201
181
    const Function *func = arg->getParent();
202
181
    std::vector<unsigned> annot;
203
181
    if (
findAllNVVMAnnotation(func, "rdwrimage", annot)181
) {
204
5
      if (is_contained(annot, arg->getArgNo()))
205
3
        return true;
206
178
    }
207
181
  }
208
178
  return false;
209
178
}
210
211
184
bool isImage(const Value &val) {
212
184
  return isImageReadOnly(val) || 
isImageWriteOnly(val)180
||
isImageReadWrite(val)178
;
213
184
}
214
215
54
bool isManaged(const Value &val) {
216
54
  if(const GlobalValue *
gv54
= dyn_cast<GlobalValue>(&val)) {
217
54
    unsigned annot;
218
54
    if (
findOneNVVMAnnotation(gv, "managed", annot)54
) {
219
1
      assert((annot == 1) && "Unexpected annotation on a managed symbol");
220
1
      return true;
221
1
    }
222
53
  }
223
53
  return false;
224
53
}
225
226
6
std::string getTextureName(const Value &val) {
227
6
  assert(val.hasName() && "Found texture variable with no name");
228
6
  return val.getName();
229
6
}
230
231
8
std::string getSurfaceName(const Value &val) {
232
8
  assert(val.hasName() && "Found surface variable with no name");
233
8
  return val.getName();
234
8
}
235
236
0
std::string getSamplerName(const Value &val) {
237
0
  assert(val.hasName() && "Found sampler variable with no name");
238
0
  return val.getName();
239
0
}
240
241
96
bool getMaxNTIDx(const Function &F, unsigned &x) {
242
96
  return findOneNVVMAnnotation(&F, "maxntidx", x);
243
96
}
244
245
96
bool getMaxNTIDy(const Function &F, unsigned &y) {
246
96
  return findOneNVVMAnnotation(&F, "maxntidy", y);
247
96
}
248
249
96
bool getMaxNTIDz(const Function &F, unsigned &z) {
250
96
  return findOneNVVMAnnotation(&F, "maxntidz", z);
251
96
}
252
253
96
bool getReqNTIDx(const Function &F, unsigned &x) {
254
96
  return findOneNVVMAnnotation(&F, "reqntidx", x);
255
96
}
256
257
96
bool getReqNTIDy(const Function &F, unsigned &y) {
258
96
  return findOneNVVMAnnotation(&F, "reqntidy", y);
259
96
}
260
261
96
bool getReqNTIDz(const Function &F, unsigned &z) {
262
96
  return findOneNVVMAnnotation(&F, "reqntidz", z);
263
96
}
264
265
96
bool getMinCTASm(const Function &F, unsigned &x) {
266
96
  return findOneNVVMAnnotation(&F, "minctasm", x);
267
96
}
268
269
96
bool getMaxNReg(const Function &F, unsigned &x) {
270
96
  return findOneNVVMAnnotation(&F, "maxnreg", x);
271
96
}
272
273
8.60k
bool isKernelFunction(const Function &F) {
274
8.60k
  unsigned x = 0;
275
8.60k
  bool retval = findOneNVVMAnnotation(&F, "kernel", x);
276
8.60k
  if (
!retval8.60k
) {
277
8.06k
    // There is no NVVM metadata, check the calling convention
278
8.06k
    return F.getCallingConv() == CallingConv::PTX_Kernel;
279
8.06k
  }
280
547
  return (x == 1);
281
547
}
282
283
539
bool getAlign(const Function &F, unsigned index, unsigned &align) {
284
539
  std::vector<unsigned> Vs;
285
539
  bool retval = findAllNVVMAnnotation(&F, "align", Vs);
286
539
  if (!retval)
287
539
    return false;
288
0
  
for (int i = 0, e = Vs.size(); 0
i < e0
;
i++0
) {
289
0
    unsigned v = Vs[i];
290
0
    if (
(v >> 16) == index0
) {
291
0
      align = v & 0xFFFF;
292
0
      return true;
293
0
    }
294
0
  }
295
0
  return false;
296
539
}
297
298
3
bool getAlign(const CallInst &I, unsigned index, unsigned &align) {
299
3
  if (MDNode *
alignNode3
= I.getMetadata("callalign")) {
300
0
    for (int i = 0, n = alignNode->getNumOperands(); 
i < n0
;
i++0
) {
301
0
      if (const ConstantInt *CI =
302
0
              mdconst::dyn_extract<ConstantInt>(alignNode->getOperand(i))) {
303
0
        unsigned v = CI->getZExtValue();
304
0
        if (
(v >> 16) == index0
) {
305
0
          align = v & 0xFFFF;
306
0
          return true;
307
0
        }
308
0
        
if (0
(v >> 16) > index0
) {
309
0
          return false;
310
0
        }
311
0
      }
312
0
    }
313
0
  }
314
3
  return false;
315
3
}
316
317
} // namespace llvm