@@ -54,13 +54,15 @@ enum OperandKind {
54
54
Type,
55
55
Function,
56
56
Block,
57
+ Arg,
57
58
UnimplementedOperand = 255 ,
58
59
};
59
60
60
61
enum TypeKind {
61
62
Void = 0 ,
62
63
Integer,
63
64
Ptr,
65
+ FunctionTy,
64
66
UnimplementedType = 255 , // YKFIXME: Will eventually be deleted.
65
67
};
66
68
@@ -132,8 +134,17 @@ class YkIRWriter {
132
134
if (Found != Types.end ()) {
133
135
return std::distance (Types.begin (), Found);
134
136
}
137
+
138
+ // Not found. Assign it a type index.
135
139
size_t Idx = Types.size ();
136
140
Types.push_back (Ty);
141
+
142
+ // If the newly-registered type is an aggregate type that contains other
143
+ // types, then assign them type indices now too.
144
+ for (llvm::Type *STy : Ty->subtypes ()) {
145
+ typeIndex (STy);
146
+ }
147
+
137
148
return Idx;
138
149
}
139
150
@@ -205,12 +216,20 @@ class YkIRWriter {
205
216
serialiseString (toString (V));
206
217
}
207
218
219
+ void serialiseArgOperand (ValueLoweringMap &VLMap, Argument *A) {
220
+ // This assumes that the argument indices match in both IRs.
221
+ OutStreamer.emitInt8 (OperandKind::Arg);
222
+ OutStreamer.emitSizeT (A->getArgNo ());
223
+ }
224
+
208
225
void serialiseOperand (Instruction *Parent, ValueLoweringMap &VLMap,
209
226
Value *V) {
210
227
if (llvm::Function *F = dyn_cast<llvm::Function>(V)) {
211
228
serialiseFunctionOperand (F);
212
229
} else if (llvm::Constant *C = dyn_cast<llvm::Constant>(V)) {
213
230
serialiseConstantOperand (Parent, C);
231
+ } else if (llvm::Argument *A = dyn_cast<llvm::Argument>(V)) {
232
+ serialiseArgOperand (VLMap, A);
214
233
} else if (Instruction *I = dyn_cast<Instruction>(V)) {
215
234
// If an instruction defines the operand, it's a local variable.
216
235
serialiseLocalVariableOperand (I, VLMap);
@@ -371,9 +390,16 @@ class YkIRWriter {
371
390
BBIdx++;
372
391
}
373
392
393
+ void serialiseArg (Argument *A) {
394
+ // type_index:
395
+ OutStreamer.emitSizeT (typeIndex (A->getType ()));
396
+ }
397
+
374
398
void serialiseFunc (llvm::Function &F) {
375
399
// name:
376
400
serialiseString (F.getName ());
401
+ // type_idx:
402
+ OutStreamer.emitSizeT (typeIndex (F.getFunctionType ()));
377
403
// num_blocks:
378
404
OutStreamer.emitSizeT (F.size ());
379
405
// blocks:
@@ -384,6 +410,20 @@ class YkIRWriter {
384
410
}
385
411
}
386
412
413
+ void serialiseFunctionType (FunctionType *Ty) {
414
+ OutStreamer.emitInt8 (TypeKind::FunctionTy);
415
+ // num_args:
416
+ OutStreamer.emitSizeT (Ty->getNumParams ());
417
+ // arg_tys:
418
+ for (llvm::Type *SubTy : Ty->params ()) {
419
+ OutStreamer.emitSizeT (typeIndex (SubTy));
420
+ }
421
+ // ret_ty:
422
+ OutStreamer.emitSizeT (typeIndex (Ty->getReturnType ()));
423
+ // is_vararg:
424
+ OutStreamer.emitInt8 (Ty->isVarArg ());
425
+ }
426
+
387
427
void serialiseType (llvm::Type *Ty) {
388
428
if (Ty->isVoidTy ()) {
389
429
OutStreamer.emitInt8 (TypeKind::Void);
@@ -392,6 +432,8 @@ class YkIRWriter {
392
432
} else if (IntegerType *ITy = dyn_cast<IntegerType>(Ty)) {
393
433
OutStreamer.emitInt8 (TypeKind::Integer);
394
434
OutStreamer.emitInt32 (ITy->getBitWidth ());
435
+ } else if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
436
+ serialiseFunctionType (FTy);
395
437
} else {
396
438
OutStreamer.emitInt8 (TypeKind::UnimplementedType);
397
439
serialiseString (toString (Ty));
0 commit comments