From: Borja F. <bor...@gm...> - 2011-04-05 21:31:07
|
Hello, it's been a little while since last time we got an update. Although I haven't commited any code during the last 3 months, I want to say that doesn't mean the project is dead or something similar, it's just the opposite that's why i want to explain what is the current status, in fact i havent stopped working on this at all. >From Jan to approximately March I've been investigating different ways to handle the insane reg constraints to pair adjacent regs to store 16bit and wider data with the PBQP allocator and other ideas i had, I think i had like 4 branches to see which one was the best. From here I want to give a big thank to Lang Hames, the author of this allocator for all the help he gave me and for his interest. But solving this using this approach was getting pretty hard, tracking which virtual reg had the low and hi part of a 16bit value is simply impossible in LLVM with the current interfaces in order to build the constraint matrix for the PBPQ allocator, in addition, there were other underlying problems when working with only 8bit types as a legal sizes, like 16 bit pointers. So around mid March I started a new backend from scratch with a new idea which has simplified everything in a huge manner. Like everything in this life, all things have pros and cons so we have to get a balance. The biggest pro of this approach is it's simplicity, the cons is that we'll have to work a bit harder to get some nice optimizations in. But these cons aren't too bad at all, because most of them would have to be handled in all aproaches so after all, we will have to get our hands dirty to get really nice code. The basic idea is to make 16bit data legal, that means working with pseudo register pairs and psuedo 16 bit instructions that need to get expanded into 8 bit instructions in a later stage. When we get a movw or adiw/sbiw we leave them alone because they're legal instructions but when we get say a 16bit and instr we have to expand it to two and instructions. As i said, when we move further we can start thinking in introducing optimizations over pseudo intrs which is something that gcc doesn't do very well, and after all we want to beat it. So the current status is: - Added support for all arithmetic and binary instructions for all data types, except mul. Including, INC/DEC, COM/NEG and SWAP. - Convert all (add x, imm) into sub(x, -imm) since we dont have an add with imm instruction. This saves doing ldi+add into a subi. - Handle adiw/sbiw instructions when it's beneficial. - Allocate everything in register pairs, as it should be, and emit movw always, no need for more heuristics. - Implemented calling conventions, including argument passing, return values, and function calls, including externals symbols which isn't handled in the current backend in SVN. - Pointers are now 16bits as it should be, and not 8bits as a hack. - Added support for ICALL. - BIG ONE: Added support for data memory operatons, this includes: ld, ldd, st and std. This adds support for the reg+imm addressing mode when imm<64. - Print for ld, ldd, st and std when emmiting asm code the X, Y, Z names. I think this is it for the moment, probably i've left something out, but those are the basic points. I'm currently working in adding support for lds and sts, so we can load/store global symbols. And after that is implemented we'll be able to implement stack frames, which is an important milestone. I'll commit the new code in a few days, i want to get something done before. Let me know your thoughts. For me the most important part is to remark that we're moving further. PS: John do you get clang rebuilt each time you recompile LLVM, if that's the case do you know a way to stop this because linking it takes like 40secs here. Im using ccache as mentioned in some doc file. |