@@ -54,13 +54,15 @@ enum OperandKind {
5454 Type,
5555 Function,
5656 Block,
57+ Arg,
5758 UnimplementedOperand = 255 ,
5859};
5960
6061enum TypeKind {
6162 Void = 0 ,
6263 Integer,
6364 Ptr,
65+ FunctionTy,
6466 UnimplementedType = 255 , // YKFIXME: Will eventually be deleted.
6567};
6668
@@ -132,8 +134,17 @@ class YkIRWriter {
132134 if (Found != Types.end ()) {
133135 return std::distance (Types.begin (), Found);
134136 }
137+
138+ // Not found. Assign it a type index.
135139 size_t Idx = Types.size ();
136140 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+
137148 return Idx;
138149 }
139150
@@ -205,12 +216,20 @@ class YkIRWriter {
205216 serialiseString (toString (V));
206217 }
207218
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+
208225 void serialiseOperand (Instruction *Parent, ValueLoweringMap &VLMap,
209226 Value *V) {
210227 if (llvm::Function *F = dyn_cast<llvm::Function>(V)) {
211228 serialiseFunctionOperand (F);
212229 } else if (llvm::Constant *C = dyn_cast<llvm::Constant>(V)) {
213230 serialiseConstantOperand (Parent, C);
231+ } else if (llvm::Argument *A = dyn_cast<llvm::Argument>(V)) {
232+ serialiseArgOperand (VLMap, A);
214233 } else if (Instruction *I = dyn_cast<Instruction>(V)) {
215234 // If an instruction defines the operand, it's a local variable.
216235 serialiseLocalVariableOperand (I, VLMap);
@@ -371,9 +390,16 @@ class YkIRWriter {
371390 BBIdx++;
372391 }
373392
393+ void serialiseArg (Argument *A) {
394+ // type_index:
395+ OutStreamer.emitSizeT (typeIndex (A->getType ()));
396+ }
397+
374398 void serialiseFunc (llvm::Function &F) {
375399 // name:
376400 serialiseString (F.getName ());
401+ // type_idx:
402+ OutStreamer.emitSizeT (typeIndex (F.getFunctionType ()));
377403 // num_blocks:
378404 OutStreamer.emitSizeT (F.size ());
379405 // blocks:
@@ -384,6 +410,20 @@ class YkIRWriter {
384410 }
385411 }
386412
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+
387427 void serialiseType (llvm::Type *Ty) {
388428 if (Ty->isVoidTy ()) {
389429 OutStreamer.emitInt8 (TypeKind::Void);
@@ -392,6 +432,8 @@ class YkIRWriter {
392432 } else if (IntegerType *ITy = dyn_cast<IntegerType>(Ty)) {
393433 OutStreamer.emitInt8 (TypeKind::Integer);
394434 OutStreamer.emitInt32 (ITy->getBitWidth ());
435+ } else if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
436+ serialiseFunctionType (FTy);
395437 } else {
396438 OutStreamer.emitInt8 (TypeKind::UnimplementedType);
397439 serialiseString (toString (Ty));
0 commit comments