@@ -52,6 +52,7 @@ enum OperandKind {
52
52
Constant = 0 ,
53
53
LocalVariable,
54
54
Type,
55
+ Function,
55
56
UnimplementedOperand = 255 ,
56
57
};
57
58
@@ -148,6 +149,12 @@ class YkIRWriter {
148
149
return Idx;
149
150
}
150
151
152
+ size_t functionIndex (llvm::Function *F) {
153
+ // FIXME: For now we assume that function indicies in LLVM IR and our IR
154
+ // are the same.
155
+ return getIndex (&M, F);
156
+ }
157
+
151
158
public:
152
159
YkIRWriter (Module &M, MCStreamer &OutStreamer)
153
160
: M(M), OutStreamer(OutStreamer) {}
@@ -177,6 +184,11 @@ class YkIRWriter {
177
184
serialiseString (S);
178
185
}
179
186
187
+ void serialiseFunctionOperand (llvm::Function *F) {
188
+ OutStreamer.emitInt8 (OperandKind::Function);
189
+ OutStreamer.emitSizeT (functionIndex (F));
190
+ }
191
+
180
192
// YKFIXME: This allows programs which we haven't yet defined a
181
193
// lowering for to compile. For now We just emit a string operand containing
182
194
// the unhandled LLVM operand in textual form.
@@ -187,7 +199,9 @@ class YkIRWriter {
187
199
188
200
void serialiseOperand (Instruction *Parent, ValueLoweringMap &VLMap,
189
201
Value *V) {
190
- if (llvm::Constant *C = dyn_cast<llvm::Constant>(V)) {
202
+ if (llvm::Function *F = dyn_cast<llvm::Function>(V)) {
203
+ serialiseFunctionOperand (F);
204
+ } else if (llvm::Constant *C = dyn_cast<llvm::Constant>(V)) {
191
205
serialiseConstantOperand (Parent, C);
192
206
} else if (Instruction *I = dyn_cast<Instruction>(V)) {
193
207
// If an instruction defines the operand, it's a local variable.
@@ -239,6 +253,30 @@ class YkIRWriter {
239
253
InstIdx++;
240
254
}
241
255
256
+ void serialiseCallInst (CallInst *I, ValueLoweringMap &VLMap, unsigned BBIdx,
257
+ unsigned InstIdx) {
258
+ // type_index:
259
+ OutStreamer.emitSizeT (typeIndex (I->getType ()));
260
+ // opcode:
261
+ serialiseOpcode (OpCode::Call);
262
+ // num_operands:
263
+ unsigned NumOpers = I->getNumOperands ();
264
+ OutStreamer.emitInt32 (NumOpers);
265
+
266
+ // OPERAND 0: What to call.
267
+ //
268
+ // In LLVM IR this is the final operand, which is a cause of confusion.
269
+ serialiseOperand (I, VLMap, I->getOperand (NumOpers - 1 ));
270
+
271
+ // Now the rest of the operands.
272
+ for (unsigned OI = 0 ; OI < NumOpers - 1 ; OI++) {
273
+ serialiseOperand (I, VLMap, I->getOperand (OI));
274
+ }
275
+
276
+ VLMap[I] = {BBIdx, InstIdx};
277
+ InstIdx++;
278
+ }
279
+
242
280
void serialiseInst (Instruction *I, ValueLoweringMap &VLMap, unsigned BBIdx,
243
281
unsigned &InstIdx) {
244
282
// Macros to help dispatch to serialisers.
@@ -257,14 +295,14 @@ class YkIRWriter {
257
295
258
296
GENERIC_INST_SERIALISE (I, LoadInst, Load)
259
297
GENERIC_INST_SERIALISE (I, StoreInst, Store)
260
- GENERIC_INST_SERIALISE (I, CallInst, Call)
261
298
GENERIC_INST_SERIALISE (I, GetElementPtrInst, GetElementPtr)
262
299
GENERIC_INST_SERIALISE (I, BranchInst, Branch)
263
300
GENERIC_INST_SERIALISE (I, ICmpInst, ICmp)
264
301
GENERIC_INST_SERIALISE (I, llvm::BinaryOperator, BinaryOperator)
265
302
GENERIC_INST_SERIALISE (I, ReturnInst, Ret)
266
303
267
304
CUSTOM_INST_SERIALISE (I, AllocaInst, serialiseAllocaInst)
305
+ CUSTOM_INST_SERIALISE (I, CallInst, serialiseCallInst)
268
306
269
307
// GENERIC_INST_SERIALISE and CUSTOM_INST_SERIALISE do an early return upon
270
308
// a match, so if we get here then the instruction wasn't handled.
@@ -301,7 +339,7 @@ class YkIRWriter {
301
339
BBIdx++;
302
340
}
303
341
304
- void serialiseFunc (Function &F) {
342
+ void serialiseFunc (llvm:: Function &F) {
305
343
// name:
306
344
serialiseString (F.getName ());
307
345
// num_blocks:
@@ -361,7 +399,7 @@ class YkIRWriter {
361
399
// num_funcs:
362
400
OutStreamer.emitSizeT (M.size ());
363
401
// funcs:
364
- for (Function &F : M) {
402
+ for (llvm:: Function &F : M) {
365
403
serialiseFunc (F);
366
404
}
367
405
0 commit comments