From cdcfed9737c6cd20a36833b540c030f6601fea03 Mon Sep 17 00:00:00 2001 From: bellard Date: Fri, 22 Nov 2002 22:16:30 +0000 Subject: [PATCH] restored include file optimization - added static on all globals --- tcc.c | 268 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 134 insertions(+), 134 deletions(-) diff --git a/tcc.c b/tcc.c index c8637e2..bf84795 100644 --- a/tcc.c +++ b/tcc.c @@ -213,7 +213,8 @@ typedef struct BufferedFile { unsigned char *buf_end; int fd; int line_num; /* current line number - here to simply code */ - int ifndef_macro; /*'#ifndef macro \n #define macro' search */ + int ifndef_macro; /* #ifndef macro / #endif search */ + int ifndef_macro_saved; /* saved ifndef_macro */ int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */ char inc_type; /* type of include */ char inc_filename[512]; /* filename specified by the user */ @@ -249,73 +250,76 @@ typedef struct CachedInclude { } CachedInclude; /* parser */ -struct BufferedFile *file; -int ch, tok, tok1; -CValue tokc, tok1c; -CString tokcstr; /* current parsed string, if any */ +static struct BufferedFile *file; +static int ch, tok, tok1; +static CValue tokc, tok1c; +static CString tokcstr; /* current parsed string, if any */ +/* additionnal informations about token */ +static int tok_flags; +#define TOK_FLAG_BOL 0x0001 /* beginning of line before */ +#define TOK_FLAG_BOF 0x0002 /* beginning of file before */ +#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */ + /* if true, line feed is returned as a token. line feed is also returned at eof */ -int return_linefeed; -/* set to TRUE if eof was reached */ -int eof_seen; -Section *text_section, *data_section, *bss_section; /* predefined sections */ -Section *cur_text_section; /* current section where function code is +static int return_linefeed; +static Section *text_section, *data_section, *bss_section; /* predefined sections */ +static Section *cur_text_section; /* current section where function code is generated */ /* bound check related sections */ -Section *bounds_section; /* contains global data bound description */ -Section *lbounds_section; /* contains local data bound description */ +static Section *bounds_section; /* contains global data bound description */ +static Section *lbounds_section; /* contains local data bound description */ /* symbol sections */ -Section *symtab_section, *strtab_section; +static Section *symtab_section, *strtab_section; /* debug sections */ -Section *stab_section, *stabstr_section; +static Section *stab_section, *stabstr_section; /* loc : local variable index ind : output code index rsym: return symbol anon_sym: anonymous symbol index */ -int rsym, anon_sym, - prog, ind, loc; +static int rsym, anon_sym, ind, loc; /* expression generation modifiers */ -int const_wanted; /* true if constant wanted */ -int nocode_wanted; /* true if no code generation wanted for an expression */ -int global_expr; /* true if compound literals must be allocated - globally (used during initializers parsing */ -CType func_vt; /* current function return type (used by return - instruction) */ -int func_vc; -int last_line_num, last_ind, func_ind; /* debug last line number and pc */ -int tok_ident; -TokenSym **table_ident; -TokenSym *hash_ident[TOK_HASH_SIZE]; -char token_buf[STRING_MAX_SIZE + 1]; -char *funcname; -Sym *global_stack, *local_stack; -Sym *define_stack; -Sym *label_stack; +static int const_wanted; /* true if constant wanted */ +static int nocode_wanted; /* true if no code generation wanted for an expression */ +static int global_expr; /* true if compound literals must be allocated + globally (used during initializers parsing */ +static CType func_vt; /* current function return type (used by return + instruction) */ +static int func_vc; +static int last_line_num, last_ind, func_ind; /* debug last line number and pc */ +static int tok_ident; +static TokenSym **table_ident; +static TokenSym *hash_ident[TOK_HASH_SIZE]; +static char token_buf[STRING_MAX_SIZE + 1]; +static char *funcname; +static Sym *global_stack, *local_stack; +static Sym *define_stack; +static Sym *label_stack; -SValue vstack[VSTACK_SIZE], *vtop; -int *macro_ptr, *macro_ptr_allocated; +static SValue vstack[VSTACK_SIZE], *vtop; +static int *macro_ptr, *macro_ptr_allocated; /* some predefined types */ -CType char_pointer_type, func_old_type, int_type; +static CType char_pointer_type, func_old_type, int_type; /* compile with debug symbol (and use them if error during execution) */ -int do_debug = 0; +static int do_debug = 0; /* compile with built-in memory and bounds checker */ -int do_bounds_check = 0; +static int do_bounds_check = 0; /* display benchmark infos */ -int do_bench = 0; -int total_lines; -int total_bytes; +static int do_bench = 0; +static int total_lines; +static int total_bytes; /* use GNU C extensions */ -int gnu_ext = 1; +static int gnu_ext = 1; /* use Tiny C extensions */ -int tcc_ext = 1; +static int tcc_ext = 1; /* max number of callers shown if error */ static int num_callers = 6; @@ -1225,6 +1229,21 @@ static void cstr_free(CString *cstr) #define cstr_reset(cstr) cstr_free(cstr) +static CString *cstr_dup(CString *cstr1) +{ + CString *cstr; + int size; + + cstr = tcc_malloc(sizeof(CString)); + size = cstr1->size; + cstr->size = size; + cstr->size_allocated = size; + cstr->data_allocated = tcc_malloc(size); + cstr->data = cstr->data_allocated; + memcpy(cstr->data_allocated, cstr1->data_allocated, size); + return cstr; +} + /* XXX: unicode ? */ static void add_char(CString *cstr, int c) { @@ -1525,32 +1544,10 @@ int tcc_getc_slow(BufferedFile *bf) /* no need to put that inline */ void handle_eob(void) { - TCCState *s1 = tcc_state; - /* no need to do anything if not at EOB */ if (file->buf_ptr <= file->buf_end) return; - - for(;;) { - ch = tcc_getc_slow(file); - if (ch != CH_EOF) - return; - eof_seen = 1; - if (return_linefeed) { - ch = '\n'; - return; - } - if (s1->include_stack_ptr == s1->include_stack) - return; - /* add end of include file debug info */ - if (do_debug) { - put_stabd(N_EINCL, 0, 0); - } - /* pop include stack */ - tcc_close(file); - s1->include_stack_ptr--; - file = *s1->include_stack_ptr; - } + ch = tcc_getc_slow(file); } /* read next char from current input file and handle end of input buffer */ @@ -1668,7 +1665,8 @@ void preprocess_skip(void) start_of_line = 1; a = 0; - while (1) { + for(;;) { + redo_no_start: switch(ch) { case ' ': case '\t': @@ -1676,19 +1674,18 @@ void preprocess_skip(void) case '\v': case '\r': inp(); - break; + goto redo_no_start; case '\n': start_of_line = 1; file->line_num++; inp(); - break; + goto redo_no_start; case '\\': handle_stray(); - break; + goto redo_no_start; /* skip strings */ case '\"': case '\'': - start_of_line = 0; sep = ch; inp(); while (ch != sep) { @@ -1714,8 +1711,6 @@ void preprocess_skip(void) parse_comment(); } else if (ch == '/') { parse_line_comment(); - } else { - start_of_line = 0; } break; @@ -1731,16 +1726,15 @@ void preprocess_skip(void) else if (tok == TOK_ENDIF) a--; } - start_of_line = 0; break; case CH_EOF: expect("#endif"); break; default: inp(); - start_of_line = 0; break; } + start_of_line = 0; } the_end: ; } @@ -1846,22 +1840,13 @@ static void tok_str_add(TokenString *s, int t) static void tok_str_add2(TokenString *s, int t, CValue *cv) { - int n, i, size; - CString *cstr, *cstr1; + int n, i; CValue cv1; tok_str_add(s, t); if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) { /* special case: need to duplicate string */ - cstr1 = cv->cstr; - cstr = tcc_malloc(sizeof(CString)); - size = cstr1->size; - cstr->size = size; - cstr->size_allocated = size; - cstr->data_allocated = tcc_malloc(size); - cstr->data = cstr->data_allocated; - memcpy(cstr->data_allocated, cstr1->data_allocated, size); - cv1.cstr = cstr; + cv1.cstr = cstr_dup(cv->cstr); tok_str_add(s, cv1.tab[0]); } else { n = tok_ext_size(t); @@ -2107,17 +2092,11 @@ static inline void add_cached_include(TCCState *s1, int type, dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e); } - -enum IncludeState { - INCLUDE_STATE_NONE = 0, - INCLUDE_STATE_SEEK_IFNDEF, -}; - -void preprocess(void) +/* is_bof is true if first non space token at beginning of file */ +static void preprocess(int is_bof) { TCCState *s1 = tcc_state; int size, i, c, n, line_num; - enum IncludeState state; char buf[1024], *q, *p; char buf1[1024]; BufferedFile *f; @@ -2126,9 +2105,6 @@ void preprocess(void) return_linefeed = 1; /* linefeed will be returned as a token. EOF is also returned as line feed */ - state = INCLUDE_STATE_NONE; - eof_seen = 0; - redo1: next_nomacro(); redo: switch(tok) { @@ -2253,16 +2229,8 @@ void preprocess(void) if (do_debug) { put_stabs(file->filename, N_BINCL, 0, 0, 0); } - /* we check for the construct: #ifndef IDENT \n #define IDENT */ - inp(); - /* get first non space char */ - while (is_space(ch) || ch == '\n') - cinp(); - if (ch != '#') - goto the_end; - state = INCLUDE_STATE_SEEK_IFNDEF; - cinp(); - goto redo1; + tok_flags |= TOK_FLAG_BOF; + goto the_end; } break; case TOK_IFNDEF: @@ -2277,11 +2245,13 @@ void preprocess(void) next_nomacro(); if (tok < TOK_IDENT) error("invalid argument for '#if%sdef'", c ? "n" : ""); - if (state == INCLUDE_STATE_SEEK_IFNDEF) { + if (is_bof) { if (c) { +#ifdef INC_DEBUG + printf("#ifndef %s\n", get_tok_str(tok, NULL)); +#endif file->ifndef_macro = tok; } - state = INCLUDE_STATE_NONE; } c = (define_find(tok) != 0) ^ c; do_if: @@ -2311,31 +2281,27 @@ void preprocess(void) if (!(c & 1)) { skip: preprocess_skip(); - state = INCLUDE_STATE_NONE; + is_bof = 0; goto redo; } break; case TOK_ENDIF: if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr) error("#endif without matching #if"); + s1->ifdef_stack_ptr--; + /* '#ifndef macro' was at the start of file. Now we check if + an '#endif' is exactly at the end of file */ if (file->ifndef_macro && - s1->ifdef_stack_ptr == (file->ifdef_stack_ptr + 1)) { - /* '#ifndef macro \n #define macro' was at the start of - file. Now we check if an '#endif' is exactly at the end - of file */ + s1->ifdef_stack_ptr == file->ifdef_stack_ptr) { + file->ifndef_macro_saved = file->ifndef_macro; + /* need to set to zero to avoid false matches if another + #ifndef at middle of file */ + file->ifndef_macro = 0; while (tok != TOK_LINEFEED) next_nomacro(); - /* XXX: should also skip comments, but it is more complicated */ - if (eof_seen) { - add_cached_include(s1, file->inc_type, file->inc_filename, - file->ifndef_macro); - } else { - /* if not end of file, we must desactivate the ifndef - macro search */ - file->ifndef_macro = 0; - } + tok_flags |= TOK_FLAG_ENDIF; + goto the_end; } - s1->ifdef_stack_ptr--; break; case TOK_LINE: next(); @@ -2378,7 +2344,7 @@ void preprocess(void) break; } /* ignore other preprocess commands or #! for C scripts */ - while (tok != TOK_LINEFEED && tok != TOK_EOF) + while (tok != TOK_LINEFEED) next_nomacro(); the_end: return_linefeed = 0; @@ -2780,11 +2746,10 @@ void parse_number(const char *p) /* return next token without macro substitution */ static inline void next_nomacro1(void) { - int b, t, start_of_line; + int b, t; char *q; TokenSym *ts; - start_of_line = 0; redo_no_start: switch(ch) { case ' ': @@ -2799,13 +2764,48 @@ static inline void next_nomacro1(void) handle_stray(); goto redo_no_start; + case CH_EOF: + { + TCCState *s1 = tcc_state; + + if (return_linefeed) { + tok = TOK_LINEFEED; + } else if (s1->include_stack_ptr == s1->include_stack) { + /* no include left : end of file */ + tok = TOK_EOF; + } else { + /* pop include file */ + + /* test if previous '#endif' was after a #ifdef at + start of file */ + if (tok_flags & TOK_FLAG_ENDIF) { +#ifdef INC_DEBUG + printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL)); +#endif + add_cached_include(s1, file->inc_type, file->inc_filename, + file->ifndef_macro_saved); + } + + /* add end of include file debug info */ + if (do_debug) { + put_stabd(N_EINCL, 0, 0); + } + /* pop include stack */ + tcc_close(file); + s1->include_stack_ptr--; + file = *s1->include_stack_ptr; + inp(); + goto redo_no_start; + } + } + break; + case '\n': file->line_num++; if (return_linefeed) { - /* XXX: should eat token ? */ tok = TOK_LINEFEED; } else { - start_of_line = 1; + tok_flags |= TOK_FLAG_BOL; inp(); goto redo_no_start; } @@ -2813,8 +2813,8 @@ static inline void next_nomacro1(void) case '#': minp(); - if (start_of_line) { - preprocess(); + if (tok_flags & TOK_FLAG_BOL) { + preprocess(tok_flags & TOK_FLAG_BOF); goto redo_no_start; } else { if (ch == '#') { @@ -3108,13 +3108,11 @@ static inline void next_nomacro1(void) tok = ch; cinp(); break; - case CH_EOF: - tok = TOK_EOF; - break; default: error("unrecognized character \\x%02x", ch); break; } + tok_flags = 0; #if defined(PARSE_DEBUG) printf("token = %s\n", get_tok_str(tok, &tokc)); #endif @@ -3386,6 +3384,7 @@ static int macro_subst_tok(TokenString *tok_str, if (macro_ptr) { t = *macro_ptr; } else { + /* XXX: incorrect with comments */ while (is_space(ch) || ch == '\n') cinp(); t = ch; @@ -7642,7 +7641,8 @@ static int tcc_compile(TCCState *s1) s1->nb_errors = 0; s1->error_set_jmp_enabled = 1; - ch = '\n'; /* needed to parse correctly first preprocessor command */ + ch = '\n'; /* XXX: suppress that*/ + tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; next(); decl(VT_CONST); if (tok != -1)