@@ -56,6 +56,7 @@ enum OpCode {
56
56
OpCodePHI,
57
57
OpCodeIndirectCall,
58
58
OpCodeSelect,
59
+ OpCodeLoadArg,
59
60
OpCodeUnimplemented = 255 , // YKFIXME: Will eventually be deleted.
60
61
};
61
62
@@ -184,6 +185,8 @@ class FuncLowerCtxt {
184
185
public:
185
186
// Create an empty function lowering context.
186
187
FuncLowerCtxt () : VLMap(ValueLoweringMap()), InstIdxPatchUps({}){};
188
+ // Maps argument operands to LoadArg instructions.
189
+ map<Argument *, InstIdx> ArgumentMap;
187
190
188
191
// Defer (patch up later) the use-site of the (as-yet unknown) instruction
189
192
// index of the instruction `I`, which has the symbol `Sym`.
@@ -349,15 +352,19 @@ class YkIRWriter {
349
352
OutStreamer.emitSizeT (getIndex (BB->getParent (), BB));
350
353
}
351
354
352
- void serialiseArgOperand (Argument *A) {
353
- // This assumes that the argument indices match in both IRs.
354
-
355
- // opcode:
356
- serialiseOperandKind (OperandKindArg);
357
- // parent function index:
355
+ void serialiseArgOperand (Argument *A, FuncLowerCtxt &FLCtxt) {
356
+ // operand kind:
357
+ serialiseOperandKind (OperandKindLocal);
358
+ // func_idx:
358
359
OutStreamer.emitSizeT (getIndex (&M, A->getParent ()));
359
- // arg index
360
- OutStreamer.emitSizeT (A->getArgNo ());
360
+ // bb_idx:
361
+ OutStreamer.emitSizeT (0 );
362
+
363
+ // inst_idx:
364
+ if (FLCtxt.ArgumentMap .count (A) > 0 ) {
365
+ InstIdx InstIdx = FLCtxt.ArgumentMap [A];
366
+ OutStreamer.emitSizeT (InstIdx);
367
+ }
361
368
}
362
369
363
370
void serialiseGlobalOperand (GlobalVariable *G) {
@@ -373,7 +380,7 @@ class YkIRWriter {
373
380
} else if (llvm::Constant *C = dyn_cast<llvm::Constant>(V)) {
374
381
serialiseConstantOperand (Parent, C);
375
382
} else if (llvm::Argument *A = dyn_cast<llvm::Argument>(V)) {
376
- serialiseArgOperand (A);
383
+ serialiseArgOperand (A, FLCtxt );
377
384
} else if (Instruction *I = dyn_cast<Instruction>(V)) {
378
385
serialiseLocalVariableOperand (I, FLCtxt);
379
386
} else {
@@ -1180,7 +1187,17 @@ class YkIRWriter {
1180
1187
InstIdx++;
1181
1188
}
1182
1189
1183
- void serialiseBlock (BasicBlock &BB, FuncLowerCtxt &FLCtxt, unsigned &BBIdx) {
1190
+ void serialiseLoadArg (Argument *Arg) {
1191
+ // opcode:
1192
+ serialiseOpcode (OpCodeLoadArg);
1193
+ // arg index:
1194
+ OutStreamer.emitSizeT (Arg->getArgNo ());
1195
+ // type_idx:
1196
+ OutStreamer.emitSizeT (typeIndex (Arg->getType ()));
1197
+ }
1198
+
1199
+ void serialiseBlock (BasicBlock &BB, FuncLowerCtxt &FLCtxt, unsigned &BBIdx,
1200
+ Function &F) {
1184
1201
auto ShouldSkipInstr = [](Instruction *I) {
1185
1202
// Skip non-semantic instrucitons for now.
1186
1203
//
@@ -1211,6 +1228,19 @@ class YkIRWriter {
1211
1228
1212
1229
// instrs:
1213
1230
unsigned InstIdx = 0 ;
1231
+
1232
+ // Insert LoadArg instructions for each argument of this function and
1233
+ // replace all Argument operands with their respective LoadArg instruction.
1234
+ // This ensures we won't have to deal with argument operands in the yk
1235
+ // pipeline (e.g. trace_builder, deopt).
1236
+ if (BBIdx == 0 ) {
1237
+ for (Argument *Arg = F.arg_begin (); Arg != F.arg_end (); Arg++) {
1238
+ serialiseLoadArg (Arg);
1239
+ FLCtxt.ArgumentMap [Arg] = InstIdx;
1240
+ InstIdx++;
1241
+ }
1242
+ }
1243
+
1214
1244
for (Instruction &I : BB) {
1215
1245
if (ShouldSkipInstr (&I)) {
1216
1246
continue ;
@@ -1243,8 +1273,9 @@ class YkIRWriter {
1243
1273
// blocks:
1244
1274
unsigned BBIdx = 0 ;
1245
1275
FuncLowerCtxt FLCtxt;
1276
+ std::vector<Argument> V;
1246
1277
for (BasicBlock &BB : F) {
1247
- serialiseBlock (BB, FLCtxt, BBIdx);
1278
+ serialiseBlock (BB, FLCtxt, BBIdx, F );
1248
1279
}
1249
1280
FLCtxt.patchUpInstIdxs (OutStreamer);
1250
1281
}
0 commit comments