Page 1 of 1

Compound initializers for arrays

PostPosted: Fri Jan 04, 2019 5:59 pm
by phantombeta
Exactly what it says on the thread title.
Why haven't I made a PR yet? Two reasons. First, I'm not sure if I did everything necessary, and if I did everything correctly.
Second, this just felt WAY too easy to code... I feel like there must be something horribly wrong that's very well hidden in it and that'll only show up after this code is in a stable release build, what with how it all went so well so smoothly up until now.

Re: Compound initializers for arrays

PostPosted: Fri Jan 04, 2019 6:27 pm
by Graf Zahl
If you don't do a PR I cannot check it.

Re: Compound initializers for arrays

PostPosted: Fri Jan 04, 2019 6:46 pm
by phantombeta

Re: Compound initializers for arrays

PostPosted: Fri Jan 04, 2019 10:31 pm
by phantombeta
I force-pushed some changes to fix consistency issues, change the new class' name to something that makes more sense, fix a crash where it'd run Emit even if it failed resolving the values and fix some minor issues I found in the code while fixing that.
(Fucking knew it couldn't have been that easy... >_>)

Re: Compound initializers for arrays

PostPosted: Sat Jan 05, 2019 2:01 am
by Graf Zahl
Thanks. It looks mostly ok, but for arrays only containing constant values I wouldn't use the constant space as a store for the source data. I'm not sure if it's worth the added work, though.

Re: Compound initializers for arrays

PostPosted: Sat Jan 05, 2019 6:36 am
by phantombeta
I'd say a decent way to deal with that would be to add opcodes for moving a constant value to memory or a register, but where the constant value is stored in the opcode's data itself instead of in the constant space.
It'd also mean I wouldn't have to move the constants to a register to be able to store them in memory. (Since there's no opcodes for moving a constant to memory directly)

I'd be willing to add and code these opcodes myself, of course.

While somewhat only tangentially related - speaking of adding opcodes, I've been thinking about adding a function to initialize all values in an array to a single value. It'd call memset internally for performance, but the only secure way I can think of to do this would be to add an opcode for it - which I'd be fine with doing, but I imagine I'd need your permission for that first.

Re: Compound initializers for arrays

PostPosted: Sat Jan 05, 2019 7:43 am
by Graf Zahl
As you noticed, the entire VM was strictly modelled after some RISC processor, I believe the MIPS. Whether that was such a smart move is up for debate. I have my doubts about that and if it wouldn't limit the targets would actually consider rewriting the code generator to directly target AsmJIT.

But in the end, what would be gained here? The generated code still initializes all members by manually copying data around. For purely constant arrays a memcpy instruction may make more sense than trying to fiddle around with the instruction set.

Re: Compound initializers for arrays

PostPosted: Sat Jan 05, 2019 7:58 am
by dpJudas
I don't think targeting AsmJIT directly would be the better solution - it is too low level. It would have been better if the VM opcodes had instead been modeled with SSA (static single assignment) variables (instead of registers) and basic blocks for branching. This would have made it significantly easier to add the missing optimization passes that a compiler needs before things are lowered to CPU opcodes.

Re: Compound initializers for arrays

PostPosted: Sat Jan 05, 2019 8:18 am
by Graf Zahl
Like I said last time, I think it would have been better to fix the VM before adding a JIT compiler.. ;)

To be honest, I would have never ever tried to transform this byte code directly into machine code because even as a VM it was already showing too many problems, like the extremely inefficient branching and pointless redundant null pointer checks on pointer variables and a few things more.

Regarding the compiler backend, I think you can clearly see that it was my first step into that area of coding. Of course there's problems but ultimately the goal wasn't to create an IR that can be JITed but to create byte code for the existing VM.

Re: Compound initializers for arrays

PostPosted: Sat Jan 05, 2019 8:52 am
by dpJudas
Hehe, I'm by no means a compiler expert myself. :)

My knowledge about SSA vars and basic blocks comes mostly from the LLVM architecture. I also once wrote an incomplete C# compiler for LLVM that helps me compare your compiler frontend to that one. The two most striking differences are that you solved the register allocation problem and constant folding in the front end, while I forwarded those problems to the LLVM back end.

While the VM opcodes doesn't map *that* badly to AsmJIT (thanks to its virtual register allocator feature), the biggest problem left is how to implement the missing optimization passes: dead code elimination, constant folding and function inlining. What all those have in common is that they affect if variables end up as constants and consequently how many registers are needed. The current VM set doesn't prevent writing such optimization passes, but they do make it somewhat harder.

About fixing the VM before adding the JIT, my answer to that is roughly the same as it was for the calling convention. It would have made the work required much bigger, which ultimately would have stopped it in its tracks. I personally prefer iterative solutions if possible, even if it sometimes means doing more work in the long run. A non-optimizing JIT is better than no JIT at all, just like your direct-to-VM compiler code was better than no ZScript. Our current code may not win a design award, but I just read the other day that Ruby only reached the stage of outputting C code that it then feeds into a C compiler - we are already ahead of THAT. :)

Re: Compound initializers for arrays

PostPosted: Sun Jan 06, 2019 6:08 am
by phantombeta