Skip to content

Commit e4701fb

Browse files
jbower-fbfacebook-github-bot
authored andcommitted
Add support for LOAD_COMMON_CONSTANT
Summary: We pre-compute the `Type` objects so we don't have to worry about getting an interperter instance during JIT compilation (not compatible with multi-threaded compile). Reviewed By: DinoV Differential Revision: D82054730 fbshipit-source-id: 1ef69c5b9c662fd6ee5d7c9c0673fefc7ccbcb03
1 parent 678de61 commit e4701fb

6 files changed

Lines changed: 51 additions & 4 deletions

File tree

cinderx/Common/opcode_stubs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
X(JUMP_BACKWARD) \
7070
X(JUMP_BACKWARD_NO_INTERRUPT) \
7171
X(KW_NAMES) \
72+
X(LOAD_COMMON_CONSTANT) \
7273
X(LOAD_FAST_AND_CLEAR) \
7374
X(LOAD_FAST_CHECK) \
7475
X(LOAD_FAST_BORROW) \
@@ -183,6 +184,7 @@ enum {
183184
X(LOAD_ATTR_S_MODULE) \
184185
X(LOAD_ATTR_TYPE) \
185186
X(LOAD_ATTR_UNCACHABLE) \
187+
X(LOAD_COMMON_CONSTANT) \
186188
X(LOAD_FAST_BORROW) \
187189
X(LOAD_FAST_BORROW_LOAD_FAST_BORROW) \
188190
X(LOAD_FAST_LOAD_FAST) \

cinderx/Jit/hir/builder.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "cinderx/Jit/containers.h"
1616
#include "cinderx/Jit/hir/ssa.h"
1717
#include "cinderx/Jit/hir/type.h"
18+
#include "cinderx/Jit/runtime.h"
1819
#include "cinderx/StaticPython/checked_dict.h"
1920
#include "cinderx/StaticPython/checked_list.h"
2021
#include "cinderx/StaticPython/classloader.h"
@@ -149,6 +150,7 @@ bool isSupportedOpcode(int opcode) {
149150
case LOAD_ATTR:
150151
case LOAD_ATTR_SUPER:
151152
case LOAD_CLOSURE:
153+
case LOAD_COMMON_CONSTANT:
152154
case LOAD_CONST:
153155
case LOAD_DEREF:
154156
case LOAD_FAST:
@@ -1529,6 +1531,10 @@ void HIRBuilder::translate(
15291531
emitFormatSimple(irfunc.cfg, tc);
15301532
break;
15311533
}
1534+
case LOAD_COMMON_CONSTANT: {
1535+
emitLoadCommonConstant(tc, bc_instr);
1536+
break;
1537+
}
15321538
case CHECK_EG_MATCH:
15331539
case CHECK_EXC_MATCH:
15341540
case CLEANUP_THROW:
@@ -4889,6 +4895,15 @@ void HIRBuilder::emitFormatSimple(CFG& cfg, TranslationContext& tc) {
48894895
stack.push(out);
48904896
}
48914897

4898+
void HIRBuilder::emitLoadCommonConstant(
4899+
TranslationContext& tc,
4900+
const BytecodeInstruction& bc_instr) {
4901+
Register* out = temps_.AllocateStack();
4902+
tc.emit<LoadConst>(
4903+
out, Runtime::get()->typeForCommonConstant(bc_instr.oparg()));
4904+
tc.frame.stack.push(out);
4905+
}
4906+
48924907
void HIRBuilder::insertEvalBreakerCheck(
48934908
CFG& cfg,
48944909
BasicBlock* check_block,

cinderx/Jit/hir/builder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,10 @@ class HIRBuilder {
461461

462462
void emitFormatSimple(CFG& cfg, TranslationContext& tc);
463463

464+
void emitLoadCommonConstant(
465+
TranslationContext& tc,
466+
const BytecodeInstruction& bc_instr);
467+
464468
BorrowedRef<> constArg(const jit::BytecodeInstruction& bc_instr);
465469

466470
ExecutionBlock popBlock(CFG& cfg, TranslationContext& tc);

cinderx/Jit/runtime.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@
1313

1414
namespace jit {
1515

16+
Runtime::Runtime() : zero_(Ref<>::create(PyLong_FromLong(0))) {
17+
#if PY_VERSION_HEX >= 0x030E0000
18+
PyObject** common_consts = PyThreadState_GET()->interp->common_consts;
19+
for (int i = 0; i < NUM_COMMON_CONSTANTS; i++) {
20+
common_constant_types_.emplace_back(
21+
hir::Type::fromObject(common_consts[i]));
22+
}
23+
#endif
24+
}
25+
1626
void Builtins::init() {
1727
ThreadedCompileSerialize guard;
1828
if (is_initialized_) {

cinderx/Jit/runtime.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,8 @@ class Builtins {
102102
// Runtime owns all metadata created by the JIT.
103103
class Runtime : public IRuntime {
104104
public:
105-
Runtime() {
106-
zero_ = Ref<>::create(PyLong_FromLong(0));
107-
}
105+
Runtime();
106+
108107
// Return the singleton Runtime, creating it first if necessary.
109108
static Runtime* get() {
110109
return static_cast<Runtime*>(cinderx::getModuleState()->runtime());
@@ -278,7 +277,13 @@ class Runtime : public IRuntime {
278277
void watchPendingTypes();
279278
void fixupFunctionEntryCachePostMultiThreadedCompile();
280279

281-
private:
280+
const hir::Type& typeForCommonConstant([[maybe_unused]] int i) const {
281+
#if PY_VERSION_HEX >= 0x030E0000
282+
return common_constant_types_.at(i);
283+
#endif
284+
JIT_ABORT("Common constants are a feature of 3.14+");
285+
}
286+
282287
// Allocate all CodeRuntimes together so they can be mlocked() without
283288
// including any other data that happened to be on the same page.
284289
SlabArena<CodeRuntime> code_runtimes_;
@@ -311,6 +316,8 @@ class Runtime : public IRuntime {
311316

312317
Ref<> zero_;
313318
std::unordered_set<BorrowedRef<PyTypeObject>> pending_watches_;
319+
320+
std::vector<hir::Type> common_constant_types_;
314321
};
315322

316323
} // namespace jit

cinderx/PythonLib/test_cinderx/test_python314_bytecodes.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,15 @@ def x():
431431
locals,
432432
)
433433

434+
def test_LOAD_COMMON_CONSTANT(self):
435+
@cinder_support.fail_if_deopt
436+
@cinder_support.failUnlessJITCompiled
437+
def x(a):
438+
assert a
439+
440+
x(True)
441+
self._assertBytecodeContains(x, "LOAD_COMMON_CONSTANT")
442+
434443

435444
if __name__ == "__main__":
436445
unittest.main()

0 commit comments

Comments
 (0)