In general, how can I create any labels that I can jump to?
Best this of course linked to a condition (IsGt, IsLt, ...).
Currently my experimental (and very risky) code:
https://gist.github.com/deeprobin/1275813f3b9ba4401982b681786d6991
I don't think we support labels directly (i.e goto). However you should be able to create a block for each label and jump to each block.
Yep, in a control-flow-graph IR, labels are blocks. The main difference with a classical "conditional goto" representation (like machine code or JVM bytecode or...) is that the end of a block doesn't have a fallthrough; a conditional always has two targets. You can make one of those targets the very next block if you want to emulate conditional-gotos-with-fallthrough
So could I create a block for each instruction or is it better to do the per condition?
In other words, do the blocks prevent Cranelift from doing any optimizations?
It would be quite costly to build a basic block per instruction. The usual way to break code into blocks is to split wherever a label occurs
@Chris Fallin So that's probably going to be a little more complex then. Does wasmtime have something like this or has anyone already tried to implement a JVM using Cranelift?
I'm not aware of any other JVMs done using Cranelift. However this sort of thing (translating JVM bytecode to a CFG) should exist in any other optimizing JVM as well, it's not anything specific to Cranelift's requirements; I would recommend looking at how e.g. OpenJDK builds its IR, as inspiration for your project
@Robin Lindner In case it's helpful, I've written a JVM using a custom JIT (Cranelift didn't exist at the time) which uses an SSA-style IR which is organized into a control flow graph of basic blocks. As Chris alluded to, every branch represents the end of a block, and every branch target represents the start of a block. For a block ending in a goto
, there's only a single outgoing edge to the target block. For a block ending in e.g. a ifeq
, there are two outgoing edges for the two target blocks. For a block ending in a tableswitch
, there may be an arbitrary number of outgoing edges corresponding to each of the switch cases. And of course each branch target can be a target for any number of branches, so it may have any number of incoming edges.
Here's how I recommend thinking of it: Java bytecode implicitly defines a control flow graph -- you just need turn that implicit graph into an explicit one for Cranelift. I haven't used Cranelift yet myself, so I'll leave it to others to answer any specific questions about it, but I'm happy to answer questions about the Java side of things.
Thank you @Joel Dice I'll take a look at your project.
@Chris Fallin
In order to understand a bit of the Cranelift architecture, etc. I would like to get a halfway working prototype running first, regardless of whether it has underground performance or not.
Therefore I chose the simple case that I create a block for each instruction.
For some reason I get the error that it doesn't find the entry block. Where is the problem?
https://gist.github.com/deeprobin/4bb6e98bff65271c92861ca7e165997a
Last updated: Nov 22 2024 at 17:03 UTC