@@ -51,6 +51,7 @@ enum OpCode {
5151enum OperandKind {
5252 Constant = 0 ,
5353 LocalVariable,
54+ Type,
5455 UnimplementedOperand = 255 ,
5556};
5657
@@ -123,8 +124,9 @@ class YkIRWriter {
123124
124125 // Return the index of the LLVM type `Ty`, inserting a new entry if
125126 // 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);
128130 if (Found != Types.end ()) {
129131 return std::distance (Types.begin (), Found);
130132 }
@@ -211,29 +213,61 @@ class YkIRWriter {
211213 InstIdx++;
212214 }
213215
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+
214242 void serialiseInst (Instruction *I, ValueLoweringMap &VLMap, unsigned BBIdx,
215243 unsigned &InstIdx) {
216- // Macro to help dispatch to generic lowering .
244+ // Macros to help dispatch to serialisers .
217245//
218246// Note that this is unhygenic so as to make the call-sites readable.
219247#define GENERIC_INST_SERIALISE (LLVM_INST, LLVM_INST_TYPE, YKIR_OPCODE ) \
220248 if (isa<LLVM_INST_TYPE>(LLVM_INST)) { \
221249 serialiseInstGeneric (LLVM_INST, VLMap, BBIdx, InstIdx, YKIR_OPCODE); \
222250 return ; \
223251 }
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+ }
224257
225258 GENERIC_INST_SERIALISE (I, LoadInst, Load)
226259 GENERIC_INST_SERIALISE (I, StoreInst, Store)
227- GENERIC_INST_SERIALISE (I, AllocaInst, Alloca)
228260 GENERIC_INST_SERIALISE (I, CallInst, Call)
229261 GENERIC_INST_SERIALISE (I, GetElementPtrInst, GetElementPtr)
230262 GENERIC_INST_SERIALISE (I, BranchInst, Branch)
231263 GENERIC_INST_SERIALISE (I, ICmpInst, ICmp)
232264 GENERIC_INST_SERIALISE (I, llvm::BinaryOperator, BinaryOperator)
233265 GENERIC_INST_SERIALISE (I, ReturnInst, Ret)
234266
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.
237271 serialiseUnimplementedInstruction (I, VLMap, BBIdx, InstIdx);
238272 }
239273
@@ -280,7 +314,7 @@ class YkIRWriter {
280314 }
281315 }
282316
283- void serialiseType (Type *Ty) {
317+ void serialiseType (llvm:: Type *Ty) {
284318 if (Ty->isVoidTy ()) {
285319 OutStreamer.emitInt8 (TypeKind::Void);
286320 } else if (Ty->isPointerTy ()) {
@@ -341,7 +375,7 @@ class YkIRWriter {
341375 // num_types:
342376 OutStreamer.emitSizeT (Types.size ());
343377 // types:
344- for (Type *&Ty : Types) {
378+ for (llvm:: Type *&Ty : Types) {
345379 serialiseType (Ty);
346380 }
347381 }
0 commit comments