@@ -41,7 +41,8 @@ enum OpCode {
41
41
Alloca,
42
42
Call,
43
43
GetElementPtr,
44
- Branch,
44
+ Br,
45
+ CondBr,
45
46
ICmp,
46
47
BinaryOperator,
47
48
Ret,
@@ -53,6 +54,7 @@ enum OperandKind {
53
54
LocalVariable,
54
55
Type,
55
56
Function,
57
+ Block,
56
58
UnimplementedOperand = 255 ,
57
59
};
58
60
@@ -189,6 +191,13 @@ class YkIRWriter {
189
191
OutStreamer.emitSizeT (functionIndex (F));
190
192
}
191
193
194
+ void serialiseBlockOperand (BasicBlock *BB, ValueLoweringMap &VLMap) {
195
+ OutStreamer.emitInt8 (OperandKind::Block);
196
+ // FIXME: For now we assume that basic block indices are the same in LLVM
197
+ // IR and our IR.
198
+ OutStreamer.emitSizeT (getIndex (BB->getParent (), BB));
199
+ }
200
+
192
201
// YKFIXME: This allows programs which we haven't yet defined a
193
202
// lowering for to compile. For now We just emit a string operand containing
194
203
// the unhandled LLVM operand in textual form.
@@ -206,6 +215,8 @@ class YkIRWriter {
206
215
} else if (Instruction *I = dyn_cast<Instruction>(V)) {
207
216
// If an instruction defines the operand, it's a local variable.
208
217
serialiseLocalVariableOperand (I, VLMap);
218
+ } else if (BasicBlock *BB = dyn_cast<BasicBlock>(V)) {
219
+ serialiseBlockOperand (BB, VLMap);
209
220
} else {
210
221
serialiseUnimplementedOperand (V);
211
222
}
@@ -277,6 +288,28 @@ class YkIRWriter {
277
288
InstIdx++;
278
289
}
279
290
291
+ void serialiseBranchInst (BranchInst *I, ValueLoweringMap &VLMap,
292
+ unsigned BBIdx, unsigned InstIdx) {
293
+ // We split LLVM's `br` into two Yk IR instructions: one for unconditional
294
+ // branching, another for conidtional branching.
295
+ if (!I->isConditional ()) {
296
+ // type_index:
297
+ OutStreamer.emitSizeT (typeIndex (I->getType ()));
298
+ // opcode:
299
+ serialiseOpcode (OpCode::Br);
300
+ // num_operands:
301
+ // We don't serialise any operands, because traces will guide us.
302
+ OutStreamer.emitInt32 (0 );
303
+
304
+ VLMap[I] = {BBIdx, InstIdx};
305
+ InstIdx++;
306
+ } else {
307
+ // We DO need operands for conditional branches, so that we can build
308
+ // guards.
309
+ serialiseInstGeneric (I, VLMap, BBIdx, InstIdx, OpCode::CondBr);
310
+ }
311
+ }
312
+
280
313
void serialiseInst (Instruction *I, ValueLoweringMap &VLMap, unsigned BBIdx,
281
314
unsigned &InstIdx) {
282
315
// Macros to help dispatch to serialisers.
@@ -296,13 +329,13 @@ class YkIRWriter {
296
329
GENERIC_INST_SERIALISE (I, LoadInst, Load)
297
330
GENERIC_INST_SERIALISE (I, StoreInst, Store)
298
331
GENERIC_INST_SERIALISE (I, GetElementPtrInst, GetElementPtr)
299
- GENERIC_INST_SERIALISE (I, BranchInst, Branch)
300
332
GENERIC_INST_SERIALISE (I, ICmpInst, ICmp)
301
333
GENERIC_INST_SERIALISE (I, llvm::BinaryOperator, BinaryOperator)
302
334
GENERIC_INST_SERIALISE (I, ReturnInst, Ret)
303
335
304
336
CUSTOM_INST_SERIALISE (I, AllocaInst, serialiseAllocaInst)
305
337
CUSTOM_INST_SERIALISE (I, CallInst, serialiseCallInst)
338
+ CUSTOM_INST_SERIALISE (I, BranchInst, serialiseBranchInst)
306
339
307
340
// GENERIC_INST_SERIALISE and CUSTOM_INST_SERIALISE do an early return upon
308
341
// a match, so if we get here then the instruction wasn't handled.
0 commit comments