@@ -51,6 +51,7 @@ enum OpCode {
51
51
enum OperandKind {
52
52
Constant = 0 ,
53
53
LocalVariable,
54
+ Type,
54
55
UnimplementedOperand = 255 ,
55
56
};
56
57
@@ -123,8 +124,9 @@ class YkIRWriter {
123
124
124
125
// Return the index of the LLVM type `Ty`, inserting a new entry if
125
126
// necessary.
126
- size_t typeIndex (Type *Ty) {
127
- vector<Type *>::iterator Found = std::find (Types.begin (), Types.end (), Ty);
127
+ size_t typeIndex (llvm::Type *Ty) {
128
+ vector<llvm::Type *>::iterator Found =
129
+ std::find (Types.begin (), Types.end (), Ty);
128
130
if (Found != Types.end ()) {
129
131
return std::distance (Types.begin (), Found);
130
132
}
@@ -211,29 +213,61 @@ class YkIRWriter {
211
213
InstIdx++;
212
214
}
213
215
216
+ void serialiseAllocaInst (AllocaInst *I, ValueLoweringMap &VLMap,
217
+ unsigned BBIdx, unsigned InstIdx) {
218
+ // type_index:
219
+ OutStreamer.emitSizeT (typeIndex (I->getType ()));
220
+ // opcode:
221
+ serialiseOpcode (OpCode::Alloca);
222
+ // num_operands:
223
+ OutStreamer.emitInt32 (2 );
224
+
225
+ // OPERAND 0: allocated type
226
+ // Needs custom serialisation: not stored in the instruction's operand list.
227
+ //
228
+ // operand_kind:
229
+ OutStreamer.emitInt8 (OperandKind::Type);
230
+ // type_index
231
+ OutStreamer.emitSizeT (typeIndex (I->getAllocatedType ()));
232
+
233
+ // OPERAND 1: number of objects to allocate
234
+ Value *Op0 = I->getOperand (0 );
235
+ assert (isa<ConstantInt>(Op0));
236
+ serialiseOperand (I, VLMap, Op0);
237
+
238
+ VLMap[I] = {BBIdx, InstIdx};
239
+ InstIdx++;
240
+ }
241
+
214
242
void serialiseInst (Instruction *I, ValueLoweringMap &VLMap, unsigned BBIdx,
215
243
unsigned &InstIdx) {
216
- // Macro to help dispatch to generic lowering .
244
+ // Macros to help dispatch to serialisers .
217
245
//
218
246
// Note that this is unhygenic so as to make the call-sites readable.
219
247
#define GENERIC_INST_SERIALISE (LLVM_INST, LLVM_INST_TYPE, YKIR_OPCODE ) \
220
248
if (isa<LLVM_INST_TYPE>(LLVM_INST)) { \
221
249
serialiseInstGeneric (LLVM_INST, VLMap, BBIdx, InstIdx, YKIR_OPCODE); \
222
250
return ; \
223
251
}
252
+ #define CUSTOM_INST_SERIALISE (LLVM_INST, LLVM_INST_TYPE, SERIALISER ) \
253
+ if (LLVM_INST_TYPE *II = dyn_cast<LLVM_INST_TYPE>(LLVM_INST)) { \
254
+ SERIALISER (II, VLMap, BBIdx, InstIdx); \
255
+ return ; \
256
+ }
224
257
225
258
GENERIC_INST_SERIALISE (I, LoadInst, Load)
226
259
GENERIC_INST_SERIALISE (I, StoreInst, Store)
227
- GENERIC_INST_SERIALISE (I, AllocaInst, Alloca)
228
260
GENERIC_INST_SERIALISE (I, CallInst, Call)
229
261
GENERIC_INST_SERIALISE (I, GetElementPtrInst, GetElementPtr)
230
262
GENERIC_INST_SERIALISE (I, BranchInst, Branch)
231
263
GENERIC_INST_SERIALISE (I, ICmpInst, ICmp)
232
264
GENERIC_INST_SERIALISE (I, llvm::BinaryOperator, BinaryOperator)
233
265
GENERIC_INST_SERIALISE (I, ReturnInst, Ret)
234
266
235
- // GENERIC_INST_SERIALISE does an early return upon a match, so if we get
236
- // here then the instruction wasn't handled.
267
+ CUSTOM_INST_SERIALISE (I, AllocaInst, serialiseAllocaInst)
268
+
269
+ // GENERIC_INST_SERIALISE and CUSTOM_INST_SERIALISE do an early return upon
270
+ // a match, so if we get here then the instruction wasn't handled.
237
271
serialiseUnimplementedInstruction (I, VLMap, BBIdx, InstIdx);
238
272
}
239
273
@@ -280,7 +314,7 @@ class YkIRWriter {
280
314
}
281
315
}
282
316
283
- void serialiseType (Type *Ty) {
317
+ void serialiseType (llvm:: Type *Ty) {
284
318
if (Ty->isVoidTy ()) {
285
319
OutStreamer.emitInt8 (TypeKind::Void);
286
320
} else if (Ty->isPointerTy ()) {
@@ -341,7 +375,7 @@ class YkIRWriter {
341
375
// num_types:
342
376
OutStreamer.emitSizeT (Types.size ());
343
377
// types:
344
- for (Type *&Ty : Types) {
378
+ for (llvm:: Type *&Ty : Types) {
345
379
serialiseType (Ty);
346
380
}
347
381
}
0 commit comments