Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!think.com!mintaka!spdcc!iecc!compilers-sender From: Olivier.Levillain@cl.bull.fr (Olivier Levillain) Newsgroups: comp.compilers Subject: Re: Squashing C Source Keywords: optimize Message-ID: <429@clbull.cl.bull.fr> Date: 18 Dec 90 14:24:31 GMT References: <10767.9012051639@subnode.sari.ed.ac.uk> <14662@goofy.megatest.UUCP> Sender: compilers-sender@iecc.cambridge.ma.us Reply-To: Olivier.Levillain@cl.bull.fr (Olivier Levillain) Organization: Bull, Les Clayes, France Lines: 89 Approved: compilers@iecc.cambridge.ma.us In article <14662@goofy.megatest.UUCP>, megatest!djones@decwrl.dec.com (Dave Jones) writes: |>Now then, please tell us why in the world you would want to make an entire |>program into one procedure. That will certainly make the resulting object |>code slower. For one thing, on most machines, the procedure call/return is |>an efficient way to save and restore registers. For another, unless the |>program is a rather simple one with most procedures being called from only |>one place, the program will be larger. On machines that do paging, larger |>usually means slower, sometimes much slower. I don't agree with these arguments. |> For one thing, on most machines, the procedure call/return is |>an efficient way to save and restore registers. Saving and restoring registers even if it is efficient, can be expensive especially on CISC machine. On our machine (BULL DPS7), it uses 50 cycles + 1 cycle by register to save/restore. |> For another, unless the |>program is a rather simple one with most procedures being called from only |>one place, the program will be larger. I wrote myself an inliner for a common code generator which generates code for several front-ends (C, Fortran, PL1). Inlining is done on an intermediary language and takes place before local and global optimization. So that the optimizers can work on larger sequences of linear code. Big parts in and around call of inlined functions disappear in the optimizers because their context is more completely defined. If you write: f (x) int x; { switch (x) { case 1: return 1;break; case 2: return 0;break; case 3: return 1;break; case 4; return 2;break; } } main () { int y; ... y=2; ... if (f(y)) ... else ; ... Without an inliner, the whole code will be generated. If you "inline" f, generated code will look as if you wrote: main () { int y; ... y=2; ... ; ... because, after f has been inlined, optimizer can compute at compile-time that f(y) will return 0. So that, the final size of generated code is not necessarily very much bigger. |>On machines that do paging, larger |>usually means slower, sometimes much slower. If the procedure you call is not in the same page that the page from where you call this procedure, OS will also have a missing page exception to handle. |>I will leave you with one last word: "recursion". You will have to |>reinvent procedure calls to handle recursion. Inlining procedure does not mean that you don't call a procedure any longer. You can just inline a call to a (directly or not) recursive procedure and leave the really recursive call in place. As a conclusion, just one thing: we have an improvement of 30% on dhrystone1.1 benchmark when using the inliner. Olivier LEVILLAIN --- Bull S.A. BSS7-LANG-LSLI e-mail: Olivier.Levillain@cl.bull.fr Rue Jean-Jaures, F6/1D/10, BP 53 tel: (33-1) 34-80-65-52 78340 Les Clayes-sous-Bois, France Fax: (33-1) 34-80-79-50 -- Send compilers articles to compilers@iecc.cambridge.ma.us or {ima | spdcc | world}!iecc!compilers. Meta-mail to compilers-request.