make pr | opr
lint: $(ISRC)
- lint -hbx $(DSRC) $(ISRC)
+ lint -hbx $(INCLUDES) $(DSRC) $(ISRC)
.ft \\n(Sf
.sp 1
..
-.TH ACK I
+.TH ACK 1ACK
.ad
.SH NAME
ack \- Amsterdam Compiler Kit
to a string containing the name of the routine.
.SB optimizing
.IP \-O
-.IP \-Oopt1,opt2,...
+.IP \-O\fInum\fP
+.IP \-O\fIopt1,opt2,...\fP
Try to use the named optimizers, or, if no optimizers are given,
-try using the peephole optimizer and a target optimizer.
+try to use the optimizers with optimization level <= \fInum\fP (default 1).
For optimizer names, see the table at the end of this manual page.
-For the global optimizer, the following flags indicate which
-phases must be executed:
+Currently, only the global optimizer has a level > 1.
+Higher levels will invoke more passes of the global optimizer.
+For the global optimizer, it is also possible to indicate explicitly which
+phases must be executed, using the following flags:
.RS
-.IP \-IL
+.IP \-EGO-IL
Inline substitution.
-.IP \-CS
+.IP \-EGO-CS
Commom subexpression elimination.
-.IP \-SR
+.IP \-EGO-SR
Strength reduction.
-.IP \-UD
+.IP \-EGO-UD
Use definition analysis.
-.IP \-LV
+.IP \-EGO-LV
Live variable analysis.
-.IP \-SA
+.IP \-EGO-RA
Register allocation.
-.IP \-SP
+.IP \-EGO-SP
Stack pollution.
-.IP \-BO
+.IP \-EGO-BO
Branch optimization.
-.IP \-CJ
+.IP \-EGO-CJ
Cross jumping.
+.RE
+.IP ""
+Also, the following flags may be used:
+.RS
.IP \-s<num>
-Give an indication to the IL phase, how much bigger the program may get.
-The IL phase will not make the program bigger when given \-s0.
+Give an indication to the inline substitution phase,
+how much bigger the program may get,
+in percentage. This is only used as a rough indication.
+The inline substitution phase will not make the program bigger when given \-s0.
.IP \-a
-Indicate to the IL phase that it is offered the whole program. This allows
-IL to throw away routines that it has substituted inline.
+Indicate to the inline substitution phase that it is offered the whole program.
+This allows it to throw away routines that it has substituted inline.
.IP \-Q
Give some statistics.
.IP \-T
Optimize for size.
.RE
.IP ""
-The default options are: -CJ -BO -SP.
-.br
In principle, the optimization phases can be run in any order; a phase
may even be run more than once. However, the following rules must be obeyed:
.RS
.RE
.IP ""
The global optimizer is a combiner, so, when using it, offer it all the source
-files of your program. It may throw away definitions of unused routines.
+files of your program. This is not strictly necessary, but it makes the
+global optimizer more effective.
+The current default optimization phases are:
+.RS
+.IP -
+for \-O2: CJ, BO, SP;
+.IP -
+for \-O3: CS, SR, CJ, BO, SP, UD, LV, RA;
+.IP -
+for \-O4: IL, CS, SR, CJ, BO, SP, UD, LV, RA;
+.IP -
+for higher levels: as for \-O4.
+.RE
.IP \-L
Disable the generation of code by the front ends to
record line number and source file name at run-time.
.IP \-R\fIprogram:n\fP
Set the priority of the indicated transformation to \fIn\fP.
The default priority is 0, setting it to -1 makes it highly
-inlikely the the phase will be used, setting it to 1 makes
+unlikely the the phase will be used, setting it to 1 makes
it very likely that the phase will be used.
.IP \-k
Do not stop when an error occurs, but try to transform all
EXTERN int v_flag; /* Verbose */
EXTERN int w_flag; /* Don't print warnings */
EXTERN int nill_flag; /* Don't print file names */
-EXTERN int Optflag; /* Optimizing */
+EXTERN int Optlevel; /* Optimizing */
#ifdef DEBUG
EXTERN int debug; /* Debugging control */
scanlist( l_first(phase->t_inputs), elem) {
l_in= p_cont(*elem) ;
file_final(l_in) ;
- freecore(l_in) ;
+ freecore((char *)l_in) ;
}
l_clear(&phase->t_inputs) ;
}
outfile= argv[nextarg++] ;
hide=YES ;
break ;
- case 'O': Optflag++ ;
+ case 'O': Optlevel = atoi(&argp[2]);
+ if (! Optlevel) Optlevel = 1;
Optlist= &argp[2] ;
eaten=1 ;
break ;
#define PROG "program"
#define MAPF "mapflag"
#define ARGS "args"
-#define PROP "prop"
#define STD_IN "stdin"
#define STD_OUT "stdout"
#define PREP "prep"
intrf() {
register trf *new ;
- register char *ptr ;
- growstring bline, vline ;
+ growstring bline ;
int twice ;
int name_seen=0 ;
} else
if ( strcmp(ty_name,OPT)==0 ) {
if ( new->t_optim ) twice=YES ;
- new->t_optim= YES ;
+ new->t_optim= atoi(bol) ;
+ if (new->t_optim <= 0) new->t_optim = 1;
} else
if ( strcmp(ty_name,LINKER)==0 ) {
if ( new->t_linker ) twice=YES ;
if ( strcmp(ty_name,PRIO)==0 ) {
new->t_priority= atoi(bol) ;
} else
- if ( strcmp(ty_name,PROP)==0 ) {
- /* Obsolete by now, to be removed */
- for ( ptr=bol ; *ptr ; ptr++ ) {
- switch( *ptr ) {
- case C_IN: new->t_stdin= YES ; break ;
- case C_OUT: new->t_stdout= YES ; break ;
- case 'P': new->t_isprep= YES ; break ;
- case 'p': new->t_prep= YES ; break ;
- case 'm': new->t_prep= MAYBE ; break ;
- case 'O': new->t_optim= YES ; break ;
- case 'L': new->t_linker=YES ;
- case 'C': new->t_combine= YES ; break ;
- default :
- error("Unkown option %c in %s for %s",
- *ptr,new->t_name,inname) ;
- break ;
- }
- }
- } else
if ( strcmp(ty_name,RUNT)==0 ) {
if ( new->t_rts ) twice=YES ;
new->t_rts= keeps(bol) ;
if ( new->t_needed ) vprint("\tneeded: %s\n",new->t_needed) ;
}
#endif
- if ( new->t_optim && inoptlist(new->t_name) ) {
- new->t_priority++ ;
- if ( new->t_priority < 0 ) new->t_priority=0 ;
+ if ( new->t_optim &&
+ ( new->t_optim <= Optlevel || inoptlist(new->t_name) ) ) {
+ new->t_optim = Optlevel;
}
l_add(&tr_list,(char *)new) ;
}
if ( debug>=4 ) vprint("%s-",t_cont(*scan)->t_name) ;
#endif
if( t_cont(*scan)->t_optim ) ocount++ ;else ncount++ ;
+ if( t_cont(*scan)->t_optim>Optlevel ) pcount-- ;
pcount += t_cont(*scan)->t_priority ;
}
}
( last_pcount==pcount && /* Same prio, and */
( last_ncount>ncount || /* Shorter nec. path */
(last_ncount==ncount && /* Same nec. path, optimize?*/
- (Optflag? last_ocount<ocount : last_ocount>ocount ))))) {
+ (Optlevel? last_ocount<ocount : last_ocount>ocount ))))) {
/* Yes it is */
#ifdef DEBUG
if ( debug>=3 ) vprint("Better\n");
int t_combine:1 ; /* Transform several files to one result */
int t_visited:1 ; /* NO before setup, YES after */
int t_prep:2 ; /* Needs preprocessor YES/NO/MAYBE */
- int t_optim:1 ; /* Is optimizer */
int t_isprep:1 ; /* Is preprocessor */
int t_keep:1 ; /* Keep the output file */
int t_scan:1 ; /* Used while finding path's */
int t_linker:1 ; /* The linker usurps all unrecognized flags */
int t_do:1 ; /* Is in a path to execute */
int t_blocked:1 ; /* An input file could not be produced */
+ short t_optim ; /* Is optimizer, + optimizer level */
short t_priority ; /* Importance of including phase in scan */
list_head t_inputs ; /* The input 'path's of a combiner */
char *t_origname ; /* The basename of the output file */