I am looking at ways of dynamically realigning the runtime stack in GCC. Currently it looks like x86 is the only architecture that supports this.
The issue that I am trying to address is MSA registers on MIPS. The O32 MIPS ABI specifies an 8 byte aligned stack but MSA registers should be 16 byte aligned when spilled to memory. I don't see anyway to do this unless we can force the stack to be 16 byte aligned. Richard Henderson created a way of aligning local variables with an alignment greater than the maximum stack alignment by using alloca and creating an aligned pointer in to that space but that doesn't help when reload or LRA is spilling a register to memory. My thought was to use alloca, not to create space, but to move the stack pointer to an aligned address so that subsequent spills using the stack pointer would be to aligned addresses. As a test I created a simple gimple pass that called __builtin_alloca at the beginning of each function just to see if that was possible and it seemed to work fine. This seemed to be much cleaner than when I tried to modify the stack pointer in expand_prologue. When I did it there I had issues with tests that use setjmp/longjmp and there seems to be a lot of bookkeeping needed to track registers and offsets when working at that level. With this gimple pass that was all taken care of by existing mechanisms. Of course that test just did an alloca of 8 bytes, the actual code needs to allocate a dynamic number of bytes depending on the current value of the stack pointer. __builtin_alloca(stack_pointer MOD desired_alignment) So my first question is: Is there way to access/refrence the stack pointer in a gimple pass? If so, how? My second question is what do people think about this as a way to dymanically align the stack? It seems a lot simpler and more target independent than what x86 is doing. Steve Ellcey sell...@imgtec.com A pass that inserts __builtin_alloca(8) at front of all routines: unsigned int pass_realign_stack::execute (function *fun) { basic_block bb; gimple g; tree size; gimple_stmt_iterator gsi; bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (fun)); gsi = gsi_start_bb (bb); size = build_int_cst (sizetype, 8); g = gimple_build_call (builtin_decl_explicit (BUILT_IN_ALLOCA), 1, size); gsi_insert_before (&gsi, g, GSI_NEW_STMT); return 0; }