Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dis: Show names of intrinsics #103963

Closed
JelleZijlstra opened this issue Apr 28, 2023 · 12 comments · Fixed by #104029
Closed

dis: Show names of intrinsics #103963

JelleZijlstra opened this issue Apr 28, 2023 · 12 comments · Fixed by #104029
Labels
3.12 bugs and security fixes stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@JelleZijlstra
Copy link
Member

JelleZijlstra commented Apr 28, 2023

For CALL_INTRINSIC_* opcodes, dis currently just shows the number, which makes it hard to figure out what the code actually does:

              2 LOAD_CONST               0 ('T')
              4 CALL_INTRINSIC_1         7

It would be nice if this instead said

              2 LOAD_CONST               0 ('T')
              4 CALL_INTRINSIC_1         7 (INTRINSIC_TYPEVAR)

Possible implementation strategy:

  • instrinsic names are defined in opcode.py
  • pycore_intrinsics.h is generated from opcode.py (bonus: we no longer have to manually update MAX_INTRINSIC_1)
  • dis learns to read the intrinsic names from opcode.py

Linked PRs

@JelleZijlstra JelleZijlstra added type-feature A feature request or enhancement 3.12 bugs and security fixes labels Apr 28, 2023
@iritkatriel
Copy link
Member

@jkchandalia are you interested in this?

@jkchandalia
Copy link
Contributor

@iritkatriel I can work on this.

@iritkatriel
Copy link
Member

Great. Have a look at /Tools/build/generate_opcode_h.py
(re generating the .h file).

@iritkatriel
Copy link
Member

Great. Have a look at /Tools/build/generate_opcode_h.py
(re generating the .h file).

Use make regen-opcode to run this script.

@iritkatriel iritkatriel added the stdlib Python modules in the Lib dir label Apr 28, 2023
@JelleZijlstra
Copy link
Member Author

@jkchandalia thanks! It would be nice for me if this can make it in before the 3.12 feature freeze (May 8), since #103764 relies heavily on intrinsics, so this feature will make the bytecode generated by that PR much easier to understand. If that timeline is too tight for you, I'm happy to have a go at implementing this myself.

@jkchandalia
Copy link
Contributor

@JelleZijlstra that timeline is fine for me.

@JelleZijlstra
Copy link
Member Author

Great! Let me know if you need any help.

FYI I think these are some of the easiest ways to trigger intrinsics on current main for testing:

>>> dis.dis('(*a,)')
  0           0 RESUME                   0

  1           2 BUILD_LIST               0
              4 LOAD_NAME                0 (a)
              6 LIST_EXTEND              1
              8 CALL_INTRINSIC_1         6
             10 RETURN_VALUE
>>> dis.dis('+a')
  0           0 RESUME                   0

  1           2 LOAD_NAME                0 (a)
              4 CALL_INTRINSIC_1         5
              6 RETURN_VALUE

@jkchandalia
Copy link
Contributor

Absolutely, thank you. And I appreciate the examples.

@jkchandalia
Copy link
Contributor

@JelleZijlstra I've pushed my branch (https://github.com/jkchandalia/cpython/tree/display_intrinsics_names) and I wasn't quite sure if it's ready for a PR but can definitely open one if that's easier for feedback/discussion.

  1. I added two lists to opcode.py for the intrinsics names (I added an extra option for not valid, not sure if this is needed)
  2. I use these lists in dis.py to get the argrepr to pass to the Instruction class.
  3. I added tests for args 2, 5, and 6 for CALL_INTRINSIC_1 and updated an existing test for arg 3. I put the three new tests into one test function but can split out if better. I had some trouble getting something to trigger the other codes (0?, 1, 4) and also CALL_INTRINSIC_2 for additional testing.
  4. I updated /Tools/build/generate_opcode_h.py to include the new intrinsic names sections (not sure if this is desired?)
  5. I regenerated opcode.h with the new intrinsics-related sections
  6. I could definitely write the code to generate pycore_intrinsics.h as you suggested but I wasn’t quite sure where to put it? A separate script or another internal file output from /Tools/build/generate_opcode_h.py or something else?

@JelleZijlstra
Copy link
Member Author

