History

tccpp: faster next()

- call TOK_GET() as a function only for tokens with values - get rid of 'next_nomacro_spc()' - be sligtly more efficient in next() This made about 4-5%+ speed in my tests.

grischka committed 6 years ago

Commit b5faa451 parent 78187253 files · +146 −133Browse files

Unified · Split

3 files
  1. tcc.h +61 −55
  2. tccgen.c +11 −22
  3. tccpp.c +74 −56
tcc.h+61−55
@@ -35,6 +35,7 @@ · 34 unmodified lines
3535 #include <time.h>
3636
3737 #ifndef _WIN32
38+# define WIN32_LEAN_AND_MEAN 1
3839 # include <unistd.h>
3940 # include <sys/time.h>
4041 # ifndef CONFIG_TCC_STATIC
@@ -1009,6 +1010,9 @@ struct filespec { · 968 unmodified lines
10091010
10101011 /* token values */
10111012
1013+/* conditional ops */
1014+#define TOK_LAND 0x90
1015+#define TOK_LOR 0x91
10121016 /* warning: the following compare tokens depend on i386 asm code */
10131017 #define TOK_ULT 0x92
10141018 #define TOK_UGE 0x93
@@ -1023,62 +1027,65 @@ struct filespec { · 8 unmodified lines
10231027 #define TOK_LE 0x9e
10241028 #define TOK_GT 0x9f
10251029
1026−#define TOK_LAND 0xa0
1027−#define TOK_LOR 0xa1
1028−#define TOK_DEC 0xa2
1029−#define TOK_MID 0xa3 /* inc/dec, to void constant */
1030−#define TOK_INC 0xa4
1031−#define TOK_UDIV 0xb0 /* unsigned division */
1032−#define TOK_UMOD 0xb1 /* unsigned modulo */
1033−#define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
1030+#define TOK_ISCOND(t) (t >= TOK_LAND && t <= TOK_GT)
1031+
1032+#define TOK_DEC 0x80 /* -- */
1033+#define TOK_MID 0x81 /* inc/dec, to void constant */
1034+#define TOK_INC 0x82 /* ++ */
1035+#define TOK_UDIV 0x83 /* unsigned division */
1036+#define TOK_UMOD 0x84 /* unsigned modulo */
1037+#define TOK_PDIV 0x85 /* fast division with undefined rounding for pointers */
1038+#define TOK_UMULL 0x86 /* unsigned 32x32 -> 64 mul */
1039+#define TOK_ADDC1 0x87 /* add with carry generation */
1040+#define TOK_ADDC2 0x88 /* add with carry use */
1041+#define TOK_SUBC1 0x89 /* add with carry generation */
1042+#define TOK_SUBC2 0x8a /* add with carry use */
1043+#define TOK_SHL '<' /* shift left */
1044+#define TOK_SAR '>' /* signed shift right */
1045+#define TOK_SHR 0x8b /* unsigned shift right */
1046+
1047+#define TOK_ARROW 0xa0 /* -> */
1048+#define TOK_DOTS 0xa1 /* three dots */
1049+#define TOK_TWODOTS 0xa2 /* C++ token ? */
1050+#define TOK_TWOSHARPS 0xa3 /* ## preprocessing token */
1051+#define TOK_PLCHLDR 0xa4 /* placeholder token as defined in C99 */
1052+#define TOK_NOSUBST 0xa5 /* means following token has already been pp'd */
1053+#define TOK_PPJOIN 0xa6 /* A '##' in the right position to mean pasting */
1054+
1055+/* assignment operators */
1056+#define TOK_A_ADD 0xb0
1057+#define TOK_A_SUB 0xb1
1058+#define TOK_A_MUL 0xb2
1059+#define TOK_A_DIV 0xb3
1060+#define TOK_A_MOD 0xb4
1061+#define TOK_A_AND 0xb5
1062+#define TOK_A_OR 0xb6
1063+#define TOK_A_XOR 0xb7
1064+#define TOK_A_SHL 0xb8
1065+#define TOK_A_SAR 0xb9
1066+
1067+#define TOK_ASSIGN(t) (t >= TOK_A_ADD && t <= TOK_A_SAR)
1068+#define TOK_ASSIGN_OP(t) ("+-*/%&|^<>"[t - TOK_A_ADD])
10341069
10351070 /* tokens that carry values (in additional token string space / tokc) --> */
1036−#define TOK_CCHAR 0xb3 /* char constant in tokc */
1037−#define TOK_LCHAR 0xb4
1038−#define TOK_CINT 0xb5 /* number in tokc */
1039−#define TOK_CUINT 0xb6 /* unsigned int constant */
1040−#define TOK_CLLONG 0xb7 /* long long constant */
1041−#define TOK_CULLONG 0xb8 /* unsigned long long constant */
1042−#define TOK_STR 0xb9 /* pointer to string in tokc */
1043−#define TOK_LSTR 0xba
1044−#define TOK_CFLOAT 0xbb /* float constant */
1045−#define TOK_CDOUBLE 0xbc /* double constant */
1046−#define TOK_CLDOUBLE 0xbd /* long double constant */
1047−#define TOK_PPNUM 0xbe /* preprocessor number */
1048−#define TOK_PPSTR 0xbf /* preprocessor string */
1049−#define TOK_LINENUM 0xc0 /* line number info */
1050−#define TOK_TWODOTS 0xa8 /* C++ token ? */
1051−/* <-- */
1052−
1053−#define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
1054−#define TOK_ADDC1 0xc3 /* add with carry generation */
1055−#define TOK_ADDC2 0xc4 /* add with carry use */
1056−#define TOK_SUBC1 0xc5 /* add with carry generation */
1057−#define TOK_SUBC2 0xc6 /* add with carry use */
1058−#define TOK_ARROW 0xc7
1059−#define TOK_DOTS 0xc8 /* three dots */
1060−#define TOK_SHR 0xc9 /* unsigned shift right */
1061−#define TOK_TWOSHARPS 0xca /* ## preprocessing token */
1062−#define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */
1063−#define TOK_NOSUBST 0xcc /* means following token has already been pp'd */
1064−#define TOK_PPJOIN 0xcd /* A '##' in the right position to mean pasting */
1065−#define TOK_CLONG 0xce /* long constant */
1066−#define TOK_CULONG 0xcf /* unsigned long constant */
1067−
1068−#define TOK_SHL 0x01 /* shift left */
1069−#define TOK_SAR 0x02 /* signed shift right */
1070−
1071−/* assignment operators : normal operator or 0x80 */
1072−#define TOK_A_MOD 0xa5
1073−#define TOK_A_AND 0xa6
1074−#define TOK_A_MUL 0xaa
1075−#define TOK_A_ADD 0xab
1076−#define TOK_A_SUB 0xad
1077−#define TOK_A_DIV 0xaf
1078−#define TOK_A_XOR 0xde
1079−#define TOK_A_OR 0xfc
1080−#define TOK_A_SHL 0x81
1081−#define TOK_A_SAR 0x82
1071+#define TOK_CCHAR 0xc0 /* char constant in tokc */
1072+#define TOK_LCHAR 0xc1
1073+#define TOK_CINT 0xc2 /* number in tokc */
1074+#define TOK_CUINT 0xc3 /* unsigned int constant */
1075+#define TOK_CLLONG 0xc4 /* long long constant */
1076+#define TOK_CULLONG 0xc5 /* unsigned long long constant */
1077+#define TOK_CLONG 0xc6 /* long constant */
1078+#define TOK_CULONG 0xc7 /* unsigned long constant */
1079+#define TOK_STR 0xc8 /* pointer to string in tokc */
1080+#define TOK_LSTR 0xc9
1081+#define TOK_CFLOAT 0xca /* float constant */
1082+#define TOK_CDOUBLE 0xcb /* double constant */
1083+#define TOK_CLDOUBLE 0xcc /* long double constant */
1084+#define TOK_PPNUM 0xcd /* preprocessor number */
1085+#define TOK_PPSTR 0xce /* preprocessor string */
1086+#define TOK_LINENUM 0xcf /* line number info */
1087+
1088+#define TOK_HAS_VALUE(t) (t >= TOK_CCHAR && t <= TOK_LINENUM)
10821089
10831090 #define TOK_EOF (-1) /* end of file */
10841091 #define TOK_LINEFEED 10 /* line feed */
@@ -1346,7 +1353,6 @@ ST_FUNC Sym *label_push(Sym **ptop, int v, int flags); · 261 unmodified lines
13461353 ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep);
13471354 ST_FUNC void parse_define(void);
13481355 ST_FUNC void preprocess(int is_bof);
1349−ST_FUNC void next_nomacro(void);
13501356 ST_FUNC void next(void);
13511357 ST_INLN void unget_tok(int last_tok);
13521358 ST_FUNC void preprocess_start(TCCState *s1, int is_asm);
tccgen.c+11−22
@@ -3064,7 +3064,7 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op) · 3063 unmodified lines
30643064 else if (bt1 != bt2) {
30653065 /* accept comparison or cond-expr between pointer and integer
30663066 with a warning */
3067− if ((op == '?' || (op >= TOK_ULT && op <= TOK_LOR))
3067+ if ((op == '?' || TOK_ISCOND(op))
30683068 && (is_integer_btype(bt1) || is_integer_btype(bt2)))
30693069 tcc_warning("pointer/integer mismatch in %s",
30703070 op == '?' ? "conditional expression" : "comparison");
@@ -3079,7 +3079,7 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op) · 8 unmodified lines
30793079 int newquals, copied = 0;
30803080 if (pbt1 != VT_VOID && pbt2 != VT_VOID
30813081 && !compare_types(pt1, pt2, 1/*unqualif*/)) {
3082− if (op != '?' && (op < TOK_ULT || op > TOK_LOR))
3082+ if (op != '?' && !TOK_ISCOND(op))
30833083 ret = 0;
30843084 else
30853085 type_incompatibility_warning(type1, type2,
@@ -3120,7 +3120,7 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op) · 34 unmodified lines
31203120 }
31213121 }
31223122 }
3123− if (op >= TOK_ULT && op <= TOK_LOR)
3123+ if (TOK_ISCOND(op))
31243124 type.t = VT_SIZE_T;
31253125 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
31263126 if (op != '?' || !compare_types(type1, type2, 1))
@@ -3188,7 +3188,7 @@ redo: · 61 unmodified lines
31883188 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
31893189 /* at least one operand is a pointer */
31903190 /* relational op: must be both pointers */
3191− if (op >= TOK_ULT && op <= TOK_LOR)
3191+ if (TOK_ISCOND(op))
31923192 goto std_op;
31933193 /* if both pointers, then it must be the '-' op */
31943194 if (bt1 == VT_PTR && bt2 == VT_PTR) {
@@ -3256,7 +3256,7 @@ redo: · 61 unmodified lines
32563256 /* floats can only be used for a few operations */
32573257 if (is_float(combtype.t)
32583258 && op != '+' && op != '-' && op != '*' && op != '/'
3259− && (op < TOK_ULT || op > TOK_LOR))
3259+ && !TOK_ISCOND(op))
32603260 tcc_error("invalid operands for binary operation");
32613261 else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
32623262 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
@@ -3297,7 +3297,7 @@ redo: · 34 unmodified lines
32973297 gen_opif(op);
32983298 else
32993299 gen_opic(op);
3300− if (op >= TOK_ULT && op <= TOK_LOR) {
3300+ if (TOK_ISCOND(op)) {
33013301 /* relational op: the result is an int */
33023302 vtop->type.t = VT_INT;
33033303 } else {
@@ -4065,13 +4065,8 @@ redo: · 761 unmodified lines
40654065 tcc_warning("implicit declaration of function '%s'",
40664066 get_tok_str(tok, &tokc));
40674067 s = external_global_sym(tok, &func_old_type);
4068− }
4069− else if ((s->type.t & VT_BTYPE) == VT_FUNC) {
4070− ad->cleanup_func = s;
4071− }
4072− else {
4068+ } else if ((s->type.t & VT_BTYPE) != VT_FUNC)
40734069 tcc_error("'%s' is not declared as function", get_tok_str(tok, &tokc));
4074− }
40754070 ad->cleanup_func = s;
40764071 next();
40774072 skip(')');
@@ -5937,11 +5932,8 @@ special_math_val: · 1859 unmodified lines
59375932 test_lvalue();
59385933 gaddrof();
59395934 /* expect pointer on structure */
5940− if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) {
5941− char got[256];
5942− type_to_str(got, sizeof got, &vtop->type, NULL);
5943− tcc_error("expected struct or union but not '%s'", got);
5944− }
5935+ if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
5936+ expect("struct or union");
59455937 if (tok == TOK_CDOUBLE)
59465938 expect("field name");
59475939 next();
@@ -6487,10 +6479,7 @@ static void expr_eq(void) · 539 unmodified lines
64876479 int t;
64886480
64896481 expr_cond();
6490− if ((t = tok) == '='
6491− || (t >= TOK_A_MOD && t <= TOK_A_DIV)
6492− || t == TOK_A_XOR || t == TOK_A_OR
6493− || t == TOK_A_SHL || t == TOK_A_SAR) {
6482+ if ((t = tok) == '=' || TOK_ASSIGN(t)) {
64946483 test_lvalue();
64956484 next();
64966485 if (t == '=') {
@@ -6498,7 +6487,7 @@ static void expr_eq(void) · 1 unmodified line
64986487 } else {
64996488 vdup();
65006489 expr_eq();
6501− gen_op(t & 0x7f);
6490+ gen_op(TOK_ASSIGN_OP(t));
65026491 }
65036492 vstore();
65046493 }
tccpp.c+74−56
@@ -92,7 +92,7 @@ static const unsigned char tok_two_chars[] = · 91 unmodified lines
9292 0
9393 };
9494
95−static void next_nomacro_spc(void);
95+static void next_nomacro(void);
9696
9797 ST_FUNC void skip(int c)
9898 {
@@ -1230,7 +1230,7 @@ ST_FUNC void tok_str_add_tok(TokenString *s) · 1131 unmodified lines
12301230 }
12311231
12321232 /* get a token from an integer array and increment pointer. */
1233−static inline void TOK_GET(int *t, const int **pp, CValue *cv)
1233+static inline void tok_get(int *t, const int **pp, CValue *cv)
12341234 {
12351235 const int *p = *pp;
12361236 int n, *tab;
@@ -1293,6 +1293,18 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) · 56 unmodified lines
12931293 *pp = p;
12941294 }
12951295
1296+#if 0
1297+# define TOK_GET(t,p,c) tok_get(t,p,c)
1298+#else
1299+# define TOK_GET(t,p,c) do { \
1300+ int _t = **(p); \
1301+ if (TOK_HAS_VALUE(_t)) \
1302+ tok_get(t, p, c); \
1303+ else \
1304+ *(t) = _t, ++*(p); \
1305+ } while (0)
1306+#endif
1307+
12961308 static int macro_is_equal(const int *a, const int *b)
12971309 {
12981310 CValue cv;
@@ -1493,7 +1505,8 @@ ST_FUNC void parse_define(void) · 194 unmodified lines
14931505 character. */
14941506 parse_flags = ((parse_flags & ~PARSE_FLAG_ASM_FILE) | PARSE_FLAG_SPACES);
14951507 /* '(' must be just after macro definition for MACRO_FUNC */
1496− next_nomacro_spc();
1508+ next_nomacro();
1509+ parse_flags &= ~PARSE_FLAG_SPACES;
14971510 if (tok == '(') {
14981511 int dotid = set_idnum('.', 0);
14991512 next_nomacro();
@@ -1521,7 +1534,8 @@ ST_FUNC void parse_define(void) · 21 unmodified lines
15211534 goto bad_list;
15221535 next_nomacro();
15231536 }
1524− next_nomacro_spc();
1537+ parse_flags |= PARSE_FLAG_SPACES;
1538+ next_nomacro();
15251539 t = MACRO_FUNC;
15261540 set_idnum('.', dotid);
15271541 }
@@ -1550,7 +1564,7 @@ ST_FUNC void parse_define(void) · 22 unmodified lines
15501564 }
15511565 tok_str_add2(&tokstr_buf, tok, &tokc);
15521566 skip:
1553− next_nomacro_spc();
1567+ next_nomacro();
15541568 }
15551569
15561570 parse_flags = saved_parse_flags;
@@ -2586,6 +2600,7 @@ static inline void next_nomacro1(void) · 1029 unmodified lines
25862600 case '\t':
25872601 tok = c;
25882602 p++;
2603+ maybe_space:
25892604 if (parse_flags & PARSE_FLAG_SPACES)
25902605 goto keep_tok_flags;
25912606 while (isidnum_table[*p - CH_EOF] & IS_SPC)
@@ -2932,11 +2947,11 @@ maybe_newline: · 340 unmodified lines
29322947 p = parse_comment(p);
29332948 /* comments replaced by a blank */
29342949 tok = ' ';
2935− goto keep_tok_flags;
2950+ goto maybe_space;
29362951 } else if (c == '/') {
29372952 p = parse_line_comment(p);
29382953 tok = ' ';
2939− goto keep_tok_flags;
2954+ goto maybe_space;
29402955 } else if (c == '=') {
29412956 p++;
29422957 tok = TOK_A_DIV;
@@ -2978,34 +2993,6 @@ keep_tok_flags: · 35 unmodified lines
29782993 #endif
29792994 }
29802995
2981−/* return next token without macro substitution. Can read input from
2982− macro_ptr buffer */
2983−static void next_nomacro_spc(void)
2984−{
2985− if (macro_ptr) {
2986− redo:
2987− tok = *macro_ptr;
2988− if (tok) {
2989− TOK_GET(&tok, &macro_ptr, &tokc);
2990− if (tok == TOK_LINENUM) {
2991− file->line_num = tokc.i;
2992− goto redo;
2993− }
2994− }
2995− } else {
2996− next_nomacro1();
2997− }
2998− //printf("token = %s\n", get_tok_str(tok, &tokc));
2999−}
3000−
3001−ST_FUNC void next_nomacro(void)
3002−{
3003− do {
3004− next_nomacro_spc();
3005− } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC));
3006−}
3007−
3008−
30092996 static void macro_subst(
30102997 TokenString *tok_str,
30112998 Sym **nested_list,
@@ -3281,7 +3268,7 @@ static int next_argstream(Sym **nested_list, TokenString *ws_str) · 269 unmodified lines
32813268
32823269 if (ws_str)
32833270 return t;
3284− next_nomacro_spc();
3271+ next_nomacro();
32853272 return tok;
32863273 }
32873274 }
@@ -3372,7 +3359,7 @@ static int macro_subst_tok( · 84 unmodified lines
33723359 }
33733360 do {
33743361 next_nomacro(); /* eat '(' */
3375− } while (tok == TOK_PLCHLDR);
3362+ } while (tok == TOK_PLCHLDR || is_space(tok));
33763363
33773364 /* argument macro */
33783365 args = NULL;
@@ -3533,29 +3520,59 @@ no_subst: · 154 unmodified lines
35333520 }
35343521 }
35353522
3523+/* return next token without macro substitution. Can read input from
3524+ macro_ptr buffer */
3525+static void next_nomacro(void)
3526+{
3527+ int t;
3528+ if (macro_ptr) {
3529+ redo:
3530+ t = *macro_ptr;
3531+ if (TOK_HAS_VALUE(t)) {
3532+ tok_get(&tok, &macro_ptr, &tokc);
3533+ if (t == TOK_LINENUM) {
3534+ file->line_num = tokc.i;
3535+ goto redo;
3536+ }
3537+ } else {
3538+ macro_ptr++;
3539+ if (t < TOK_IDENT) {
3540+ if (!(parse_flags & PARSE_FLAG_SPACES)
3541+ && (isidnum_table[t - CH_EOF] & IS_SPC))
3542+ goto redo;
3543+ }
3544+ tok = t;
3545+ }
3546+ } else {
3547+ next_nomacro1();
3548+ }
3549+}
3550+
35363551 /* return next token with macro substitution */
35373552 ST_FUNC void next(void)
35383553 {
3554+ int t;
35393555 redo:
3540− if (parse_flags & PARSE_FLAG_SPACES)
3541− next_nomacro_spc();
3542− else
3543− next_nomacro();
3544−
3556+ next_nomacro();
3557+ t = tok;
35453558 if (macro_ptr) {
3546− if (tok == TOK_NOSUBST || tok == TOK_PLCHLDR) {
3547− /* discard preprocessor markers */
3548− goto redo;
3549− } else if (tok == 0) {
3550− /* end of macro or unget token string */
3551− end_macro();
3552− goto redo;
3553− } else if (tok == '\\' && !(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
3554− tcc_error("stray '\\' in program");
3555− } else if (tok >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) {
3556− Sym *s;
3559+ if (!TOK_HAS_VALUE(t)) {
3560+ if (t == TOK_NOSUBST || t == TOK_PLCHLDR) {
3561+ /* discard preprocessor markers */
3562+ goto redo;
3563+ } else if (t == 0) {
3564+ /* end of macro or unget token string */
3565+ end_macro();
3566+ goto redo;
3567+ } else if (t == '\\') {
3568+ if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
3569+ tcc_error("stray '\\' in program");
3570+ }
3571+ return;
3572+ }
3573+ } else if (t >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) {
35573574 /* if reading from file, try to substitute macros */
3558− s = define_find(tok);
3575+ Sym *s = define_find(t);
35593576 if (s) {
35603577 Sym *nested_list = NULL;
35613578 tokstr_buf.len = 0;
@@ -3564,12 +3581,13 @@ ST_FUNC void next(void) · 2 unmodified lines
35643581 begin_macro(&tokstr_buf, 0);
35653582 goto redo;
35663583 }
3584+ return;
35673585 }
35683586 /* convert preprocessor tokens into C tokens */
3569− if (tok == TOK_PPNUM) {
3587+ if (t == TOK_PPNUM) {
35703588 if (parse_flags & PARSE_FLAG_TOK_NUM)
35713589 parse_number((char *)tokc.str.data);
3572− } else if (tok == TOK_PPSTR) {
3590+ } else if (t == TOK_PPSTR) {
35733591 if (parse_flags & PARSE_FLAG_TOK_STR)
35743592 parse_string((char *)tokc.str.data, tokc.str.size - 1);
35753593 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t