From mboxrd@z Thu Jan 1 00:00:00 1970 From: Zack Weinberg To: egcs@egcs.cygnus.com Subject: a strange infelicity of register allocation Date: Sat, 23 Jan 1999 22:42:00 -0000 Message-id: <199901240642.BAA27889@blastula.phys.columbia.edu> X-SW-Source: 1999-01/msg00124.html Consider this loop: char *p = buffer, *op = out_buffer; for (;;) { char c = *p++; switch (c) { case '\0': goto out; case '\n': /* stuff... */ break; case '\r': /* similar stuff... */ break; case '?': /* other stuff... */ break; default: *op++ = c; } } out: Where each special case is long and complicated. Some of them re-use the variable c for their own purposes, but the initial store to c is dead at the beginning of each special case. The code generated copies c = *p into a register, then out to a stack slot. It then does the switch based on the contents of the register. Down in the default case, c is copied back in from the stack slot and then written to memory. If I move the default case to the top of the switch, so it begins like switch (c) { default: *op++ = c; break; then c gets to stay in a register all the time, and the code runs about twice as fast. It seems to me we should be generating identical code for both cases. Platform is x86; problem was seen with both egcs 1.1.1 and the current snapshot. The actual code I'm talking about is the function read_and_prescan in the patch for newline handling in cpplib which I just posted. zw From mboxrd@z Thu Jan 1 00:00:00 1970 From: Zack Weinberg To: egcs@egcs.cygnus.com Subject: a strange infelicity of register allocation Date: Sun, 31 Jan 1999 23:58:00 -0000 Message-ID: <199901240642.BAA27889@blastula.phys.columbia.edu> X-SW-Source: 1999-01n/msg00887.html Message-ID: <19990131235800.fLazkw14pBD6gkPsbaZL3sAPp21ZVAaHmineAu0reaE@z> Consider this loop: char *p = buffer, *op = out_buffer; for (;;) { char c = *p++; switch (c) { case '\0': goto out; case '\n': /* stuff... */ break; case '\r': /* similar stuff... */ break; case '?': /* other stuff... */ break; default: *op++ = c; } } out: Where each special case is long and complicated. Some of them re-use the variable c for their own purposes, but the initial store to c is dead at the beginning of each special case. The code generated copies c = *p into a register, then out to a stack slot. It then does the switch based on the contents of the register. Down in the default case, c is copied back in from the stack slot and then written to memory. If I move the default case to the top of the switch, so it begins like switch (c) { default: *op++ = c; break; then c gets to stay in a register all the time, and the code runs about twice as fast. It seems to me we should be generating identical code for both cases. Platform is x86; problem was seen with both egcs 1.1.1 and the current snapshot. The actual code I'm talking about is the function read_and_prescan in the patch for newline handling in cpplib which I just posted. zw