7
7
#include " llvm/BinaryFormat/ELF.h"
8
8
#include " llvm/IR/Constant.h"
9
9
#include " llvm/IR/Constants.h"
10
+ #include " llvm/IR/GlobalValue.h"
10
11
#include " llvm/IR/InstrTypes.h"
11
12
#include " llvm/IR/Instructions.h"
12
13
#include " llvm/IR/Module.h"
@@ -39,13 +40,13 @@ enum OpCode {
39
40
Store,
40
41
Alloca,
41
42
Call,
42
- GetElementPtr,
43
43
Br,
44
44
CondBr,
45
45
ICmp,
46
46
BinaryOperator,
47
47
Ret,
48
48
InsertValue,
49
+ PtrAdd,
49
50
UnimplementedInstruction = 255 , // YKFIXME: Will eventually be deleted.
50
51
};
51
52
@@ -56,6 +57,7 @@ enum OperandKind {
56
57
Function,
57
58
Block,
58
59
Arg,
60
+ Global,
59
61
UnimplementedOperand = 255 ,
60
62
};
61
63
@@ -124,9 +126,11 @@ class YkIRWriter {
124
126
private:
125
127
Module &M;
126
128
MCStreamer &OutStreamer;
129
+ DataLayout DL;
127
130
128
131
vector<llvm::Type *> Types;
129
132
vector<llvm::Constant *> Constants;
133
+ vector<llvm::GlobalVariable *> Globals;
130
134
131
135
// Return the index of the LLVM type `Ty`, inserting a new entry if
132
136
// necessary.
@@ -163,6 +167,19 @@ class YkIRWriter {
163
167
return Idx;
164
168
}
165
169
170
+ // Return the index of the LLVM global `G`, inserting a new entry if
171
+ // necessary.
172
+ size_t globalIndex (class GlobalVariable *G) {
173
+ vector<class GlobalVariable *>::iterator Found =
174
+ std::find (Globals.begin (), Globals.end (), G);
175
+ if (Found != Globals.end ()) {
176
+ return std::distance (Globals.begin (), Found);
177
+ }
178
+ size_t Idx = Globals.size ();
179
+ Globals.push_back (G);
180
+ return Idx;
181
+ }
182
+
166
183
size_t functionIndex (llvm::Function *F) {
167
184
// FIXME: For now we assume that function indicies in LLVM IR and our IR
168
185
// are the same.
@@ -220,9 +237,16 @@ class YkIRWriter {
220
237
OutStreamer.emitSizeT (A->getArgNo ());
221
238
}
222
239
240
+ void serialiseGlobalOperand (GlobalVariable *G) {
241
+ OutStreamer.emitInt8 (OperandKind::Global);
242
+ OutStreamer.emitSizeT (globalIndex (G));
243
+ }
244
+
223
245
void serialiseOperand (Instruction *Parent, ValueLoweringMap &VLMap,
224
246
Value *V) {
225
- if (llvm::Function *F = dyn_cast<llvm::Function>(V)) {
247
+ if (llvm::GlobalVariable *G = dyn_cast<llvm::GlobalVariable>(V)) {
248
+ serialiseGlobalOperand (G);
249
+ } else if (llvm::Function *F = dyn_cast<llvm::Function>(V)) {
226
250
serialiseFunctionOperand (F);
227
251
} else if (llvm::Constant *C = dyn_cast<llvm::Constant>(V)) {
228
252
serialiseConstantOperand (Parent, C);
@@ -326,6 +350,30 @@ class YkIRWriter {
326
350
}
327
351
}
328
352
353
+ void serialiseGetElementPtr (GetElementPtrInst *I, ValueLoweringMap &VLMap,
354
+ unsigned BBIdx, unsigned &InstIdx) {
355
+ unsigned BitWidth = 64 ;
356
+ MapVector<Value *, APInt> Offsets;
357
+ APInt Offset (BitWidth, 0 );
358
+
359
+ bool Res = I->collectOffset (DL, BitWidth, Offsets, Offset);
360
+ assert (Res);
361
+
362
+ // type_index:
363
+ OutStreamer.emitSizeT (typeIndex (I->getType ()));
364
+ // opcode:
365
+ serialiseOpcode (OpCode::PtrAdd);
366
+ // num_operands:
367
+ OutStreamer.emitInt32 (2 );
368
+ // pointer:
369
+ serialiseOperand (I, VLMap, I->getPointerOperand ());
370
+ // offset:
371
+ serialiseOperand (I, VLMap, ConstantInt::get (I->getContext (), Offset));
372
+
373
+ VLMap[I] = {BBIdx, InstIdx};
374
+ InstIdx++;
375
+ }
376
+
329
377
void serialiseInst (Instruction *I, ValueLoweringMap &VLMap, unsigned BBIdx,
330
378
unsigned &InstIdx) {
331
379
// Macros to help dispatch to serialisers.
@@ -344,15 +392,16 @@ class YkIRWriter {
344
392
345
393
GENERIC_INST_SERIALISE (I, LoadInst, Load)
346
394
GENERIC_INST_SERIALISE (I, StoreInst, Store)
347
- GENERIC_INST_SERIALISE (I, GetElementPtrInst, GetElementPtr)
348
395
GENERIC_INST_SERIALISE (I, ICmpInst, ICmp)
349
396
GENERIC_INST_SERIALISE (I, llvm::BinaryOperator, BinaryOperator)
350
397
GENERIC_INST_SERIALISE (I, ReturnInst, Ret)
351
398
GENERIC_INST_SERIALISE (I, llvm::InsertValueInst, InsertValue)
399
+ GENERIC_INST_SERIALISE (I, StoreInst, Store)
352
400
353
401
CUSTOM_INST_SERIALISE (I, AllocaInst, serialiseAllocaInst)
354
402
CUSTOM_INST_SERIALISE (I, CallInst, serialiseCallInst)
355
403
CUSTOM_INST_SERIALISE (I, BranchInst, serialiseBranchInst)
404
+ CUSTOM_INST_SERIALISE (I, GetElementPtrInst, serialiseGetElementPtr)
356
405
357
406
// GENERIC_INST_SERIALISE and CUSTOM_INST_SERIALISE do an early return upon
358
407
// a match, so if we get here then the instruction wasn't handled.
@@ -485,9 +534,14 @@ class YkIRWriter {
485
534
}
486
535
}
487
536
537
+ void serialiseGlobal (class GlobalVariable *G) {
538
+ OutStreamer.emitInt8 (G->isThreadLocal ());
539
+ serialiseString (G->getName ());
540
+ }
541
+
488
542
public:
489
543
YkIRWriter (Module &M, MCStreamer &OutStreamer)
490
- : M(M), OutStreamer(OutStreamer) {}
544
+ : M(M), OutStreamer(OutStreamer), DL(&M) {}
491
545
492
546
// Entry point for IR serialisation.
493
547
//
@@ -516,6 +570,13 @@ class YkIRWriter {
516
570
serialiseConstant (C);
517
571
}
518
572
573
+ // num_globals:
574
+ OutStreamer.emitSizeT (Globals.size ());
575
+ // globals:
576
+ for (class GlobalVariable *&G : Globals) {
577
+ serialiseGlobal (G);
578
+ }
579
+
519
580
// num_types:
520
581
OutStreamer.emitSizeT (Types.size ());
521
582
// types:
0 commit comments