------- Comment #14 from zadeck at naturalbridge dot com 2007-06-30 20:11 ------- Subject: Re: [4.3 Regression] function with asm() does not setup stack frame
ian at airs dot com wrote: > ------- Comment #13 from ian at airs dot com 2007-06-30 18:08 ------- > The problem here is that although the stack pointer is not used in the > function, adjusting it does reserve space on the stack for the local variables > which are used. The local variables are accessed via the frame pointer with a > negative offset. Deleting the adjustment of the stack pointer is causing that > the reference to be implicitly invalid. This test case makes the problem > obvious via an asm which essentially does a function call which the compiler > doesn't know about. If the asm weren't there, though, there would still be a > difficult to diagnose problem in that an interrupt at the wrong time would > corrupt the value of the local variables. > > One possible approach to this is that DF should note that any reference to a > local variable via the frame pointer is implicitly a use of the stack > pointer. > Note that this doesn't necessarily mean a negative offset from the frame > pointer, although it does in this case. On processors like the Thumb even > local variables are accessed as positive offsets from the frame pointer, and > parameters are accessed by larger positive offsets. We also need to consider > whether any asm statement is a use of the stack pointer. It may be that DF > should treat an asm statement however it treats a function call with regard to > uses of the stack pointer. A non-volatile asm would be a const call, and a > volatile asm would be an ordinary call. I'm not completely sure about that, > but it seems worth considering. > > A simpler approach would be for DCE to simply not remove adjustments to the > stack pointer. I believe this would have to be done whether the adjustment > was > frame related or not. I think the fact that the instruction is frame related > is probably a red herring here. > > > it is interesting to read the comments as a historical record to what we do. Looking at it from the point of view that we should treat asms more like function calls, there is a disturbing comment in the code that scans the asm inputs: case ASM_INPUT: { /* Traditional and volatile asm instructions must be considered to use and clobber all hard registers, all pseudo-registers and all of memory. So must TRAP_IF and UNSPEC_VOLATILE operations. Consider for instance a volatile asm that changes the fpu rounding mode. An insn should not be moved across this even if it only uses pseudo-regs because it might give an incorrectly rounded result. However, flow.c's liveness computation did *not* do this, giving the reasoning as " ?!? Unfortunately, marking all hard registers as live causes massive problems for the register allocator and marking all pseudos as live creates mountains of uninitialized variable warnings." In order to maintain the status quo with regard to liveness and uses, we do what flow.c did and just mark any regs we can find in ASM_OPERANDS as used. In global asm insns are scanned and regs_asm_clobbered is filled out. For all ASM_OPERANDS, we must traverse the vector of input operands. We can not just fall through here since then we would be confused by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate traditional asms unlike their normal usage. */ if (code == ASM_OPERANDS) { int j; for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++) df_uses_record (collection_rec, &ASM_OPERANDS_INPUT (x, j), DF_REF_REG_USE, bb, insn, flags); return; } break; } Asside from the fallout in the register allocator or uninitialized warnings, there really is not problem adding the stack_pointer. Flow could get away with it because it could assume that the rest of the optimizations were stupid or had been neutered. I do not think that is the way to go. We add the stack pointer not matter if the function call is a const call or not. Note that const calls do generally read the stack. Adding the stack pointer for asms is certainly the easiest thing to do. If you think that we want to view mem refs off the frame pointer as if they also touch the stack pointer, we can do that, but i would ask the question as to "why just in dce?" -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32475