Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
numba
GitHub Repository: numba/llvmlite
Path: blob/main/ffi/value.cpp
1154 views
1
#include "core.h"
2
#include "llvm-c/Core.h"
3
#include <string>
4
5
#include <iostream>
6
7
// the following is needed for WriteGraph()
8
#include "llvm/Analysis/CFGPrinter.h"
9
#include "llvm/IR/GlobalVariable.h"
10
#include "llvm/Support/GraphWriter.h"
11
12
/* An iterator around a attribute list, including the stop condition */
13
struct AttributeListIterator {
14
typedef llvm::AttributeList::iterator const_iterator;
15
const_iterator cur;
16
const_iterator end;
17
18
AttributeListIterator(const_iterator cur, const_iterator end)
19
: cur(cur), end(end) {}
20
};
21
22
struct OpaqueAttributeListIterator;
23
typedef OpaqueAttributeListIterator *LLVMAttributeListIteratorRef;
24
25
/* An iterator around a attribute set, including the stop condition */
26
struct AttributeSetIterator {
27
typedef llvm::AttributeSet::iterator const_iterator;
28
const_iterator cur;
29
const_iterator end;
30
31
AttributeSetIterator(const_iterator cur, const_iterator end)
32
: cur(cur), end(end) {}
33
};
34
35
struct OpaqueAttributeSetIterator;
36
typedef OpaqueAttributeSetIterator *LLVMAttributeSetIteratorRef;
37
38
/* An iterator around a function's blocks, including the stop condition */
39
struct BlocksIterator {
40
typedef llvm::Function::const_iterator const_iterator;
41
const_iterator cur;
42
const_iterator end;
43
44
BlocksIterator(const_iterator cur, const_iterator end)
45
: cur(cur), end(end) {}
46
};
47
48
struct OpaqueBlocksIterator;
49
typedef OpaqueBlocksIterator *LLVMBlocksIteratorRef;
50
51
/* An iterator around a function's arguments, including the stop condition */
52
struct ArgumentsIterator {
53
typedef llvm::Function::const_arg_iterator const_iterator;
54
const_iterator cur;
55
const_iterator end;
56
57
ArgumentsIterator(const_iterator cur, const_iterator end)
58
: cur(cur), end(end) {}
59
};
60
61
struct OpaqueArgumentsIterator;
62
typedef OpaqueArgumentsIterator *LLVMArgumentsIteratorRef;
63
64
/* An iterator around a basic block's instructions, including the stop condition
65
*/
66
struct InstructionsIterator {
67
typedef llvm::BasicBlock::const_iterator const_iterator;
68
const_iterator cur;
69
const_iterator end;
70
71
InstructionsIterator(const_iterator cur, const_iterator end)
72
: cur(cur), end(end) {}
73
};
74
75
struct OpaqueInstructionsIterator;
76
typedef OpaqueInstructionsIterator *LLVMInstructionsIteratorRef;
77
78
/* An iterator around a instruction's operands, including the stop condition */
79
struct OperandsIterator {
80
typedef llvm::Instruction::const_op_iterator const_iterator;
81
const_iterator cur;
82
const_iterator end;
83
84
OperandsIterator(const_iterator cur, const_iterator end)
85
: cur(cur), end(end) {}
86
};
87
88
struct OpaqueOperandsIterator;
89
typedef OpaqueOperandsIterator *LLVMOperandsIteratorRef;
90
91
/* An iterator around a phi node's incoming blocks, including the stop condition
92
*/
93
struct IncomingBlocksIterator {
94
typedef llvm::PHINode::const_block_iterator const_iterator;
95
const_iterator cur;
96
const_iterator end;
97
98
IncomingBlocksIterator(const_iterator cur, const_iterator end)
99
: cur(cur), end(end) {}
100
};
101
102
struct OpaqueIncomingBlocksIterator;
103
typedef OpaqueIncomingBlocksIterator *LLVMIncomingBlocksIteratorRef;
104
105
namespace llvm {
106
107
static LLVMAttributeListIteratorRef wrap(AttributeListIterator *GI) {
108
return reinterpret_cast<LLVMAttributeListIteratorRef>(GI);
109
}
110
111
static AttributeListIterator *unwrap(LLVMAttributeListIteratorRef GI) {
112
return reinterpret_cast<AttributeListIterator *>(GI);
113
}
114
115
static LLVMAttributeSetIteratorRef wrap(AttributeSetIterator *GI) {
116
return reinterpret_cast<LLVMAttributeSetIteratorRef>(GI);
117
}
118
119
static AttributeSetIterator *unwrap(LLVMAttributeSetIteratorRef GI) {
120
return reinterpret_cast<AttributeSetIterator *>(GI);
121
}
122
123
static LLVMBlocksIteratorRef wrap(BlocksIterator *GI) {
124
return reinterpret_cast<LLVMBlocksIteratorRef>(GI);
125
}
126
127
static BlocksIterator *unwrap(LLVMBlocksIteratorRef GI) {
128
return reinterpret_cast<BlocksIterator *>(GI);
129
}
130
131
static LLVMArgumentsIteratorRef wrap(ArgumentsIterator *GI) {
132
return reinterpret_cast<LLVMArgumentsIteratorRef>(GI);
133
}
134
135
static ArgumentsIterator *unwrap(LLVMArgumentsIteratorRef GI) {
136
return reinterpret_cast<ArgumentsIterator *>(GI);
137
}
138
139
static LLVMInstructionsIteratorRef wrap(InstructionsIterator *GI) {
140
return reinterpret_cast<LLVMInstructionsIteratorRef>(GI);
141
}
142
143
static InstructionsIterator *unwrap(LLVMInstructionsIteratorRef GI) {
144
return reinterpret_cast<InstructionsIterator *>(GI);
145
}
146
147
static LLVMOperandsIteratorRef wrap(OperandsIterator *GI) {
148
return reinterpret_cast<LLVMOperandsIteratorRef>(GI);
149
}
150
151
static OperandsIterator *unwrap(LLVMOperandsIteratorRef GI) {
152
return reinterpret_cast<OperandsIterator *>(GI);
153
}
154
155
static LLVMIncomingBlocksIteratorRef wrap(IncomingBlocksIterator *GI) {
156
return reinterpret_cast<LLVMIncomingBlocksIteratorRef>(GI);
157
}
158
159
static IncomingBlocksIterator *unwrap(LLVMIncomingBlocksIteratorRef GI) {
160
return reinterpret_cast<IncomingBlocksIterator *>(GI);
161
}
162
163
} // namespace llvm
164
165
extern "C" {
166
167
API_EXPORT(LLVMAttributeListIteratorRef)
168
LLVMPY_FunctionAttributesIter(LLVMValueRef F) {
169
using namespace llvm;
170
Function *func = unwrap<Function>(F);
171
AttributeList attrs = func->getAttributes();
172
return wrap(new AttributeListIterator(attrs.begin(), attrs.end()));
173
}
174
175
API_EXPORT(LLVMAttributeSetIteratorRef)
176
LLVMPY_ArgumentAttributesIter(LLVMValueRef A) {
177
using namespace llvm;
178
Argument *arg = unwrap<Argument>(A);
179
unsigned argno = arg->getArgNo();
180
const AttributeSet attrs =
181
arg->getParent()->getAttributes().getParamAttrs(argno);
182
return wrap(new AttributeSetIterator(attrs.begin(), attrs.end()));
183
}
184
185
API_EXPORT(LLVMAttributeListIteratorRef)
186
LLVMPY_CallInstAttributesIter(LLVMValueRef C) {
187
using namespace llvm;
188
CallInst *inst = unwrap<CallInst>(C);
189
AttributeList attrs = inst->getAttributes();
190
return wrap(new AttributeListIterator(attrs.begin(), attrs.end()));
191
}
192
193
API_EXPORT(LLVMAttributeListIteratorRef)
194
LLVMPY_InvokeInstAttributesIter(LLVMValueRef C) {
195
using namespace llvm;
196
InvokeInst *inst = unwrap<InvokeInst>(C);
197
AttributeList attrs = inst->getAttributes();
198
return wrap(new AttributeListIterator(attrs.begin(), attrs.end()));
199
}
200
201
API_EXPORT(LLVMAttributeSetIteratorRef)
202
LLVMPY_GlobalAttributesIter(LLVMValueRef G) {
203
using namespace llvm;
204
GlobalVariable *g = unwrap<GlobalVariable>(G);
205
AttributeSet attrs = g->getAttributes();
206
return wrap(new AttributeSetIterator(attrs.begin(), attrs.end()));
207
}
208
209
API_EXPORT(LLVMBlocksIteratorRef)
210
LLVMPY_FunctionBlocksIter(LLVMValueRef F) {
211
using namespace llvm;
212
Function *func = unwrap<Function>(F);
213
return wrap(new BlocksIterator(func->begin(), func->end()));
214
}
215
216
API_EXPORT(LLVMArgumentsIteratorRef)
217
LLVMPY_FunctionArgumentsIter(LLVMValueRef F) {
218
using namespace llvm;
219
Function *func = unwrap<Function>(F);
220
return wrap(new ArgumentsIterator(func->arg_begin(), func->arg_end()));
221
}
222
223
API_EXPORT(LLVMInstructionsIteratorRef)
224
LLVMPY_BlockInstructionsIter(LLVMValueRef B) {
225
using namespace llvm;
226
BasicBlock *block = unwrap<BasicBlock>(B);
227
return wrap(new InstructionsIterator(block->begin(), block->end()));
228
}
229
230
API_EXPORT(LLVMOperandsIteratorRef)
231
LLVMPY_InstructionOperandsIter(LLVMValueRef I) {
232
using namespace llvm;
233
Instruction *inst = unwrap<Instruction>(I);
234
return wrap(new OperandsIterator(inst->op_begin(), inst->op_end()));
235
}
236
237
API_EXPORT(LLVMIncomingBlocksIteratorRef)
238
LLVMPY_PhiIncomingBlocksIter(LLVMValueRef I) {
239
using namespace llvm;
240
PHINode *inst = unwrap<PHINode>(I);
241
return wrap(
242
new IncomingBlocksIterator(inst->block_begin(), inst->block_end()));
243
}
244
245
API_EXPORT(const char *)
246
LLVMPY_AttributeListIterNext(LLVMAttributeListIteratorRef GI) {
247
using namespace llvm;
248
AttributeListIterator *iter = unwrap(GI);
249
if (iter->cur != iter->end) {
250
return LLVMPY_CreateString((&*iter->cur++)->getAsString().c_str());
251
} else {
252
return NULL;
253
}
254
}
255
256
API_EXPORT(const char *)
257
LLVMPY_AttributeSetIterNext(LLVMAttributeSetIteratorRef GI) {
258
using namespace llvm;
259
AttributeSetIterator *iter = unwrap(GI);
260
if (iter->cur != iter->end) {
261
return LLVMPY_CreateString((&*iter->cur++)->getAsString().c_str());
262
} else {
263
return NULL;
264
}
265
}
266
267
API_EXPORT(LLVMValueRef)
268
LLVMPY_BlocksIterNext(LLVMBlocksIteratorRef GI) {
269
using namespace llvm;
270
BlocksIterator *iter = unwrap(GI);
271
if (iter->cur != iter->end) {
272
return wrap(static_cast<const Value *>(&*iter->cur++));
273
} else {
274
return NULL;
275
}
276
}
277
278
API_EXPORT(LLVMValueRef)
279
LLVMPY_ArgumentsIterNext(LLVMArgumentsIteratorRef GI) {
280
using namespace llvm;
281
ArgumentsIterator *iter = unwrap(GI);
282
if (iter->cur != iter->end) {
283
return wrap(&*iter->cur++);
284
} else {
285
return NULL;
286
}
287
}
288
289
API_EXPORT(LLVMValueRef)
290
LLVMPY_InstructionsIterNext(LLVMInstructionsIteratorRef GI) {
291
using namespace llvm;
292
InstructionsIterator *iter = unwrap(GI);
293
if (iter->cur != iter->end) {
294
return wrap(&*iter->cur++);
295
} else {
296
return NULL;
297
}
298
}
299
300
API_EXPORT(LLVMValueRef)
301
LLVMPY_OperandsIterNext(LLVMOperandsIteratorRef GI) {
302
using namespace llvm;
303
OperandsIterator *iter = unwrap(GI);
304
if (iter->cur != iter->end) {
305
return wrap((&*iter->cur++)->get());
306
} else {
307
return NULL;
308
}
309
}
310
311
API_EXPORT(LLVMValueRef)
312
LLVMPY_IncomingBlocksIterNext(LLVMIncomingBlocksIteratorRef GI) {
313
using namespace llvm;
314
IncomingBlocksIterator *iter = unwrap(GI);
315
if (iter->cur != iter->end) {
316
return wrap(static_cast<const Value *>(*iter->cur++));
317
} else {
318
return NULL;
319
}
320
}
321
322
API_EXPORT(void)
323
LLVMPY_DisposeAttributeListIter(LLVMAttributeListIteratorRef GI) {
324
delete llvm::unwrap(GI);
325
}
326
327
API_EXPORT(void)
328
LLVMPY_DisposeAttributeSetIter(LLVMAttributeSetIteratorRef GI) {
329
delete llvm::unwrap(GI);
330
}
331
332
API_EXPORT(void)
333
LLVMPY_DisposeBlocksIter(LLVMBlocksIteratorRef GI) { delete llvm::unwrap(GI); }
334
335
API_EXPORT(void)
336
LLVMPY_DisposeArgumentsIter(LLVMArgumentsIteratorRef GI) {
337
delete llvm::unwrap(GI);
338
}
339
340
API_EXPORT(void)
341
LLVMPY_DisposeInstructionsIter(LLVMInstructionsIteratorRef GI) {
342
delete llvm::unwrap(GI);
343
}
344
345
API_EXPORT(void)
346
LLVMPY_DisposeOperandsIter(LLVMOperandsIteratorRef GI) {
347
delete llvm::unwrap(GI);
348
}
349
350
API_EXPORT(void)
351
LLVMPY_DisposeIncomingBlocksIter(LLVMIncomingBlocksIteratorRef GI) {
352
delete llvm::unwrap(GI);
353
}
354
355
API_EXPORT(bool)
356
LLVMPY_IsConstant(LLVMValueRef Val) { return LLVMIsConstant(Val); }
357
358
API_EXPORT(const uint64_t *)
359
LLVMPY_GetConstantIntRawValue(LLVMValueRef Val, bool *littleEndian) {
360
if (littleEndian) {
361
*littleEndian = llvm::sys::IsLittleEndianHost;
362
}
363
if (llvm::ConstantInt *CI =
364
llvm::dyn_cast<llvm::ConstantInt>((llvm::Value *)Val)) {
365
return CI->getValue().getRawData();
366
}
367
return nullptr;
368
}
369
370
API_EXPORT(unsigned)
371
LLVMPY_GetConstantIntNumWords(LLVMValueRef Val) {
372
if (llvm::ConstantInt *CI =
373
llvm::dyn_cast<llvm::ConstantInt>((llvm::Value *)Val)) {
374
return CI->getValue().getNumWords();
375
}
376
return 0;
377
}
378
379
API_EXPORT(double)
380
LLVMPY_GetConstantFPValue(LLVMValueRef Val, bool *losesInfo) {
381
LLVMBool losesInfo_internal;
382
double result = LLVMConstRealGetDouble(Val, &losesInfo_internal);
383
if (losesInfo) {
384
*losesInfo = losesInfo_internal;
385
}
386
return result;
387
}
388
389
API_EXPORT(int)
390
LLVMPY_GetValueKind(LLVMValueRef Val) { return (int)LLVMGetValueKind(Val); }
391
392
API_EXPORT(void)
393
LLVMPY_PrintValueToString(LLVMValueRef Val, const char **outstr) {
394
*outstr = LLVMPrintValueToString(Val);
395
}
396
397
API_EXPORT(const char *)
398
LLVMPY_GetValueName(LLVMValueRef Val) { return LLVMGetValueName(Val); }
399
400
API_EXPORT(void)
401
LLVMPY_SetValueName(LLVMValueRef Val, const char *Name) {
402
LLVMSetValueName(Val, Name);
403
}
404
405
API_EXPORT(LLVMModuleRef)
406
LLVMPY_GetGlobalParent(LLVMValueRef Val) { return LLVMGetGlobalParent(Val); }
407
408
API_EXPORT(LLVMTypeRef)
409
LLVMPY_GlobalGetValueType(LLVMValueRef GlobalVal) {
410
return LLVMGlobalGetValueType(GlobalVal);
411
}
412
413
API_EXPORT(void)
414
LLVMPY_SetLinkage(LLVMValueRef Val, int Linkage) {
415
LLVMSetLinkage(Val, (LLVMLinkage)Linkage);
416
}
417
418
API_EXPORT(int)
419
LLVMPY_GetLinkage(LLVMValueRef Val) { return (int)LLVMGetLinkage(Val); }
420
421
API_EXPORT(void)
422
LLVMPY_SetVisibility(LLVMValueRef Val, int Visibility) {
423
LLVMSetVisibility(Val, (LLVMVisibility)Visibility);
424
}
425
426
API_EXPORT(int)
427
LLVMPY_GetVisibility(LLVMValueRef Val) { return (int)LLVMGetVisibility(Val); }
428
429
API_EXPORT(void)
430
LLVMPY_SetDLLStorageClass(LLVMValueRef Val, int DLLStorageClass) {
431
LLVMSetDLLStorageClass(Val, (LLVMDLLStorageClass)DLLStorageClass);
432
}
433
434
API_EXPORT(int)
435
LLVMPY_GetDLLStorageClass(LLVMValueRef Val) {
436
return (int)LLVMGetDLLStorageClass(Val);
437
}
438
439
API_EXPORT(unsigned)
440
LLVMPY_GetEnumAttributeKindForName(const char *name, size_t len) {
441
/* zero is returned if no match */
442
return LLVMGetEnumAttributeKindForName(name, len);
443
}
444
445
API_EXPORT(void)
446
LLVMPY_AddFunctionAttr(LLVMValueRef Fn, unsigned AttrKind) {
447
LLVMContextRef ctx = LLVMGetModuleContext(LLVMGetGlobalParent(Fn));
448
LLVMAttributeRef attr_ref = LLVMCreateEnumAttribute(ctx, AttrKind, 0);
449
LLVMAddAttributeAtIndex(Fn, LLVMAttributeReturnIndex, attr_ref);
450
}
451
452
API_EXPORT(int)
453
LLVMPY_IsDeclaration(LLVMValueRef GV) { return LLVMIsDeclaration(GV); }
454
455
API_EXPORT(void)
456
LLVMPY_WriteCFG(LLVMValueRef Fval, const char **OutStr, int ShowInst) {
457
using namespace llvm;
458
Function *F = unwrap<Function>(Fval);
459
std::string buffer;
460
raw_string_ostream stream(buffer);
461
DOTFuncInfo CFGInfo(F, nullptr, nullptr, 0);
462
WriteGraph(stream, &CFGInfo, !ShowInst);
463
*OutStr = LLVMPY_CreateString(stream.str().c_str());
464
}
465
466
API_EXPORT(const char *)
467
LLVMPY_GetOpcodeName(LLVMValueRef Val) {
468
// try to convert to an instruction value, works for other derived
469
// types too
470
llvm::Value *unwrapped = llvm::unwrap(Val);
471
llvm::Instruction *inst = llvm::dyn_cast<llvm::Instruction>(unwrapped);
472
if (inst) {
473
return LLVMPY_CreateString(inst->getOpcodeName());
474
}
475
return LLVMPY_CreateString("");
476
}
477
478
} // end extern "C"
479
480