Skip to content

Commit b6123b3

Browse files
DinoVmeta-codesync[bot]
authored andcommitted
Use PyTuple_FromArray for creation of tuple objects
Summary: A new test has arrived in 3.14.1 and 3.15 which tests that tuples which don't have any GC objects are not GC tracked. Currently our allocations are always tracking them. This replaces the kBatchDecref LIR instruction with a generic VarArgCall instruction which takes a PyObject **args, Py_ssize_t length. We use this for both BatchDecref and make tuple. Reviewed By: alexmalyshev Differential Revision: D86136959 fbshipit-source-id: 7337539b91c90c0b407a50377fb5293d2f6a2f9a
1 parent 4730d74 commit b6123b3

8 files changed

Lines changed: 31 additions & 70 deletions

File tree

cinderx/Jit/hir/instr_effects.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,15 +205,14 @@ MemoryEffects memoryEffects(const Instr& inst) {
205205
return commonEffects(inst, AOther);
206206

207207
case Opcode::kMakeCheckedList:
208-
case Opcode::kMakeList:
209-
case Opcode::kMakeTuple: {
208+
case Opcode::kMakeList: {
210209
// Steal all inputs.
211210
util::BitVector inputs{inst.NumOperands()};
212211
inputs.fill(true);
213-
auto may_store =
214-
inst.opcode() == Opcode::kMakeTuple ? ATupleItem : AListItem;
215-
return {false, AEmpty, std::move(inputs), may_store};
212+
return {false, AEmpty, std::move(inputs), AListItem};
216213
}
214+
case Opcode::kMakeTuple:
215+
return commonEffects(inst, ATupleItem);
217216

218217
case Opcode::kStoreField:
219218
JIT_DCHECK(inst.NumOperands() == 3, "Unexpected number of operands");

cinderx/Jit/lir/generator.cpp

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,7 +1769,8 @@ LIRGenerator::TranslatedBlock LIRGenerator::TranslateOneBasicBlock(
17691769
case Opcode::kBatchDecref: {
17701770
auto instr = static_cast<const BatchDecref*>(&i);
17711771

1772-
Instruction* lir = bbb.appendInstr(Instruction::kBatchDecref);
1772+
Instruction* lir = bbb.appendInstr(Instruction::kVarArgCall);
1773+
lir->addOperands(Imm{reinterpret_cast<uint64_t>(JITRT_BatchDecref)});
17731774
for (hir::Register* arg : instr->GetOperands()) {
17741775
lir->addOperands(VReg{bbb.getDefInstr(arg)});
17751776
}
@@ -2264,22 +2265,18 @@ LIRGenerator::TranslatedBlock LIRGenerator::TranslateOneBasicBlock(
22642265
}
22652266
case Opcode::kMakeTuple: {
22662267
auto instr = static_cast<const MakeTuple*>(&i);
2267-
Instruction* tuple = bbb.appendCallInstruction(
2268-
instr->output(),
2269-
PyTuple_New,
2270-
static_cast<Py_ssize_t>(instr->nvalues()));
2271-
// TODO(T174544781): need to check for 0 before initializing, currently
2272-
// that check only happens after assigning these values.
2273-
const size_t ob_item_offset = offsetof(PyTupleObject, ob_item);
2274-
for (size_t operandIdx = 0; operandIdx < instr->NumOperands();
2275-
operandIdx++) {
2276-
bbb.appendInstr(
2277-
OutInd{
2278-
tuple,
2279-
static_cast<int32_t>(
2280-
ob_item_offset + operandIdx * kPointerSize)},
2281-
Instruction::kMove,
2282-
instr->GetOperand(operandIdx));
2268+
Instruction* tuple =
2269+
bbb.appendInstr(instr->output(), Instruction::kVarArgCall);
2270+
tuple->addOperands(
2271+
Imm{reinterpret_cast<uint64_t>(
2272+
#if PY_VERSION_HEX >= 0x030F0000
2273+
PyTuple_FromArray
2274+
#else
2275+
_PyTuple_FromArray
2276+
#endif
2277+
)});
2278+
for (size_t ix = 0; ix < instr->NumOperands(); ix++) {
2279+
tuple->addOperands(VReg{bbb.getDefInstr(instr->GetOperand(ix))});
22832280
}
22842281
break;
22852282
}

cinderx/Jit/lir/instruction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ enum OperandSizeType {
9090
X(Unreachable, false, FlagEffects::kNone, kDefault, 0, {}, 1) \
9191
X(Call, false, FlagEffects::kInvalidate, kAlways64, 1, {}, 1) \
9292
X(VectorCall, false, FlagEffects::kInvalidate, kAlways64, 1, {1}, 1) \
93+
X(VarArgCall, false, FlagEffects::kInvalidate, kDefault, 1, {1}) \
9394
X(Guard, false, FlagEffects::kInvalidate, kDefault, 1, {0, 0, 1, 1}, 1) \
9495
X(DeoptPatchpoint, false, FlagEffects::kInvalidate, kDefault, 0, {1, 1}, 1) \
9596
X(Sext) \
@@ -134,7 +135,6 @@ enum OperandSizeType {
134135
X(Cdq, false, FlagEffects::kNone, kDefault, 1, {}, 1) \
135136
X(Cwd, false, FlagEffects::kNone, kDefault, 1, {}, 1) \
136137
X(Cqo, false, FlagEffects::kNone, kDefault, 1, {}, 1) \
137-
X(BatchDecref, false, FlagEffects::kInvalidate, kDefault, 1, {1}) \
138138
X(Branch) \
139139
X(BranchNZ) \
140140
X(BranchZ) \

cinderx/Jit/lir/operand.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,5 +375,3 @@ DECLARE_TYPE_ARG(OutInd, MemoryIndirect, true)
375375
DECLARE_TYPE_ARG(OutVReg, void, true)
376376

377377
} // namespace jit::lir
378-
379-
#define FUNC_MARKER_BATCHDECREF (void*)0x0001

cinderx/Jit/lir/postalloc.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -251,19 +251,18 @@ int rewriteVectorCallFunctions(instr_iter_t instr_iter) {
251251
return rsp_sub;
252252
}
253253

254-
int rewriteBatchDecrefFunction(instr_iter_t instr_iter) {
254+
int rewriteVarArgCall(instr_iter_t instr_iter) {
255255
auto instr = instr_iter->get();
256-
static_cast<Operand*>(instr->getInput(0))
257-
->setConstant(
258-
reinterpret_cast<uint64_t>(JITRT_BatchDecref), Operand::k64bit);
259-
260-
return prepareArgsArray(
256+
instr->setOpcode(Instruction::kCall);
257+
auto res = prepareArgsArray(
261258
instr_iter,
262259
instr->getNumInputs() - 1, // func is 1st argument
263260
0,
264261
1,
265262
ARGUMENT_REGS[0],
266263
ARGUMENT_REGS[1]);
264+
instr->setNumInputs(1);
265+
return res;
267266
}
268267

269268
// rewrite call instructions:
@@ -272,7 +271,11 @@ int rewriteBatchDecrefFunction(instr_iter_t instr_iter) {
272271
// JITRT_(Call|Get)Method, etc.
273272
RewriteResult rewriteCallInstrs(instr_iter_t instr_iter, Environ* env) {
274273
auto instr = instr_iter->get();
275-
if (!instr->isCall() && !instr->isVectorCall()) {
274+
if (instr->isVarArgCall()) {
275+
int rsp_sub = rewriteVarArgCall(instr_iter);
276+
env->max_arg_buffer_size = std::max<int>(env->max_arg_buffer_size, rsp_sub);
277+
return kChanged;
278+
} else if (!instr->isCall() && !instr->isVectorCall()) {
276279
return kUnchanged;
277280
}
278281

@@ -286,13 +289,6 @@ RewriteResult rewriteCallInstrs(instr_iter_t instr_iter, Environ* env) {
286289

287290
if (instr->isVectorCall()) {
288291
rsp_sub = rewriteVectorCallFunctions(instr_iter);
289-
} else if (instr->getInput(0)->isImm()) {
290-
void* func = reinterpret_cast<void*>(instr->getInput(0)->getConstant());
291-
if (func == FUNC_MARKER_BATCHDECREF) {
292-
rsp_sub = rewriteBatchDecrefFunction(instr_iter);
293-
} else {
294-
rsp_sub = rewriteRegularFunction(instr_iter);
295-
}
296292
} else {
297293
rsp_sub = rewriteRegularFunction(instr_iter);
298294
}

cinderx/Jit/lir/postgen.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -228,24 +228,6 @@ RewriteResult rewriteLoadArg(instr_iter_t instr_iter, Environ* env) {
228228
return kChanged;
229229
}
230230

231-
RewriteResult rewriteBatchDecrefInstrs(instr_iter_t instr_iter) {
232-
auto instr = instr_iter->get();
233-
if (!instr->isBatchDecref()) {
234-
return kUnchanged;
235-
}
236-
237-
// we translate BatchDecref by converting it to a Call instruction
238-
instr->setOpcode(Instruction::kCall);
239-
240-
instr->prependInput(
241-
std::make_unique<Operand>(
242-
nullptr,
243-
Operand::k64bit,
244-
Operand::kImm,
245-
reinterpret_cast<uint64_t>(FUNC_MARKER_BATCHDECREF)));
246-
return kChanged;
247-
}
248-
249231
void populateLoadSecondCallResultPhi(
250232
OperandBase::DataType data_type,
251233
Instruction* phi1,
@@ -363,7 +345,6 @@ RewriteResult rewriteLoadSecondCallResult(instr_iter_t instr_iter) {
363345
void PostGenerationRewrite::registerRewrites() {
364346
// rewriteInlineHelper should occur before other rewrites.
365347
registerOneRewriteFunction(rewriteInlineHelper, 0);
366-
registerOneRewriteFunction(rewriteBatchDecrefInstrs, 0);
367348

368349
registerOneRewriteFunction(rewriteBinaryOpConstantPosition, 1);
369350
registerOneRewriteFunction(rewriteBinaryOpLargeConstant, 1);

cinderx/Jit/lir/regalloc.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ void LinearScanAllocator::calculateLiveIntervals() {
495495
}
496496

497497
if (instr_opcode == Instruction::kCall ||
498+
instr_opcode == Instruction::kVarArgCall ||
498499
instr_opcode == Instruction::kVectorCall) {
499500
reserveCallerSaveRegisters(instr_id);
500501
}
@@ -1165,6 +1166,7 @@ void LinearScanAllocator::rewriteInstrOutput(
11651166
// TODO: Fix HIR generator to avoid generating unused output/variables.
11661167
// Need a separate pass in HIR to handle the dead code more gracefully.
11671168
if (instr->opcode() == Instruction::kCall ||
1169+
instr->opcode() == Instruction::kVarArgCall ||
11681170
instr->opcode() == Instruction::kVectorCall) {
11691171
output->setNone();
11701172
} else {

cinderx/RuntimeTests/hir_tests/refcount_insertion_test.txt

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,9 +1937,6 @@ def test(a):
19371937
fun jittestmodule:test {
19381938
bb 0 {
19391939
v2:Object = LoadArg<0; "a">
1940-
Incref v2
1941-
Incref v2
1942-
Incref v2
19431940
v6:MortalTupleExact = MakeTuple<3> v2 v2 v2 {
19441941
LiveValues<1> b:v2
19451942
FrameState {
@@ -1971,9 +1968,6 @@ fun jittestmodule:test {
19711968
}
19721969

19731970
bb 1 (preds 0, 2) {
1974-
Incref v5
1975-
Incref v5
1976-
Incref v5
19771971
v10:MortalTupleExact = MakeTuple<3> v5 v5 v5 {
19781972
LiveValues<1> b:v5
19791973
FrameState {
@@ -2005,9 +1999,6 @@ fun jittestmodule:test {
20051999
}
20062000

20072001
bb 1 (preds 0, 2) {
2008-
Incref v5
2009-
Incref v5
2010-
Incref v5
20112002
v10:MortalTupleExact = MakeTuple<3> v5 v5 v5 {
20122003
LiveValues<1> b:v5
20132004
FrameState {
@@ -2253,7 +2244,6 @@ fun jittestmodule:test {
22532244
XDecref v18
22542245
Decref v19
22552246
Decref v26
2256-
Incref v14
22572247
v20:MortalTupleExact = MakeTuple<1> v14 {
22582248
LiveValues<2> unc:v13 o:v14
22592249
FrameState {
@@ -2335,7 +2325,6 @@ fun jittestmodule:test {
23352325
XDecref v26
23362326
Decref v27
23372327
Decref v33
2338-
Incref v17
23392328
v28:MortalTupleExact = MakeTuple<1> v17 {
23402329
LiveValues<2> unc:v16 o:v17
23412330
FrameState {
@@ -2415,7 +2404,6 @@ fun jittestmodule:test {
24152404
XDecref v26
24162405
Decref v27
24172406
Decref v33
2418-
Incref v17
24192407
v28:MortalTupleExact = MakeTuple<1> v17 {
24202408
LiveValues<2> unc:v16 o:v17
24212409
FrameState {

0 commit comments

Comments
 (0)