macro optimization - string constant optimisation
This commit is contained in:
parent
ab4da04aa9
commit
8ecc9cd789
1 changed files with 174 additions and 158 deletions
104
tcc.c
104
tcc.c
|
@ -588,7 +588,7 @@ void vswap(void);
|
|||
void vdup(void);
|
||||
int get_reg(int rc);
|
||||
|
||||
void macro_subst(TokenString *tok_str,
|
||||
static void macro_subst(TokenString *tok_str,
|
||||
Sym **nested_list, int *macro_str);
|
||||
int save_reg_forced(int r);
|
||||
void gen_op(int op);
|
||||
|
@ -2727,7 +2727,7 @@ int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
|
|||
}
|
||||
|
||||
/* handle the '##' operator */
|
||||
int *macro_twosharps(int *macro_str)
|
||||
static int *macro_twosharps(void)
|
||||
{
|
||||
TokenSym *ts;
|
||||
int *macro_ptr1;
|
||||
|
@ -2771,39 +2771,25 @@ int *macro_twosharps(int *macro_str)
|
|||
return macro_str1.str;
|
||||
}
|
||||
|
||||
/* do macro substitution of macro_str and add result to
|
||||
(tok_str,tok_len). If macro_str is NULL, then input stream token is
|
||||
substituted. 'nested_list' is the list of all macros we got inside
|
||||
to avoid recursing. */
|
||||
void macro_subst(TokenString *tok_str,
|
||||
Sym **nested_list, int *macro_str)
|
||||
|
||||
/* do macro substitution of current token with macro 's' and add
|
||||
result to (tok_str,tok_len). 'nested_list' is the list of all
|
||||
macros we got inside to avoid recursing. Return non zero if no
|
||||
substitution needs to be done */
|
||||
static int macro_subst_tok(TokenString *tok_str,
|
||||
Sym **nested_list, Sym *s)
|
||||
{
|
||||
Sym *s, *args, *sa, *sa1;
|
||||
int parlevel, *mstr, t, *saved_macro_ptr;
|
||||
int mstr_allocated, *macro_str1;
|
||||
CString cstr;
|
||||
CValue cval;
|
||||
Sym *args, *sa, *sa1;
|
||||
int mstr_allocated, parlevel, *mstr, t;
|
||||
TokenString str;
|
||||
char *cstrval;
|
||||
CValue cval;
|
||||
CString cstr;
|
||||
|
||||
saved_macro_ptr = macro_ptr;
|
||||
macro_ptr = macro_str;
|
||||
macro_str1 = NULL;
|
||||
if (macro_str) {
|
||||
/* first scan for '##' operator handling */
|
||||
macro_str1 = macro_twosharps(macro_str);
|
||||
macro_ptr = macro_str1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
next_nomacro();
|
||||
if (tok == 0)
|
||||
break;
|
||||
if ((s = sym_find1(&define_stack, tok)) != NULL) {
|
||||
/* if symbol is a macro, prepare substitution */
|
||||
/* if nested substitution, do nothing */
|
||||
if (sym_find2(*nested_list, tok))
|
||||
goto no_subst;
|
||||
return -1;
|
||||
|
||||
/* special macros */
|
||||
if (tok == TOK___LINE__) {
|
||||
|
@ -2839,7 +2825,7 @@ void macro_subst(TokenString *tok_str,
|
|||
t = ch;
|
||||
}
|
||||
if (t != '(') /* no macro subst */
|
||||
goto no_subst;
|
||||
return -1;
|
||||
|
||||
/* argument macro */
|
||||
next_nomacro();
|
||||
|
@ -2909,26 +2895,46 @@ void macro_subst(TokenString *tok_str,
|
|||
if (mstr_allocated)
|
||||
tok_str_free(mstr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* do macro substitution of macro_str and add result to
|
||||
(tok_str,tok_len). 'nested_list' is the list of all macros we got
|
||||
inside to avoid recursing. */
|
||||
static void macro_subst(TokenString *tok_str,
|
||||
Sym **nested_list, int *macro_str)
|
||||
{
|
||||
Sym *s;
|
||||
int *saved_macro_ptr;
|
||||
int *macro_str1;
|
||||
|
||||
saved_macro_ptr = macro_ptr;
|
||||
macro_ptr = macro_str;
|
||||
/* first scan for '##' operator handling */
|
||||
macro_str1 = macro_twosharps();
|
||||
macro_ptr = macro_str1;
|
||||
|
||||
while (1) {
|
||||
next_nomacro();
|
||||
if (tok == 0)
|
||||
break;
|
||||
s = sym_find1(&define_stack, tok);
|
||||
if (s != NULL) {
|
||||
if (macro_subst_tok(tok_str, nested_list, s) != 0)
|
||||
goto no_subst;
|
||||
} else {
|
||||
no_subst:
|
||||
/* no need to add if reading input stream */
|
||||
if (!macro_str)
|
||||
return;
|
||||
tok_str_add2(tok_str, tok, &tokc);
|
||||
}
|
||||
/* only replace one macro while parsing input stream */
|
||||
if (!macro_str)
|
||||
return;
|
||||
}
|
||||
macro_ptr = saved_macro_ptr;
|
||||
if (macro_str1)
|
||||
tok_str_free(macro_str1);
|
||||
}
|
||||
|
||||
/* return next token with macro substitution */
|
||||
void next(void)
|
||||
{
|
||||
Sym *nested_list;
|
||||
Sym *nested_list, *s;
|
||||
TokenString str;
|
||||
|
||||
/* special 'ungettok' case for label parsing */
|
||||
|
@ -2938,23 +2944,26 @@ void next(void)
|
|||
tok1 = 0;
|
||||
} else {
|
||||
redo:
|
||||
next_nomacro();
|
||||
if (!macro_ptr) {
|
||||
/* if not reading from macro substituted string, then try
|
||||
to substitute */
|
||||
/* XXX: optimize non macro case */
|
||||
to substitute macros */
|
||||
if (tok >= TOK_IDENT) {
|
||||
s = sym_find1(&define_stack, tok);
|
||||
if (s) {
|
||||
/* we have a macro: we try to substitute */
|
||||
tok_str_new(&str);
|
||||
nested_list = NULL;
|
||||
macro_subst(&str, &nested_list, NULL);
|
||||
if (str.str) {
|
||||
if (macro_subst_tok(&str, &nested_list, s) == 0) {
|
||||
/* substitution done, NOTE: maybe empty */
|
||||
tok_str_add(&str, 0);
|
||||
macro_ptr = str.str;
|
||||
macro_ptr_allocated = str.str;
|
||||
goto redo;
|
||||
}
|
||||
if (tok == 0)
|
||||
goto redo;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
next_nomacro();
|
||||
if (tok == 0) {
|
||||
/* end of macro string: free it */
|
||||
tok_str_free(macro_ptr_allocated);
|
||||
|
@ -6226,6 +6235,12 @@ static void decl_initializer(int t, Section *sec, unsigned long c,
|
|||
if (!size_only) {
|
||||
if (cstr_len > nb)
|
||||
warning("initializer-string for array is too long");
|
||||
/* in order to go faster for common case (char
|
||||
string in global variable, we handle it
|
||||
specifically */
|
||||
if (sec && tok == TOK_STR && size1 == 1) {
|
||||
memcpy(sec->data + c + array_length, cstr->data, nb);
|
||||
} else {
|
||||
for(i=0;i<nb;i++) {
|
||||
if (tok == TOK_STR)
|
||||
ch = ((unsigned char *)cstr->data)[i];
|
||||
|
@ -6235,6 +6250,7 @@ static void decl_initializer(int t, Section *sec, unsigned long c,
|
|||
ch, EXPR_VAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
array_length += nb;
|
||||
next();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue