Article View: net.lang.c
Article #9195Re: Orphaned Response
From: Walter Bright
Date: Fri, 22 Aug 1986 16:31
Date: Fri, 22 Aug 1986 16:31
47 lines
2841 bytes
2841 bytes
In article <86900019@haddock> karl@haddock writes:
>ccvaxa!aglew (Andy Glew) writes:
>>[haddock!karl (Karl Heuer) writes:]
>>>I was trying to declare "typedef void dead;" so that I could distinguish
>>>between functions that return nothing (void perror(char *), setbuf(FILE *,
>>>char *), nullf(void)) from those that don't return (dead exit(int),
>>>abort(void), longjmp(jmp_buf, int)).
>>
>>Good point, though - an optimizing compiler could take advantage of
>>knowledge that a function doesn't return to do better register allocation,
>>etc.
>
> The only
>reasons for not adding [dead functions], as far as I can see, are as follows:
>
>[2] It won't be usable much. This is a valid point. There were a *lot* of
>nonvalued int functions before void was invented; there are only a handful of
>standard functions that are dead-ends.
Functions that never return are used a LOT in code that is loaded
with self-debugging assertion macros:
#define assert(e) ((e) || printmsgandexit("e",__LINE__,__FILE__))
>As for optimization, the calling
>function can take advantage of the knowledge by omitting extra branches (e.g.
>in "if (err) exit(1); else ...") or returns ("exit(0)" at the bottom of
>main()). This improves the space (but not time) efficiency, but not by much.
>
>I presume your comment about register allocation referred to the dead-end
>itself, in that the caller's registers need not be saved. I don't think you
>can assume this: the function "dead f() { for (;;) pause(); }" could be
>interrupted by a signal, whose handler could longjmp() to f's caller, whose
>registers must be recoverable. For similar reasons, it probably isn't okay
>to optimize the function call into a jump, unless you're careful with the
>stack.
A good optimizer can make some important optimizations if it
knows that a function will never return:
1) Register contents destroyed by the function call do not affect
the caller. This has important ramifications when doing register
allocation by coloring.
2) Functions are presumed to modify all globals and all indirect
references. Thus, if the function does not return, the optimizer
can find more common subexpressions, copy propagations, etc.
Technical Details
Message-ID:
<1074@dataio.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!seismo!lll-crg!nike!sri-spam!parcvax!hplabs!tektronix!uw-beaver!uw-june!entropy!dataio!brightReferences:
<273@watmath.UUCP> <86900019@haddock>Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!utzoo!mnetor!seismo!lll-crg!nike!sri-spam!parcvax!hplabs!tektronix!uw-beaver!uw-june!entropy!dataio!bright From: bright@dataio.UUCP (Walter Bright) Newsgroups: net.lang.c Subject: Re: Orphaned Response Message-ID: <1074@dataio.UUCP> Date: Fri, 22-Aug-86 12:31:39 EDT Article-I.D.: dataio.1074 Posted: Fri Aug 22 12:31:39 1986 Date-Received: Sun, 24-Aug-86 20:50:22 EDT References: <273@watmath.UUCP> <86900019@haddock> Reply-To: bright@dataio.UUCP (Walter Bright Organization: Data I/O Corp., Redmond WA Lines: 47