annotate interps/c-intercal/src/dekludge.c @ 12246:f3be034784d0 draft

<b_jonas> addwhatis brachylog(1egobot) - Brachylog, a Prolog-like golf language
author HackEso <hackeso@esolangs.org>
date Thu, 05 Dec 2019 23:44:34 +0000
parents 859f9b4339e6
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
996
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
1 /****************************************************************************
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
2
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
3 Name
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
4 dekludge.c -- C-INTERCAL expression and flow optimizers
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
5
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
6 DESCRIPTION
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
7 This file contains optimizations used by the C-INTERCAL compiler.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
8
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
9 LICENSE TERMS
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
10 Copyright (C) 1996 Eric S. Raymond
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
11
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
12 This program is free software; you can redistribute it and/or modify
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
13 it under the terms of the GNU General Public License as published by
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
14 the Free Software Foundation; either version 2 of the License, or
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
15 (at your option) any later version.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
16
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
17 This program is distributed in the hope that it will be useful,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
20 GNU General Public License for more details.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
21
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
22 You should have received a copy of the GNU General Public License
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
23 along with this program; if not, write to the Free Software
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
25
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
26 ****************************************************************************/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
27 /*LINTLIBRARY */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
28 #include "config.h"
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
29 #include <stdio.h>
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
30 #include <stdlib.h>
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
31 #include <string.h>
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
32 #include "sizes.h"
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
33 #include "ick.h"
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
34 #include "parser.h"
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
35 #include "fiddle.h"
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
36 #include "ick_lose.h"
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
37 #include "feh.h"
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
38
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
39 extern int emitlineno; /* AIS: From feh2.c */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
40
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
41 /* AIS: The following macro produces optimization debug data. I added all
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
42 occurences of it in this source file. It also keeps track of whether
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
43 optimizations have taken place. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
44 #define OPTING(x) if(optdebug == 2) {\
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
45 explexpr(optdebugnode,stderr);\
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
46 putc('\n',stderr); } \
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
47 if(optdebug == 3) {\
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
48 prexpr(optdebugnode,stderr,0);\
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
49 putc('\n',stderr); } \
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
50 if(optdebug) fprintf(stderr,"[%s]",#x);\
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
51 if(optdebug >= 2) putc('\n',stderr);\
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
52 opted = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
53
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
54 void checknodeactbits(node *np); /* AIS: This prototype needed early */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
55 extern void prexpr(node *np, FILE* fp, int freenode); /* AIS */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
56
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
57 /* By AIS. This function looks remarkably like a C++ copy-constructor to me,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
58 just with extra arrows in. The annotations here show that nulls are allowed
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
59 when called recursively, but not otherwise. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
60 /*@-incondefs@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
61 /*@null@*/ node *nodecopy(/*@null@*/ const node* n)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
62 /*@=incondefs@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
63 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
64 node* np;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
65 if(!n) return 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
66 np = cons(n->opcode, nodecopy(n->lval), nodecopy(n->rval));
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
67 np->constant = n->constant;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
68 np->optdata = n->optdata;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
69 np->width = n->width;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
70 return np;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
71 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
72
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
73 /* This function by AIS. Compares expressions. In C++, I'd call this
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
74 node::operator== . */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
75 ick_bool nodessame(/*@observer@*/ const node* n1, /*@observer@*/ const node* n2)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
76 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
77 if(!n1) return !n2;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
78 if(!n2) return 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
79 if(n1->opcode!=n2->opcode)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
80 return (((n1->opcode == MESH && n2->opcode == MESH32) ||
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
81 (n1->opcode == MESH32 && n2->opcode == MESH)) &&
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
82 n1->constant == n2->constant);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
83 if(!nodessame(n1->lval,n2->lval)) return 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
84 if(!nodessame(n1->rval,n2->rval)) return 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
85 switch(n1->opcode)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
86 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
87 case ick_ONESPOT:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
88 case ick_TWOSPOT:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
89 case ick_HYBRID:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
90 case ick_TAIL:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
91 case MESH:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
92 case MESH32:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
93 return n1->constant == n2->constant;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
94 case AND:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
95 case OR:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
96 case XOR:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
97 return n1->width == n2->width;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
98 default:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
99 return 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
100 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
101 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
102
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
103 /* AIS: Checks if an abstention could affect a tuple. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
104 static int abstainmatch(int npconstant, int tptype)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
105 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
106 if(npconstant == tptype) return 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
107 if(npconstant == ABSTAIN)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
108 if(tptype == FROM || tptype == MANYFROM || tptype == DISABLE) return 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
109 if(npconstant == REINSTATE)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
110 if(tptype == ENABLE) return 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
111 if(npconstant == GETS)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
112 if(tptype == RESIZE) return 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
113 if(npconstant == UNKNOWN) /* JH */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
114 if(tptype == SPLATTERED) return 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
115 return 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
116 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
117
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
118
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
119 /*************************************************************************
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
120 *
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
121 * AIS: Flow optimizer. (I wrote the whole of optimizef.)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
122 *
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
123 * This analyses the flow of the program, checking to see which lines can
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
124 * have their guards omitted, which lines can be omitted altogether, which
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
125 * variables can never be ignored, etc. The degenerator lower down can take
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
126 * this information into account, producing faster and shorter source code.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
127 * In an ideal world, we'd end up with the produced INTERCAL looking like
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
128 * proper C code, but somehow I think that's unlikely to happen.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
129 * At the moment, it just checks for unused !ick_abstained[] guards on
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
130 * statements and removes them (possibly removing comments altogether).
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
131 * This is minor, but should clear up degenerated code substantially.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
132 * It also allows the code for gets to replace ick_assign() with the faster =
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
133 * in cases where this doesn't affect the behaviour of the program.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
134 * See the function itself for what I did to NEXT.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
135 *
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
136 *************************************************************************/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
137
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
138 void optimizef(void)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
139 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
140 tuple* tp, *tpa, *tpb;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
141 atom* op;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
142 node* np;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
143 if(!flowoptimize) ick_lose(IE778, iyylineno, (const char *) NULL);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
144 for (tp = tuples; tp < tuples + ick_lineno; tp++) tp->abstainable = 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
145 /* abstainable holds whether a line's abstention status can change */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
146 for (op = oblist; op != NULL && op < obdex; op++) op->ignorable = 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
147 /* ignorable holds whether a variable's ignorance status can change */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
148 for (tp = tuples; tp < tuples + ick_lineno; tp++)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
149 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
150 /* allow for warnings to be generated during flow optimisations */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
151 /* AIS: I marked tuples as only deliberately, so that it produced warnings
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
152 when aliased in an unsafe way. However, tuples isn't realloced during
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
153 optimisation, so we can safely ignore the warning for it produced
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
154 here. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
155 /*@-onlytrans@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
156 optuple = tp;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
157 /*@=onlytrans@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
158 if(tp->maybe) tp->abstainable = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
159 if(tp->exechance < 0) tp->initabstain = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
160 if(tp->exechance != 100 && tp->exechance != -100) tp->abstainable = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
161 if(tp->onceagainflag != onceagain_NORMAL) tp->abstainable = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
162 if(tp->type == ABSTAIN || tp->type == FROM)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
163 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
164 tpa = tp->u.target - 1 + tuples;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
165 if(tpa->exechance >= 0) tpa->abstainable = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
166 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
167 if(tp->type == REINSTATE)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
168 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
169 tpa = tp->u.target - 1 + tuples;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
170 if(tpa->exechance < 0) tpa->abstainable = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
171 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
172 if(tp->type == DISABLE || tp->type == MANYFROM)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
173 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
174 for (tpa = tuples; tpa < tuples + ick_lineno; tpa++)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
175 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
176 np = tp->u.node;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
177 if(tp->type == MANYFROM) np = np->rval;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
178 for(; np; np = np -> rval)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
179 if(abstainmatch((int)np->constant, (int)tpa->type))
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
180 if(tpa->exechance >= 0) tpa->abstainable = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
181 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
182 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
183 if(tp->type == ENABLE)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
184 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
185 for (tpa = tuples; tpa < tuples + ick_lineno; tpa++)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
186 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
187 np = tp->u.node;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
188 for(; np; np = np -> rval)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
189 if(abstainmatch((int)np->constant, (int)tpa->type))
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
190 if(tpa->exechance < 0) tpa->abstainable = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
191 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
192 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
193 if(tp->type == GETS && ick_Base == 2 && !opoverused)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
194 checknodeactbits(tp->u.node->rval);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
195 /* If optdata shows that the value must always fit in the variable,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
196 and the variable cannot be ignored, ick_assign can be replaced by the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
197 cheaper =. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
198 if(tp->type == IGNORE)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
199 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
200 for (np = tp->u.node; np; np = np->rval)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
201 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
202 for (op = oblist; op != NULL && op < obdex; op++)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
203 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
204 if(op->type == np->opcode && (unsigned long)op->intindex == np->constant)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
205 op->ignorable = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
206 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
207 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
208 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
209 /* REMEMBERING variables has no effect on this code, because all
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
210 variables are initially remembered anyway, and so an IGNORE would
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
211 be needed (and caught above) to have an effect. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
212 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
213 /* There are some flow idioms that maybe should be optimized. The most
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
214 common is the NEXTing idiom for if(), which looks like this:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
215
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
216 DO (1) NEXT
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
217 block 2
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
218 escape via NEXTING or COMEFROM
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
219 (1) DO (2) NEXT
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
220 DO FORGET #1
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
221 block 1
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
222
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
223 and elsewhere in the program:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
224 (2) DO RESUME <1-or-2-condition>
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
225
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
226 Recognizing this idiom is quite difficult because there are a number of
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
227 problems and common variations.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
228 First, the FORGET might be placed elsewhere, or replaced with a higher
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
229 FORGET later or a higher RESUME later. If there is, in fact, a RESUME #1
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
230 as the ick_next NEXT-control statement, the idiom won't quite work properly.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
231 So to handle this, we need to push the original return address on the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
232 NEXT stack if block 1 is taken, unless the ick_next statement is a FORGET #1.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
233 Second, there may be abstentions or COME FROMs messing with control flow
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
234 in the area. The flow optimizer ought to be able to detect this and not
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
235 optimize the statement if true. (This means that a program which uses
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
236 gerund abstention on NEXTING or RESUMING, or that uses computed COME FROM,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
237 will probably not benefit from this optimization). Third, how should a
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
238 <1-or-2-condition> be detected? Throughout syslib, the most common
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
239 condition to use is .5, which isn't inherently 1 or 2. The way round this
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
240 seems to be to detect a <1-or-2-assignment> as the previous statement,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
241 again with checks for COME FROM and abstentions. (I treat MAYBE as a sort
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
242 of abstention, albeit a temporally undecided one.) So ignorance of the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
243 relevant variable needs to be checked for also. The checks are done partly
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
244 in optimizef() and partly in emit().
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
245 */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
246 if(compucomesused||ick_Base!=2||opoverused) return;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
247
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
248 np = (node*) NULL;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
249 for (tp = tuples; tp < tuples + ick_lineno; tp++)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
250 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
251 if(tp->type == GETS)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
252 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
253 /* if(tp->u.node->rval->opcode == C_AND1ADD1 ||
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
254 tp->u.node->rval->opcode == C_2SUBAND1 ||
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
255 ((tp->u.node->rval->opcode == C_1PLUS ||
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
256 tp->u.node->rval->opcode == C_2MINUS) &&
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
257 tp->u.node->rval->rval->optdata == 1)) //debug for now */ if(0)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
258 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
259 /* This won't catch all <1-or-2-expressions>, but will get
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
260 most of them. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
261 if(tp->u.node->lval->opcode != SUB) np = tp->u.node->lval;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
262 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
263 else if(np != NULL && nodessame(np, tp->u.node->lval)) np = (node*) NULL;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
264 if(tp->nextable) np = (node*) NULL;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
265 if(tp->maybe||tp->abstainable) np = (node*) NULL;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
266 if(tp->ncomefrom&&multithread) np = (node*) NULL;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
267 if(np)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
268 { /* IGNORING np might prevent it getting its <1-or-2-value>. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
269 atom* op2;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
270 int ignorable = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
271 for(op2 = oblist; op2 != NULL && op2 < obdex; op2++)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
272 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
273 if(op2->type == np->opcode &&
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
274 (unsigned long)op2->intindex == np->constant)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
275 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
276 ignorable &= op2->ignorable;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
277 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
278 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
279 if(ignorable) np = (node*) NULL;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
280 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
281 /* np will only have a nonnull value if it's a variable that must be
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
282 set to a <1-or-2-value> to reach line tp. Regardless of whether
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
283 maybes have been parsed or not, either maybe or abstainable or
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
284 both will be 1 on a MAYBE line. The last check is a precaution
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
285 against MAYBE COME FROM sneakily modifying a variable (although
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
286 I think it's unlikely that anyone would deliberately try to fool
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
287 -f like this, it is INTERCAL after all!) */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
288 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
289 if(tp->type == COME_FROM || tp->type == COMPUCOME) np = (node*) NULL;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
290 if(tp->type == NEXT)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
291 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
292 tpa = tuples + tp->nexttarget - 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
293 if(tpa->type == NEXT && !tp->abstainable && !tpa->abstainable
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
294 && !tp->ncomefrom && !tpa->ncomefrom)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
295 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
296 tpb = tuples + tpa->nexttarget - 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
297 if(tpb->type == RESUME && (/*(tpb->u.node->opcode == C_AND1ADD1 ||
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
298 tpb->u.node->opcode == C_2SUBAND1 ||
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
299 ((tpb->u.node->opcode == C_1PLUS ||
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
300 tpb->u.node->opcode == C_2MINUS) &&
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
301 tpb->u.node->rval->optdata == 1)) ||*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
302 (np != NULL && nodessame(tpb->u.node,np))) &&
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
303 !tpb->abstainable)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
304 /* No COMING FROM a nonabstainable RESUME line! */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
305 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
306 tp->optversion = ick_TRUE;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
307 free(tp->u.node);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
308 tp->u.node = nodecopy(tpb->u.node);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
309 /* If tp->u.node is 2, then the statement should translate to a
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
310 no-op (NEXT...NEXT...RESUME #2). However, if tp->u.node is 1,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
311 the statement should translate to a NEXT to the line after the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
312 one it's aiming for. As it's aiming for a NEXT, the solution is
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
313 to NEXT to the return label of the NEXT it's aiming for. This
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
314 won't trigger any COME FROMs or ONCE/AGAIN flags, or even MAYBEs,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
315 on the commands missed out, so the code has checked that they
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
316 aren't there. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
317 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
318 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
319 np = (node*) NULL;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
320 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
321 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
322 /*@-nullstate@*/ /* no tuples->u.node can't be null */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
323 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
324 /*@=nullstate@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
325
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
326 /*************************************************************************
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
327 *
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
328 * Expression optimizer.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
329 *
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
330 * It's not a very good optimizer, is it?
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
331 *
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
332 * AIS: All free'd pointers set to NULL, to help trace memory problems.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
333 * The optimizer can now recognize the majority of syslib's idioms.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
334 * The optimizer will make multiple passes. Although I am now happy
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
335 * with the quality of this optimizer, I'll keep the paragraph above
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
336 * this one for history's sake. The optimizing functions return 1
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
337 * if any optimizations were made, apart from optimize itself, which
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
338 * is void.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
339 *
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
340 **************************************************************************/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
341
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
342 extern int optimize_pass1(node *np); /* Read from idiotism.c */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
343 static void checkforintercaloperators(const node *np);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
344 static void checkW534(const node *np);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
345
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
346 node* optdebugnode;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
347
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
348 /* This function by AIS */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
349 void optimize(node *np)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
350 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
351 int optflag;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
352 if(opoverused) return; /* what chance do we have of optimizing this? */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
353 if(ick_Base==2)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
354 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
355 checknodeactbits(np);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
356 checkW534(np); /* This must be done before optimization, and depends on
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
357 checknodeactbits. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
358 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
359 if(optdebug == 1) explexpr(np,stderr);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
360 if(optdebug == 1) fprintf(stderr," becomes ");
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
361 if(optdebug >= 2) optdebugnode = np;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
362 if(ick_Base==2) (void) optimize_pass1(np); /* Optimize idioms; from idiotism.oil */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
363 if(ick_Base!=2)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
364 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
365 if(optdebug && optdebug != 3) explexpr(np,stderr);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
366 if(optdebug == 3) prexpr(np,stderr,0);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
367 if(optdebug) fprintf(stderr,"\n");
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
368 if(optdebug >= 2) fprintf(stderr,"-----\n");
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
369 return;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
370 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
371 do
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
372 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
373 optflag = optimize_pass1(np);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
374 } while(optflag); /* Keep optimizing until no optimizations are found */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
375 if(optdebug && optdebug != 3) explexpr(np,stderr);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
376 if(optdebug == 3) prexpr(np,stderr,0);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
377 if(optdebug) fprintf(stderr,"\n");
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
378 if(optdebug >= 2) fprintf(stderr,"-----\n");
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
379 checkforintercaloperators(np);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
380 if(optuple->type == RESUME && !np->optdata) optuple->warn622 = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
381 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
382
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
383 /* By AIS. This relies on free'd pointers being NULLed. The annotations
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
384 are basically trying to describe how the function operates. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
385 void nodefree(/*@keep@*/ /*@null@*/ node *np)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
386 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
387 if(!np) return;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
388 /*@-mustfreeonly@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
389 if(np->nextslat) return; /* don't free, has oo data */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
390 if(np==prevslat) return; /* likewise */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
391 /*@=mustfreeonly@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
392 /*@-keeptrans@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
393 nodefree(np->lval);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
394 nodefree(np->rval);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
395 free(np);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
396 /*@=keeptrans@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
397 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
398
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
399 /* By AIS. This checks W534. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
400 static void checkW534(const node *np)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
401 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
402 if(!np) return;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
403 if(np->opcode == AND || np->opcode == OR || np->opcode == XOR)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
404 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
405 if(np->rval->opcode == SELECT && np->rval->rval->width == 32 &&
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
406 !(np->rval->rval->optdata&0xffff0000lu))
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
407 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
408 /* This looks suspicious, in that C-INTERCAL will do an op32,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
409 but INTERCAL-72 would have done an op16. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
410 optuple->warn534=1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
411 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
412 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
413 checkW534(np->lval);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
414 checkW534(np->rval);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
415 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
416
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
417 /* By AIS. This checks W018. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
418 static void checkforintercaloperators(const node *np)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
419 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
420 if(!np) return;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
421 switch(np->opcode)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
422 { /* This only comes up in binary. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
423 case AND: case OR: case XOR: case MINGLE: case SELECT:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
424 optuple->warn018 = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
425 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
426 default:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
427 checkforintercaloperators(np->lval);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
428 checkforintercaloperators(np->rval);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
429 return;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
430 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
431 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
432
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
433 /* By AIS (with a few code fragments copied from elsewhere in this file)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
434 This generates the values of c used by the OIL idiom file idiotism.oil. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
435 void checknodeactbits(node *np)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
436 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
437 int temp;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
438 if (np == (node *)NULL)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
439 return;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
440 else if (np->lval != (node *)NULL)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
441 checknodeactbits(np->lval);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
442 if (np->rval != (node *)NULL)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
443 checknodeactbits(np->rval);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
444
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
445 switch (np->opcode)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
446 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
447 case MINGLE:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
448 /*@-nullderef@*/ /* mingle has two nonnull arguments */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
449 if(np->lval->optdata & 0xffff0000LU) optuple->warn276 = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
450 if(np->rval->optdata & 0xffff0000LU) optuple->warn276 = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
451 np->optdata = ick_mingle((unsigned)(np->lval->optdata & 0xffff),
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
452 (unsigned)(np->rval->optdata & 0xffff));
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
453 /*@=nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
454 /* The bitmask is needed because the output of ~ might always be 16-bit
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
455 at runtime, but appear 32-bit at compile-time. But this is somewhat
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
456 suspicious, so we can at least give a warning (W276) if -l is used. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
457 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
458
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
459 case SELECT:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
460 /* The result could be the selected optdata, or have a 1 anywhere to the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
461 right of a 1 in the resulting selection if there are 0s in rval where
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
462 there could have been 1s */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
463 /*@-nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
464 np->optdata = ick_iselect((unsigned)np->lval->optdata, (unsigned)np->rval->optdata);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
465 /*@=nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
466 temp=16;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
467 while(temp--) np->optdata|=(np->optdata>>1); /* fill in gaps in optdata */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
468 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
469
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
470 case AND:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
471 if(np->width==16)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
472 np->optdata = ick_and16((unsigned)np->rval->optdata);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
473 else
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
474 np->optdata = ick_and32((unsigned)np->rval->optdata);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
475 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
476
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
477 case OR:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
478 case XOR:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
479 if(np->width==16)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
480 np->optdata = ick_or16((unsigned)np->rval->optdata);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
481 else
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
482 np->optdata = ick_or32((unsigned)np->rval->optdata);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
483 /* This is or in both cases. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
484 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
485
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
486 case FIN:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
487 case WHIRL:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
488 case WHIRL2:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
489 case WHIRL3:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
490 case WHIRL4:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
491 case WHIRL5: /* We must be in binary to reach this point, so: */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
492 ick_lose(IE997, emitlineno, (const char*) NULL);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
493 /*@-unreachable@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
494 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
495 /*@=unreachable@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
496
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
497 case MESH:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
498 case MESH32:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
499 np->optdata = np->constant; /* It's trivial to tell which bits
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
500 can be nonzero! */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
501 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
502
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
503 case ick_ONESPOT:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
504 case ick_TWOSPOT:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
505 case ick_TAIL:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
506 case ick_HYBRID:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
507 case SUB:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
508 np->optdata = np->width == 16 ? 0xffffLU : 0xffffffffLU;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
509 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
510
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
511 /* cases from here down are generated by optimize_pass1 */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
512 case C_AND:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
513 /*@-nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
514 np->optdata = np->lval->optdata & np->rval->optdata;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
515 /*@=nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
516 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
517
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
518 case C_OR:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
519 case C_XOR:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
520 /*@-nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
521 np->optdata = np->lval->optdata | np->rval->optdata;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
522 /*@=nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
523 /* bitwise-or is correct in both cases */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
524 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
525
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
526 case C_NOT:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
527 np->optdata = np->width == 16 ? 0xffffLU : 0xffffffffLU;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
528 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
529
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
530 case C_A:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
531 np->optdata = 0xffffffffLU;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
532 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
533
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
534 case C_NOTEQUAL:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
535 case C_ISEQUAL:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
536 case C_LOGICALNOT:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
537 case C_LOGICALAND:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
538 case C_LOGICALOR:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
539 case C_GREATER:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
540 case C_LESS:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
541 np->optdata = 1; /* this is a logical function */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
542 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
543
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
544 case C_RSHIFTBY:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
545 /*@-nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
546 if(np->rval->opcode == MESH || np->rval->opcode == MESH32)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
547 np->optdata = np->lval->optdata >> np->rval->constant;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
548 else np->optdata = (np->width == 16 ? 0xffffLU : 0xffffffffLU);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
549 /*@=nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
550 /* Play safe if the RHS isn't a constant */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
551 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
552
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
553 case C_LSHIFTBY:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
554 /*@-nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
555 if(np->rval->opcode == MESH || np->rval->opcode == MESH32)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
556 np->optdata = np->lval->optdata << np->rval->constant;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
557 else np->optdata = (np->width == 16 ? 0xffffLU : 0xffffffffLU);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
558 /*@=nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
559 /* Play safe if the RHS isn't a constant */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
560 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
561
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
562 case C_PLUS:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
563 /* A bit could be set if it's set in either of the numbers, or if it's set
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
564 by a carry; so OR together the two numbers and their sum. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
565 /*@-nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
566 np->optdata = np->lval->optdata | np->rval->optdata |
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
567 (np->lval->optdata + np->rval->optdata);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
568 /*@=nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
569 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
570
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
571 case C_MINUS:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
572 case C_DIVIDEBY:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
573 /* The optimizer shouldn't be able to generate negative answers or
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
574 divisions by 0, so just fill in all bits from lval rightwards */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
575 /*@-nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
576 np->optdata = np->lval->optdata;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
577 np->optdata |= np->optdata >> 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
578 np->optdata |= np->optdata >> 2;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
579 np->optdata |= np->optdata >> 4;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
580 np->optdata |= np->optdata >> 8;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
581 np->optdata |= np->optdata >> 16;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
582 /*@=nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
583 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
584
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
585 case C_MODULUS:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
586 /* The answer must be smaller than both inputs, but we can't tell anything
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
587 else */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
588 /*@-nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
589 np->optdata = np->lval->optdata;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
590 if(np->rval->optdata < np->optdata) np->optdata = np->rval->optdata;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
591 np->optdata |= np->optdata >> 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
592 np->optdata |= np->optdata >> 2;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
593 np->optdata |= np->optdata >> 4;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
594 np->optdata |= np->optdata >> 8;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
595 np->optdata |= np->optdata >> 16;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
596 /*@=nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
597 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
598
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
599 case C_TIMES:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
600 /* Convolve one set of active bits with the other, ORadding the results */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
601 np->optdata=0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
602 temp=32;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
603 /*@-nullderef@*/ /*@-shiftnegative@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
604 while(temp--)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
605 if(np->lval->optdata & (1LU << temp))
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
606 np->optdata = np->optdata | (np->rval->optdata << temp) |
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
607 ((np->rval->optdata << temp) + np->optdata);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
608 /*@=nullderef@*/ /*@=shiftnegative@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
609 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
610
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
611 case GETS:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
612 /* Of course, this doesn't return a value. So this uses the default
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
613 code just below it, which is why it doesn't end in break;. This
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
614 has its own case so that W276 can be given on an assignment. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
615 /*@-nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
616 if(np->lval->optdata == 0xffff &&
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
617 np->rval->optdata & 0xffff0000lu) optuple->warn276 = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
618 /*@=nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
619 /*@fallthrough@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
620
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
621 case UNKNOWNOP:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
622 default:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
623 /*@-nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
624 if(np->opcode == BY && !np->lval->optdata) optuple->warn239 = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
625 /*@=nullderef@*/
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
626 np->optdata = (np->width == 16 ? 0xffffLU : 0xffffffffLU);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
627 /* Some values of opcode are used as placeholders, to save more than 1
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
628 piece of information in a node. The optdata for these is probably
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
629 irrelevant, but just in case, we mark all possible bits as active. */
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
630 break;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
631 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
632 }