Skip to content

Commit 9c99901

Browse files
authored
Merge pull request rust-lang#176 from ptersilie/loadarg
Replace argument operands with instructions.
2 parents 7cb3aa8 + 65669b0 commit 9c99901

File tree

1 file changed

+42
-11
lines changed

1 file changed

+42
-11
lines changed

llvm/lib/YkIR/YkIRWriter.cpp

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ enum OpCode {
5656
OpCodePHI,
5757
OpCodeIndirectCall,
5858
OpCodeSelect,
59+
OpCodeLoadArg,
5960
OpCodeUnimplemented = 255, // YKFIXME: Will eventually be deleted.
6061
};
6162

@@ -184,6 +185,8 @@ class FuncLowerCtxt {
184185
public:
185186
// Create an empty function lowering context.
186187
FuncLowerCtxt() : VLMap(ValueLoweringMap()), InstIdxPatchUps({}){};
188+
// Maps argument operands to LoadArg instructions.
189+
map<Argument *, InstIdx> ArgumentMap;
187190

188191
// Defer (patch up later) the use-site of the (as-yet unknown) instruction
189192
// index of the instruction `I`, which has the symbol `Sym`.
@@ -349,15 +352,19 @@ class YkIRWriter {
349352
OutStreamer.emitSizeT(getIndex(BB->getParent(), BB));
350353
}
351354

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:
358359
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+
}
361368
}
362369

363370
void serialiseGlobalOperand(GlobalVariable *G) {
@@ -373,7 +380,7 @@ class YkIRWriter {
373380
} else if (llvm::Constant *C = dyn_cast<llvm::Constant>(V)) {
374381
serialiseConstantOperand(Parent, C);
375382
} else if (llvm::Argument *A = dyn_cast<llvm::Argument>(V)) {
376-
serialiseArgOperand(A);
383+
serialiseArgOperand(A, FLCtxt);
377384
} else if (Instruction *I = dyn_cast<Instruction>(V)) {
378385
serialiseLocalVariableOperand(I, FLCtxt);
379386
} else {
@@ -1180,7 +1187,17 @@ class YkIRWriter {
11801187
InstIdx++;
11811188
}
11821189

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) {
11841201
auto ShouldSkipInstr = [](Instruction *I) {
11851202
// Skip non-semantic instrucitons for now.
11861203
//
@@ -1211,6 +1228,19 @@ class YkIRWriter {
12111228

12121229
// instrs:
12131230
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+
12141244
for (Instruction &I : BB) {
12151245
if (ShouldSkipInstr(&I)) {
12161246
continue;
@@ -1243,8 +1273,9 @@ class YkIRWriter {
12431273
// blocks:
12441274
unsigned BBIdx = 0;
12451275
FuncLowerCtxt FLCtxt;
1276+
std::vector<Argument> V;
12461277
for (BasicBlock &BB : F) {
1247-
serialiseBlock(BB, FLCtxt, BBIdx);
1278+
serialiseBlock(BB, FLCtxt, BBIdx, F);
12481279
}
12491280
FLCtxt.patchUpInstIdxs(OutStreamer);
12501281
}

0 commit comments

Comments
 (0)