zig icon indicating copy to clipboard operation
zig copied to clipboard

Computed gotos

Open EzequielRamis opened this issue 10 months ago • 11 comments

Closes https://github.com/ziglang/zig/issues/8220.

I took the risk of contributing because it's my first time working with something complex like the zig source code, but I'm currently doing a college project with it and I want to boost the performance with this feature. About the bounty, it's ok if the deadline is missed, as it's personally a nice incentive but secondary.

Below you'd find a list of what I was able to do, what needs to be corrected, what is missing and doubts/things to consider, expecting many items to have phrases like "I have no idea".

TODO

  • [ ] Better tests.
  • [ ] Backends: I've only touched the llvm one.
  • [ ] Fix zig fmt: I think the parsing works, but I couldn't found why this command does not and I don't know how to debug it properly.
  • [ ] Fix Sema:
    • I have no idea how to handle prong captures with the dispatched operands, specially if they are references. Maybe a phi instruction must be created in Air?
    • I have no idea how to link the switch_dispatch instruction with its labeled switch_br without having type or liveness resolution errors.
  • [ ] Fix codegen: Related to the last bullet, I want to identify a dispatch table by its switch. Adding this Air.SwitchBr field solves it but I don't think it's nice/good enough.
  • [ ] Direct jump: For now it only works when it's run at compile time.
  • [ ] Indirect jump: I didn't test any created function like airSwitchIndirectBr or indirectBr yet.

Doubts

  • It must be able to dispatch using integers, booleans, enums and tagged unions, but are errors also included? If that's the case, this pattern https://github.com/ziglang/zig/issues/11957 should be considered.
  • Since the else prong is also handled when dispatching, it would be reasonable to warn about using types which could generate megabytes-sized dispatch tables like a little u16.

EzequielRamis avatar Mar 28 '24 05:03 EzequielRamis

This pull request makes it possible to write code like this

const bit: u1 = 0;

label: switch (bit) {
    0 => continue :label 1,
    1 => continue :label 0,
}

It's obvious that such code results in infinite loop. So far I'm not quite sure if it will possible to compiler to infer this statically. But if so, I'm sure that compiler should produce diagnostics with a note something like this: note: consider using 'while(true)' Should I make a separate proposal for this?

wrongnull avatar Mar 28 '24 21:03 wrongnull

@wrongnull

  1. that looks very difficult to detect in a reliable way
  2. if someone's reaching for this syntax, they probably already know about while loops :)

silversquirl avatar Mar 28 '24 21:03 silversquirl

@wrongnull it does catch it if the switch is run at compile time

EzequielRamis avatar Mar 28 '24 21:03 EzequielRamis

1. that looks very difficult to detect in a reliable way

Are you completely sure about that? At least the compiler is able to detect reaching unreachable code at compile time. As far as I'm concerned there is a control flow graph for thing like that.

2. if someone's reaching for this syntax, they probably already know about while loops :)

good point. Maybe the error message is redundant here. That's why I asked a question about proposal

wrongnull avatar Mar 28 '24 21:03 wrongnull

Having the switch never result in a value explicitly is allowed: in fact, it's probably the main or only way we'll utilize the syntax in the compiler itself, since the termination case would just return.

mlugg avatar Mar 28 '24 22:03 mlugg

@EzequielRamis genuinely great work on this PR -- it needs some tinkering, but it's incredibly high-quality for a first-time PR.

Would you like to continue working on this? If you're interested in solving the TODOs and issues yourself, I'm very happy for you to do so, and I will help you where I can. However, if you'd prefer to fast-track the actual feature, or if you're too busy to dedicate much more time to it, I can take over this branch once I'm done with my current branch. Your call!

mlugg avatar Mar 30 '24 03:03 mlugg

@mlugg thank you for your kind words! It would be great if you could continue with the todos and the other comments I've left, since I need time for my studies. Before that I will push some fixes of the reviews you've written.

EzequielRamis avatar Mar 30 '24 03:03 EzequielRamis

@mlugg there you have it

EzequielRamis avatar Mar 30 '24 04:03 EzequielRamis

Okay, no worries -- I'll pick this up within the next few days. Thanks!

mlugg avatar Mar 30 '24 04:03 mlugg

It's obvious that such code results in infinite loop. So far I'm not quite sure if it will possible to compiler to infer this statically.

You can detect some infinite loops, but in general it's undecidable; see "The Halting Problem" from the Theory of Computer Science.

drfuchs avatar Apr 29 '24 12:04 drfuchs

It's obvious that such code results in infinite loop. So far I'm not quite sure if it will possible to compiler to infer this statically.

You can detect some infinite loops, but in general it's undecidable; see "The Halting Problem" from the Theory of Computer Science.

I understand it well. I told about detecting loops in control flow graph statically when it's possible

wrongnull avatar Apr 29 '24 14:04 wrongnull

draft status for > 30 days

andrewrk avatar Jun 08 '24 20:06 andrewrk

(Succeeded by #19812, which I will finish off soon!)

mlugg avatar Jun 08 '24 20:06 mlugg