Looks great! Feel free to open a draft PR and we can get it over the finish line.

You can get the CALL_INTRINSIC_2 with except* (position 38):

>>> dis.dis("try: pass\nexcept* Exception: x")
  0           0 RESUME                   0

  1           2 RETURN_CONST             0 (None)
              4 PUSH_EXC_INFO

  2           6 BUILD_LIST               0
              8 COPY                     2
             10 LOAD_NAME                0 (Exception)
             12 CHECK_EG_MATCH
             14 COPY                     1
             16 POP_JUMP_IF_NONE         8 (to 34)
             18 POP_TOP
             20 LOAD_NAME                1 (x)
             22 POP_TOP
             24 JUMP_FORWARD             3 (to 32)
        >>   26 LIST_APPEND              3
             28 POP_TOP
             30 JUMP_FORWARD             2 (to 36)
        >>   32 JUMP_FORWARD             1 (to 36)
        >>   34 POP_TOP
        >>   36 LIST_APPEND              1
             38 CALL_INTRINSIC_2         1
             40 COPY                     1
             42 POP_JUMP_IF_NOT_NONE     3 (to 50)
             44 POP_TOP
             46 POP_EXCEPT
             48 RETURN_CONST             0 (None)
        >>   50 SWAP                     2
             52 POP_EXCEPT
             54 RERAISE                  0
        >>   56 COPY                     3
             58 POP_EXCEPT
             60 RERAISE                  1
ExceptionTable:
  4 to 18 -> 56 [1] lasti
  20 to 22 -> 26 [4] lasti
  24 to 44 -> 56 [1] lasti

I don't think it's necessary to test every single one of the intrinsics in test_dis.

I would suggest simply expanding generate_opcode_h.py to also generate pycore_intrinsics.h. It already generates multiple files, so it doesn't seem too bad to make it generate another closely related file. We'll add a header to pycore_intrinsics.h to make it clear how it is generated. Perhaps @iritkatriel has a different opinion, though. We definitely shouldn't add the intrinsics to opcode.h, as that's a public header file and we don't want the intrinsics to be part of the public API.

@iritkatriel
Copy link
Member

Sounds good.

@JelleZijlstra
Copy link
Member Author

Thanks for your contribution @jkchandalia!

carljm added a commit to carljm/cpython that referenced this issue May 4, 2023
carljm added a commit to carljm/cpython that referenced this issue May 5, 2023
* main: (61 commits)
  pythongh-64595: Argument Clinic: Touch source file if any output file changed (python#104152)
  pythongh-64631: Test exception messages in cloned Argument Clinic funcs (python#104167)
  pythongh-68395: Avoid naming conflicts by mangling variable names in Argument Clinic (python#104065)
  pythongh-64658: Expand Argument Clinic return converter docs (python#104175)
  pythonGH-103092: port `_asyncio` freelist to module state (python#104196)
  pythongh-104051: fix crash in test_xxtestfuzz with -We (python#104052)
  pythongh-104190: fix ubsan crash (python#104191)
  pythongh-104106: Add gcc fallback of mkfifoat/mknodat for macOS (pythongh-104129)
  pythonGH-104142: Fix _Py_RefcntAdd to respect immortality (pythonGH-104143)
  pythongh-104112: link from cached_property docs to method-caching FAQ (python#104113)
  pythongh-68968: Correcting message display issue with assertEqual (python#103937)
  pythonGH-103899: Provide a hint when accidentally calling a module (pythonGH-103900)
  pythongh-103963: fix 'make regen-opcode' in out-of-tree builds (python#104177)
  pythongh-102500: Add PEP 688 and 698 to the 3.12 release highlights (python#104174)
  pythonGH-81079: Add case_sensitive argument to `pathlib.Path.glob()` (pythonGH-102710)
  pythongh-91896: Deprecate collections.abc.ByteString (python#102096)
  pythongh-99593: Add tests for Unicode C API (part 2) (python#99868)
  pythongh-102500: Document PEP 688 (python#102571)
  pythongh-102500: Implement PEP 688 (python#102521)
  pythongh-96534: socketmodule: support FreeBSD divert(4) socket (python#96536)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 bugs and security fixes stdlib Python modules in the Lib dir type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants