@usr: Presently, given void foo(int32_t x); int i; int16_t a[256]; ... a[i]++; foo(a[i]);
optimal code for something like an ARM7-TDMI would be ldrb r0,[r1+r2] / add r0,#1 / strb r0,[r1+r2] / asl r0,r0,#16 / asr r0,r0,#16 / bl _foo
. The fourth and fifth instructions essentially perform temp = (signed)((unsigned)temp<<16)>>16
(the fastest way to convert int32_t
to int16_t
on that CPU). If a
were declared oint16_t
which behaved as I described, it shouldn't be hard...
...for a compiler to figure out that there wasn't any need to coerce the value computed for a[i]
into the range of an int16_t
before passing it to foo
. A savings of two instruction words and two cycles, with behavior that is consistent with a simple-to-understand execution model. Another thing to note about such types is that they would reduce the need for many kinds of optimization. Given int16_t x=0; for (i=0; i<n; i++) x+=i; foo(x);
a compiler could easily interpret x
as...
...a uint32_t
register within the loop and delay the coercion to int16_t
until the call to foo
, so the runtime cost of the coercion would only be incurred once rather than n
times, but such optimizations take work. If x
were type oint16_t
, the compiler could simply omit the coercion altogether and not have to rely upon the optimizer to minimize the cost thereof.