History

Rework expr_infix

- revert const-folding in gvtst() and put it back into expr_landor(). Although it did make sense, one reason not to do it is __builtin_constant_p() which may return true when it shouldn't because of nocode_wanted, see test. - tccgen_init() can do init_prec(), also for tcc -E. - for nostalgic reasons, keep the original expression parser functions in the source. - Makefile: remove stale stuff

grischka committed 6 years ago

Commit 7e901291 parent aeac24d5 files · +191 −82Browse files

Unified · Split

5 files
  1. Makefile +3 −10
  2. tcc.h +0 −1
  3. tccgen.c +185 −69
  4. tccpp.c +0 −2
  5. tests/tcctest.c +3 −0
Makefile+3−10
@@ -238,20 +238,13 @@ XTCC ?= ./tcc$(EXESUF) · 237 unmodified lines
238238
239239 # TinyCC runtime libraries
240240 libtcc1.a : tcc$(EXESUF) FORCE
241− @$(MAKE) -C lib DEFINES='$(DEF-$T)'
241+ @$(MAKE) -C lib
242242
243243 # Cross libtcc1.a
244244 %-libtcc1.a : %-tcc$(EXESUF) FORCE
245− @$(MAKE) -C lib DEFINES='$(DEF-$*)' CROSS_TARGET=$*
245+ @$(MAKE) -C lib CROSS_TARGET=$*
246246
247−# TinyCC runtime libraries
248−libtccb1.a : libtcc1.a
249−
250−# Cross libtcc1.a
251−%-libtccb1.a : %-tcc$(EXESUF) FORCE
252− @$(MAKE) -C lib DEFINES='$(DEF-$*)' CROSS_TARGET=$*
253−
254−.PRECIOUS: %-libtcc1.a %-libtccb1.a
247+.PRECIOUS: %-libtcc1.a
255248 FORCE:
256249
257250 # --------------------------------------------------------------------------
tcc.h+0−1
@@ -1434,7 +1434,6 @@ ST_FUNC void parse_mult_str (CString *astr, const char *msg); · 1433 unmodified lines
14341434 ST_FUNC void parse_asm_str(CString *astr);
14351435 ST_FUNC void indir(void);
14361436 ST_FUNC void unary(void);
1437−ST_FUNC void init_prec(void);
14381437 ST_FUNC void gexpr(void);
14391438 ST_FUNC int expr_const(void);
14401439 #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
tccgen.c+185−69
@@ -67,7 +67,7 @@ static int gind(void) { CODE_ON(); return ind; } · 66 unmodified lines
6767
6868 /* Set 'nocode_wanted' after unconditional jumps */
6969 static void gjmp_addr_acs(int t) { gjmp_addr(t); CODE_OFF(); }
70−static int gjmp_acs(int t) { if (!nocode_wanted) {t = gjmp(t); CODE_OFF(); } return t; }
70+static int gjmp_acs(int t) { t = gjmp(t); CODE_OFF(); return t; }
7171
7272 /* These are #undef'd at the end of this file */
7373 #define gjmp_addr gjmp_addr_acs
@@ -122,6 +122,11 @@ static struct scope { · 48 unmodified lines
122122 Sym *lstk, *llstk;
123123 } *cur_scope, *loop_scope, *root_scope;
124124
125+/********************************************************/
126+#if 1
127+#define precedence_parser
128+static void init_prec(void);
129+#endif
125130 /********************************************************/
126131 #ifndef CONFIG_TCC_ASM
127132 ST_FUNC void asm_instr(void)
@@ -135,7 +140,6 @@ ST_FUNC void asm_global_instr(void) · 7 unmodified lines
135140 #endif
136141
137142 /* ------------------------------------------------------------------------- */
138−
139143 static void gen_cast(CType *type);
140144 static void gen_cast_s(int t);
141145 static inline CType *pointed_type(CType *type);
@@ -455,6 +459,9 @@ ST_FUNC void tccgen_init(TCCState *s1) · 313 unmodified lines
455459 func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
456460 func_old_type.ref->f.func_call = FUNC_CDECL;
457461 func_old_type.ref->f.func_type = FUNC_OLD;
462+#ifdef precedence_parser
463+ init_prec();
464+#endif
458465 }
459466
460467 ST_FUNC int tccgen_compile(TCCState *s1)
@@ -877,7 +884,7 @@ static void vcheck_cmp(void) · 416 unmodified lines
877884 again, so that the VT_CMP/VT_JMP value will be in vtop
878885 when code is unsuppressed again. */
879886
880− if (vtop->r == VT_CMP && !nocode_wanted && vtop->cmp_op > 1)
887+ if (vtop->r == VT_CMP && !nocode_wanted)
881888 gv(RC_INT);
882889 }
883890
@@ -1040,14 +1047,11 @@ ST_FUNC void vset_VT_CMP(int op) · 156 unmodified lines
10401047 static void vset_VT_JMP(void)
10411048 {
10421049 int op = vtop->cmp_op;
1050+
10431051 if (vtop->jtrue || vtop->jfalse) {
10441052 /* we need to jump to 'mov $0,%R' or 'mov $1,%R' */
10451053 int inv = op & (op < 2); /* small optimization */
1046− int t = gvtst(inv, 0);
1047− if (t) /* in case gvtst only needed to do a gsym */
1048− vseti(VT_JMP+inv, t);
1049− else
1050− vpushi(inv);
1054+ vseti(VT_JMP+inv, gvtst(inv, 0));
10511055 } else {
10521056 /* otherwise convert flags (rsp. 0/1) to register */
10531057 vtop->c.i = op;
@@ -1060,18 +1064,14 @@ static void vset_VT_JMP(void) · 6 unmodified lines
10601064 static void gvtst_set(int inv, int t)
10611065 {
10621066 int *p;
1067+
10631068 if (vtop->r != VT_CMP) {
10641069 vpushi(0);
10651070 gen_op(TOK_NE);
1066− if (vtop->r == VT_CMP) /* must be VT_CONST otherwise */
1067− ;
1068− else if (vtop->r == VT_CONST) {
1069− if (!t)
1070− return;
1071+ if (vtop->r != VT_CMP) /* must be VT_CONST then */
10711072 vset_VT_CMP(vtop->c.i != 0);
1072− } else
1073− tcc_error("ICE");
10741073 }
1074+
10751075 p = inv ? &vtop->jfalse : &vtop->jtrue;
10761076 *p = gjmp_append(*p, t);
10771077 }
@@ -1082,20 +1082,16 @@ static void gvtst_set(int inv, int t) · 4 unmodified lines
10821082 static int gvtst(int inv, int t)
10831083 {
10841084 int op, x, u;
1085+
10851086 gvtst_set(inv, t);
1086− if (vtop->r != VT_CMP) {
1087− t = u = x = 0;
1088− op = vtop->c.i;
1089− } else {
1090− t = vtop->jtrue, u = vtop->jfalse;
1091− if (inv)
1092− x = u, u = t, t = x;
1093− op = vtop->cmp_op;
1094− }
1087+ t = vtop->jtrue, u = vtop->jfalse;
1088+ if (inv)
1089+ x = u, u = t, t = x;
1090+ op = vtop->cmp_op;
10951091
10961092 /* jump to the wanted target */
10971093 if (op > 1)
1098− t = gjmp_cond(op ^ inv, t), op = inv;//, op = 1;
1094+ t = gjmp_cond(op ^ inv, t);
10991095 else if (op != inv)
11001096 t = gjmp(t);
11011097 /* resolve complementary jumps to here */
@@ -5690,22 +5686,120 @@ special_math_val: · 4588 unmodified lines
56905686 }
56915687 }
56925688
5693−/* Assuming vtop is a value used in a conditional context
5694− (i.e. compared with zero) return 0 if it's false, 1 if
5695− true and -1 if it can't be statically determined. */
5696−static int condition_3way(void)
5689+#ifndef precedence_parser /* original top-down parser */
5690+
5691+static void expr_prod(void)
56975692 {
5698− int c = -1;
5699− if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
5700− (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
5701− vdup();
5702− gen_cast_s(VT_BOOL);
5703− c = vtop->c.i;
5704− vpop();
5693+ int t;
5694+
5695+ unary();
5696+ while ((t = tok) == '*' || t == '/' || t == '%') {
5697+ next();
5698+ unary();
5699+ gen_op(t);
5700+ }
5701+}
5702+
5703+static void expr_sum(void)
5704+{
5705+ int t;
5706+
5707+ expr_prod();
5708+ while ((t = tok) == '+' || t == '-') {
5709+ next();
5710+ expr_prod();
5711+ gen_op(t);
5712+ }
5713+}
5714+
5715+static void expr_shift(void)
5716+{
5717+ int t;
5718+
5719+ expr_sum();
5720+ while ((t = tok) == TOK_SHL || t == TOK_SAR) {
5721+ next();
5722+ expr_sum();
5723+ gen_op(t);
5724+ }
5725+}
5726+
5727+static void expr_cmp(void)
5728+{
5729+ int t;
5730+
5731+ expr_shift();
5732+ while (((t = tok) >= TOK_ULE && t <= TOK_GT) ||
5733+ t == TOK_ULT || t == TOK_UGE) {
5734+ next();
5735+ expr_shift();
5736+ gen_op(t);
5737+ }
5738+}
5739+
5740+static void expr_cmpeq(void)
5741+{
5742+ int t;
5743+
5744+ expr_cmp();
5745+ while ((t = tok) == TOK_EQ || t == TOK_NE) {
5746+ next();
5747+ expr_cmp();
5748+ gen_op(t);
5749+ }
5750+}
5751+
5752+static void expr_and(void)
5753+{
5754+ expr_cmpeq();
5755+ while (tok == '&') {
5756+ next();
5757+ expr_cmpeq();
5758+ gen_op('&');
57055759 }
5706− return c;
57075760 }
57085761
5762+static void expr_xor(void)
5763+{
5764+ expr_and();
5765+ while (tok == '^') {
5766+ next();
5767+ expr_and();
5768+ gen_op('^');
5769+ }
5770+}
5771+
5772+static void expr_or(void)
5773+{
5774+ expr_xor();
5775+ while (tok == '|') {
5776+ next();
5777+ expr_xor();
5778+ gen_op('|');
5779+ }
5780+}
5781+
5782+static void expr_landor(int op);
5783+
5784+static void expr_land(void)
5785+{
5786+ expr_or();
5787+ if (tok == TOK_LAND)
5788+ expr_landor(tok);
5789+}
5790+
5791+static void expr_lor(void)
5792+{
5793+ expr_land();
5794+ if (tok == TOK_LOR)
5795+ expr_landor(tok);
5796+}
5797+
5798+# define expr_landor_next(op) op == TOK_LAND ? expr_or() : expr_land()
5799+#else /* defined precedence_parser */
5800+# define expr_landor_next(op) unary(), expr_infix(precedence(op) + 1)
5801+# define expr_lor() unary(), expr_infix(1)
5802+
57095803 static int precedence(int tok)
57105804 {
57115805 switch (tok) {
@@ -5725,44 +5819,23 @@ static int precedence(int tok) · 13 unmodified lines
57255819 return 0;
57265820 }
57275821 }
5728−
57295822 static unsigned char prec[256];
5730−ST_FUNC void init_prec(void)
5823+static void init_prec(void)
57315824 {
57325825 int i;
57335826 for (i = 0; i < 256; i++)
57345827 prec[i] = precedence(i);
57355828 }
5736−
57375829 #define precedence(i) ((unsigned)i < 256 ? prec[i] : 0)
57385830
5739−static void expr_infix(int p);
5740−static void expr_landor(int p, int e_op, int i)
5741−{
5742− int t = 0, f = 0;
5743− save_regs(1);
5744− do {
5745− if (!f && condition_3way() == !i)
5746− nocode_wanted++, f = 1;
5747− t = gvtst(i, t);
5748− next();
5749− unary();
5750− expr_infix(p);
5751− } while (tok == e_op);
5752− if (f) {
5753− vpop();
5754− vpushi(i ^ f);
5755− }
5756− gvtst_set(i, t);
5757− nocode_wanted -= f;
5758−}
5831+static void expr_landor(int op);
57595832
57605833 static void expr_infix(int p)
57615834 {
57625835 int t = tok, p2;
57635836 while ((p2 = precedence(t)) >= p) {
57645837 if (t == TOK_LOR || t == TOK_LAND) {
5765− expr_landor(p2 + 1, t, t == TOK_LAND);
5838+ expr_landor(t);
57665839 } else {
57675840 next();
57685841 unary();
@@ -5773,6 +5846,51 @@ static void expr_infix(int p) · 4 unmodified lines
57735846 t = tok;
57745847 }
57755848 }
5849+#endif
5850+
5851+/* Assuming vtop is a value used in a conditional context
5852+ (i.e. compared with zero) return 0 if it's false, 1 if
5853+ true and -1 if it can't be statically determined. */
5854+static int condition_3way(void)
5855+{
5856+ int c = -1;
5857+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
5858+ (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
5859+ vdup();
5860+ gen_cast_s(VT_BOOL);
5861+ c = vtop->c.i;
5862+ vpop();
5863+ }
5864+ return c;
5865+}
5866+
5867+static void expr_landor(int op)
5868+{
5869+ int t = 0, cc = 1, f = 0, i = op == TOK_LAND, c;
5870+ for(;;) {
5871+ c = f ? i : condition_3way();
5872+ if (c < 0)
5873+ save_regs(1), cc = 0;
5874+ else if (c != i)
5875+ nocode_wanted++, f = 1;
5876+ if (tok != op)
5877+ break;
5878+ if (c < 0)
5879+ t = gvtst(i, t);
5880+ else
5881+ vpop();
5882+ next();
5883+ expr_landor_next(op);
5884+ }
5885+ if (cc || f) {
5886+ vpop();
5887+ vpushi(i ^ f);
5888+ gsym(t);
5889+ nocode_wanted -= f;
5890+ } else {
5891+ gvtst_set(i, t);
5892+ }
5893+}
57765894
57775895 static int is_cond_bool(SValue *sv)
57785896 {
@@ -5791,11 +5909,11 @@ static void expr_cond(void) · 12 unmodified lines
57915909 CType type, type1, type2;
57925910 int ncw_prev;
57935911
5794− unary();
5795− expr_infix(1);
5912+ expr_lor();
57965913 if (tok == '?') {
57975914 next();
57985915 c = condition_3way();
5916+ ncw_prev = nocode_wanted;
57995917 g = (tok == ':' && gnu_ext);
58005918 tt = 0;
58015919 if (!g) {
@@ -5813,7 +5931,6 @@ static void expr_cond(void) · 11 unmodified lines
58135931 tt = gvtst(0, 0);
58145932 }
58155933
5816− ncw_prev = nocode_wanted;
58175934 if (1) {
58185935 if (c == 0)
58195936 nocode_wanted++;
@@ -6013,12 +6130,11 @@ static void expr_eq(void) · 193 unmodified lines
60136130 int t;
60146131
60156132 expr_cond();
6016− if (tok == '=' ||
6017− (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
6018− tok == TOK_A_XOR || tok == TOK_A_OR ||
6019− tok == TOK_A_SHL || tok == TOK_A_SAR) {
6133+ if ((t = tok) == '='
6134+ || (t >= TOK_A_MOD && t <= TOK_A_DIV)
6135+ || t == TOK_A_XOR || t == TOK_A_OR
6136+ || t == TOK_A_SHL || t == TOK_A_SAR) {
60206137 test_lvalue();
6021− t = tok;
60226138 next();
60236139 if (t == '=') {
60246140 expr_eq();
tccpp.c+0−2
@@ -3679,8 +3679,6 @@ ST_FUNC void tccpp_new(TCCState *s) · 3678 unmodified lines
36793679 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
36803680 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
36813681 define_push(TOK___COUNTER__, MACRO_OBJ, NULL, NULL);
3682−
3683− init_prec();
36843682 }
36853683
36863684 ST_FUNC void tccpp_delete(TCCState *s)
tests/tcctest.c+3−0
@@ -3736,6 +3736,9 @@ void builtin_test(void) · 3735 unmodified lines
37363736 printf("res = %d\n", __builtin_constant_p(&constant_p_var));
37373737 printf("res = %d\n", __builtin_constant_p(constant_p_var));
37383738 printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var));
3739+ printf("res = %d\n", __builtin_constant_p(i && 0));
3740+ printf("res = %d\n", __builtin_constant_p(i && 1));
3741+ printf("res = %d\n", __builtin_constant_p(i && 0 ? i : 34));
37393742 s = 1;
37403743 ll = 2;
37413744 i = __builtin_choose_expr (1 != 0, ll, s);

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