Maratyszcza / Maratyszcza/PeachPy
'maximum recursion depth exceeded' while finalizing a large function
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.1k
- Forks
- 170
- PR merge metrics
- No merged PRs in 30d
Description
I'm generating a fairly large function using PeachPy (compiling from another language). When the function has a large number of labels it seems that the finalization invoked when `RETURN` is called is blowing the Python style.
Part of the stack trace:
```
File "function.py", line 549, in analyze_reachability
output_block.analyze_reachability()
File "function.py", line 549, in analyze_reachability
output_block.analyze_reachability()
File "function.py", line 549, in analyze_reachability
output_block.analyze_reachability()
File "function.py", line 549, in analyze_reachability
output_block.analyze_reachability()
```
FWIW I'm not even using the register allocation features, all my registers are managed manually. A silly reproducer below:
```
import peachpy
import peachpy.x86_64
x = peachpy.Argument(peachpy.int64_t)
y = peachpy.Argument(peachpy.int64_t)
with peachpy.x86_64.Function("Times", (x, y), peachpy.int64_t) as asm_function:
reg_x = peachpy.x86_64.rax
reg_y = peachpy.x86_64.rbx
reg_accum = peachpy.x86_64.rcx
peachpy.x86_64.LOAD.ARGUMENT(reg_x, x)
peachpy.x86_64.LOAD.ARGUMENT(reg_y, y)
peachpy.x86_64.MOV(reg_accum, 0)
for i in range(1000):
loop_start_label = peachpy.x86_64.Label('loop_start{}'.format(i))
loop_end_label = peachpy.x86_64.Label('loop_end{}'.format(i))
peachpy.x86_64.CMP(reg_y, 0)
peachpy.x86_64.JE(loop_end_label)
peachpy.x86_64.LABEL(loop_start_label) # bind the label
peachpy.x86_64.ADD(reg_accum, reg_x)
peachpy.x86_64.SUB(reg_y, 1)
peachpy.x86_64.JG(loop_start_label)
peachpy.x86_64.LABEL(loop_end_label) # bind the label
peachpy.x86_64.RETURN(reg_accum)
abi = peachpy.x86_64.abi.detect()
encoded_function = asm_function.finalize(abi).encode()
python_function = encoded_function.load()
print(encoded_function.format())
code = python_function.code_segment
fname = '/tmp/ppout.bin'
with open(fname, 'wb') as f:
f.write(code)
print('Wrote code to file [{0}]: {1}'.format(fname, code))
# The JIT call
print(python_function(3, 4))
```
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in function.py at analyze_reachability, shown repeatedly in the recursion traceback, and follow how RETURN triggers finalization. Run the supplied 1,000-label reproducer through asm_function.finalize(abi).encode(). Done means the large function finalizes and encodes without exceeding Python's recursion depth.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100