This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Label question


On 20-Sep-2002, Luc Van Oostenryck <luc.vanoostenryck@easynet.be> wrote:
> Mustafa Celik wrote:
> !! "computed goto's" was not working totally correctly for me in gcc 2.8.1 
> and 2.95.3
> (not verified with more recent version) especially code path reachability.

We got it to work fine in 3.2, 3.1, 2.95.3 and (except on SPARC) in 2.8.1
for the Mercury compiler.  Basically you just need to to include at
least one reachable `goto *' with an unknown target.

See the code fragments below, from runtime/mercury_goto.h in the Mercury
distribution (available from <http://www.cs.mu.oz.au/mercury/>).


  /* The following macro expands to a dummy assembler statement which
  ** contains no code, but which tells gcc that it uses the specified
  ** address as an input value.  This is used to trick gcc into
  ** thinking that the address is used, in order to suppress unwanted
  ** optimizations.  (We used to use `volatile_global_pointer =
  ** address' to suppress optimization, but this way is better because
  ** it doesn't generate any code.)
  */
  #define MR_PRETEND_ADDRESS_IS_USED(address)		\
	__asm__ __volatile__("" : : "g"(address))
  /*
  Explanation:
  	__asm__
  	__volatile__			don't optimize this asm away
  	(
  		""			empty assembler code
  		: 			no outputs
  		: "g" (address)		one input value, `address';
  					"g" means that it can go in any
  					general-purpose register
  	)
  */


  /* Since we're jumping into and out of the middle of functions,
  ** we need to make sure that gcc thinks that (1) the function's address
  ** is used (otherwise it may optimize the whole function away) and
  ** (2) the `return' statement is reachable (otherwise its dataflow
  ** analysis for delay slot scheduling may think that global
  ** register variables which are only assigned to in the function
  ** cannot be live, when in fact they really are).
  ** That is what the two occurrences of the MR_PRETEND_ADDRESS_IS_USED
  ** macro are for.
  ** For versions of gcc later than egcs 1.1.2 (which corresponds to gcc 2.91,
  ** according to __GNUC_MINOR__), and in particular for gcc 2.95,
  ** we also need to include at least one `goto *' with an unknown
  ** target, so that gcc doesn't optimize away all the labels
  ** because it thinks they are unreachable.
  ** The MR_dummy_identify_function() function just returns the address
  ** passed to it, so `goto *MR_dummy_identify_function(&& dummy_label);
  ** dummy_label:' is the same as `goto dummy_label; dummy_label:', i.e. it
  ** just falls through. For older versions of gcc, we don't do this, since it
  ** adds significantly to the code size.
  */
  #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 91)
    /* gcc version > egcs 1.1.2 */
    #define MR_BEGIN_MODULE(module_name)				\
	void module_name(void) {					\
		MR_PRETEND_ADDRESS_IS_USED(module_name);		\
		MR_PRETEND_ADDRESS_IS_USED(				\
			&&MR_PASTE2(module_name,_dummy_label));		\
		goto *MR_dummy_identify_function(			\
			&&MR_PASTE2(module_name,_dummy_label));		\
		MR_PASTE2(module_name,_dummy_label):			\
		{

-- 
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]