History

gcase() clean up

remove tail recursion, simplify

Pavlas, Zdenek committed 10 years ago

Commit 7bd30a41 parent 7dddd651 file · +32 −33Browse files

Unified · Split

tccgen.c+32−33
@@ -4906,35 +4906,9 @@ static int gcase(struct case_t **base, int len, int case_reg, int *bsym) · 4905 unmodified lines
49064906 {
49074907 struct case_t *p;
49084908 int e;
4909− if (len <= 4) {
4910− while (len--) {
4911− p = *base++;
4912− vseti(case_reg, 0);
4913− vdup();
4914− vpushi(p->v2);
4915− if (p->v1 == p->v2) {
4916− gen_op(TOK_EQ);
4917− gtst_addr(0, p->sym);
4918− case_reg = gv(RC_INT);
4919− vpop();
4920− } else {
4921− gen_op(TOK_LE);
4922− e = gtst(1, 0);
4923− case_reg = gv(RC_INT);
4924− vpop();
4925− vseti(case_reg, 0);
4926− vdup();
4927− vpushi(p->v1);
4928− gen_op(TOK_GE);
4929− gtst_addr(0, p->sym);
4930− case_reg = gv(RC_INT);
4931− vpop();
4932− gsym(e);
4933− }
4934− }
4935− } else {
4909+ while (len > 4) {
4910+ /* binary search */
49364911 p = base[len/2];
4937− /* mid */
49384912 vseti(case_reg, 0);
49394913 vdup();
49404914 vpushi(p->v2);
@@ -4946,19 +4920,43 @@ static int gcase(struct case_t **base, int len, int case_reg, int *bsym) · 5 unmodified lines
49464920 vdup();
49474921 vpushi(p->v1);
49484922 gen_op(TOK_GE);
4949− gtst_addr(0, p->sym);
4923+ gtst_addr(0, p->sym); /* v1 <= x <= v2 */
49504924 case_reg = gv(RC_INT);
49514925 vpop();
4952− /* left */
4926+ /* x < v1 */
49534927 case_reg = gcase(base, len/2, case_reg, bsym);
49544928 if (cur_switch->def_sym)
49554929 gjmp_addr(cur_switch->def_sym);
49564930 else
49574931 *bsym = gjmp(*bsym);
4958− /* right */
4932+ /* x > v2 */
49594933 gsym(e);
49604934 e = len/2 + 1;
4961− case_reg = gcase(base + e, len - e, case_reg, bsym);
4935+ base += e; len -= e;
4936+ }
4937+ /* linear scan */
4938+ while (len--) {
4939+ p = *base++;
4940+ vseti(case_reg, 0);
4941+ vdup();
4942+ vpushi(p->v2);
4943+ if (p->v1 == p->v2) {
4944+ gen_op(TOK_EQ);
4945+ gtst_addr(0, p->sym);
4946+ } else {
4947+ gen_op(TOK_LE);
4948+ e = gtst(1, 0);
4949+ case_reg = gv(RC_INT);
4950+ vpop();
4951+ vseti(case_reg, 0);
4952+ vdup();
4953+ vpushi(p->v1);
4954+ gen_op(TOK_GE);
4955+ gtst_addr(0, p->sym);
4956+ gsym(e);
4957+ }
4958+ case_reg = gv(RC_INT);
4959+ vpop();
49624960 }
49634961 return case_reg;
49644962 }
@@ -5245,7 +5243,8 @@ static void block(int *bsym, int *csym, int is_expr) · 280 unmodified lines
52455243 b = gjmp(0); /* jump to first case */
52465244 sw.p = NULL; sw.n = 0; sw.def_sym = 0;
52475245 saved = cur_switch;
5248− cur_switch = &sw; block(&a, csym, 0);
5246+ cur_switch = &sw;
5247+ block(&a, csym, 0);
52495248 a = gjmp(a); /* add implicit break */
52505249 /* case lookup */
52515250 gsym(b);

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