@@ -42,6 +42,7 @@ enum OpCode {
4242 Call,
4343 GetElementPtr,
4444 Branch,
45+ CondBranch,
4546 ICmp,
4647 BinaryOperator,
4748 Ret,
@@ -53,6 +54,7 @@ enum OperandKind {
5354 LocalVariable,
5455 Type,
5556 Function,
57+ Block,
5658 UnimplementedOperand = 255 ,
5759};
5860
@@ -189,6 +191,13 @@ class YkIRWriter {
189191 OutStreamer.emitSizeT (functionIndex (F));
190192 }
191193
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+
192201 // YKFIXME: This allows programs which we haven't yet defined a
193202 // lowering for to compile. For now We just emit a string operand containing
194203 // the unhandled LLVM operand in textual form.
@@ -206,6 +215,8 @@ class YkIRWriter {
206215 } else if (Instruction *I = dyn_cast<Instruction>(V)) {
207216 // If an instruction defines the operand, it's a local variable.
208217 serialiseLocalVariableOperand (I, VLMap);
218+ } else if (BasicBlock *BB = dyn_cast<BasicBlock>(V)) {
219+ serialiseBlockOperand (BB, VLMap);
209220 } else {
210221 serialiseUnimplementedOperand (V);
211222 }
@@ -277,6 +288,28 @@ class YkIRWriter {
277288 InstIdx++;
278289 }
279290
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::Branch);
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::CondBranch);
310+ }
311+ }
312+
280313 void serialiseInst (Instruction *I, ValueLoweringMap &VLMap, unsigned BBIdx,
281314 unsigned &InstIdx) {
282315// Macros to help dispatch to serialisers.
@@ -296,13 +329,13 @@ class YkIRWriter {
296329 GENERIC_INST_SERIALISE (I, LoadInst, Load)
297330 GENERIC_INST_SERIALISE (I, StoreInst, Store)
298331 GENERIC_INST_SERIALISE (I, GetElementPtrInst, GetElementPtr)
299- GENERIC_INST_SERIALISE (I, BranchInst, Branch)
300332 GENERIC_INST_SERIALISE (I, ICmpInst, ICmp)
301333 GENERIC_INST_SERIALISE (I, llvm::BinaryOperator, BinaryOperator)
302334 GENERIC_INST_SERIALISE (I, ReturnInst, Ret)
303335
304336 CUSTOM_INST_SERIALISE (I, AllocaInst, serialiseAllocaInst)
305337 CUSTOM_INST_SERIALISE (I, CallInst, serialiseCallInst)
338+ CUSTOM_INST_SERIALISE (I, BranchInst, serialiseBranchInst)
306339
307340 // GENERIC_INST_SERIALISE and CUSTOM_INST_SERIALISE do an early return upon
308341 // a match, so if we get here then the instruction wasn't handled.
0 commit comments