gh-94216: add pseudo instructions to the dis/opcodes modules (GH-94241)

This commit is contained in:
Irit Katriel 2022-07-01 15:33:35 +01:00 committed by GitHub
parent be80db14c4
commit c57aad777a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 245 additions and 83 deletions

View file

@ -71,40 +71,14 @@
#define MAX_ALLOWED_STACK_USE (STACK_USE_GUIDELINE * 100)
/* Pseudo-instructions used in the compiler,
* but turned into NOPs or other instructions
* by the assembler. */
#define SETUP_FINALLY -1
#define SETUP_CLEANUP -2
#define SETUP_WITH -3
#define POP_BLOCK -4
#define JUMP -5
#define JUMP_NO_INTERRUPT -6
#define POP_JUMP_IF_FALSE -7
#define POP_JUMP_IF_TRUE -8
#define POP_JUMP_IF_NONE -9
#define POP_JUMP_IF_NOT_NONE -10
#define LOAD_METHOD -11
#define MIN_VIRTUAL_OPCODE -11
#define MAX_ALLOWED_OPCODE 254
#define MAX_REAL_OPCODE 254
#define IS_WITHIN_OPCODE_RANGE(opcode) \
((opcode) >= MIN_VIRTUAL_OPCODE && (opcode) <= MAX_ALLOWED_OPCODE)
#define IS_VIRTUAL_OPCODE(opcode) ((opcode) < 0)
#define IS_VIRTUAL_JUMP_OPCODE(opcode) \
((opcode) == JUMP || \
(opcode) == JUMP_NO_INTERRUPT || \
(opcode) == POP_JUMP_IF_NONE || \
(opcode) == POP_JUMP_IF_NOT_NONE || \
(opcode) == POP_JUMP_IF_FALSE || \
(opcode) == POP_JUMP_IF_TRUE)
(((opcode) >= 0 && (opcode) <= MAX_REAL_OPCODE) || \
IS_PSEUDO_OPCODE(opcode))
#define IS_JUMP_OPCODE(opcode) \
(IS_VIRTUAL_JUMP_OPCODE(opcode) || \
is_bit_set_in_table(_PyOpcode_Jump, opcode))
is_bit_set_in_table(_PyOpcode_Jump, opcode)
#define IS_BLOCK_PUSH_OPCODE(opcode) \
((opcode) == SETUP_FINALLY || \
@ -125,7 +99,6 @@
(opcode) == POP_JUMP_FORWARD_IF_FALSE || \
(opcode) == POP_JUMP_BACKWARD_IF_FALSE)
#define IS_BACKWARDS_JUMP_OPCODE(opcode) \
((opcode) == JUMP_BACKWARD || \
(opcode) == JUMP_BACKWARD_NO_INTERRUPT || \
@ -183,11 +156,11 @@ typedef struct exceptstack {
static inline int
is_bit_set_in_table(const uint32_t *table, int bitindex) {
/* Is the relevant bit set in the relevant word? */
/* 256 bits fit into 8 32-bits words.
/* 512 bits fit into 9 32-bits words.
* Word is indexed by (bitindex>>ln(size of int in bits)).
* Bit within word is the low bits of bitindex.
*/
if (bitindex >= 0 && bitindex < 256) {
if (bitindex >= 0 && bitindex < 512) {
uint32_t word = table[bitindex >> LOG_BITS_PER_INT];
return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1;
}
@ -218,7 +191,7 @@ static int
instr_size(struct instr *instruction)
{
int opcode = instruction->i_opcode;
assert(!IS_VIRTUAL_OPCODE(opcode));
assert(!IS_PSEUDO_OPCODE(opcode));
int oparg = HAS_ARG(opcode) ? instruction->i_oparg : 0;
int extended_args = (0xFFFFFF < oparg) + (0xFFFF < oparg) + (0xFF < oparg);
int caches = _PyOpcode_Caches[opcode];
@ -229,7 +202,7 @@ static void
write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen)
{
int opcode = instruction->i_opcode;
assert(!IS_VIRTUAL_OPCODE(opcode));
assert(!IS_PSEUDO_OPCODE(opcode));
int oparg = HAS_ARG(opcode) ? instruction->i_oparg : 0;
int caches = _PyOpcode_Caches[opcode];
switch (ilen - caches) {
@ -1274,7 +1247,7 @@ static int
is_end_of_basic_block(struct instr *instr)
{
int opcode = instr->i_opcode;
return is_jump(instr) || IS_SCOPE_EXIT_OPCODE(opcode);
return IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode);
}
static int
@ -1324,7 +1297,7 @@ basicblock_addop(basicblock *b, int opcode, int oparg,
static int
compiler_addop(struct compiler *c, int opcode, bool line)
{
assert(!HAS_ARG(opcode) || IS_ARTIFICIAL(opcode));
assert(!HAS_ARG(opcode));
if (compiler_use_new_implicit_block_if_needed(c) < 0) {
return -1;
}
@ -8990,7 +8963,6 @@ apply_static_swaps(basicblock *block, int i)
static bool
jump_thread(struct instr *inst, struct instr *target, int opcode)
{
assert(!IS_VIRTUAL_OPCODE(opcode) || IS_VIRTUAL_JUMP_OPCODE(opcode));
assert(is_jump(inst));
assert(is_jump(target));
// bpo-45773: If inst->i_target == target->i_target, then nothing actually

View file

@ -34,7 +34,8 @@ def write_contents(f):
targets = ['_unknown_opcode'] * 256
targets[255] = "TARGET_DO_TRACING"
for opname, op in opcode.opmap.items():
targets[op] = "TARGET_%s" % opname
if not opcode.is_pseudo(op):
targets[op] = "TARGET_%s" % opname
next_op = 1
for opname in opcode._specialized_instructions:
while targets[next_op] != '_unknown_opcode':