Print this page
11972 resync smatch
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/memops.c
+++ new/usr/src/tools/smatch/src/memops.c
1 1 /*
2 2 * memops - try to combine memory ops.
3 3 *
4 4 * Copyright (C) 2004 Linus Torvalds
5 5 */
6 6
7 7 #include <string.h>
8 8 #include <stdarg.h>
9 9 #include <stdlib.h>
10 10 #include <stdio.h>
11 11 #include <stddef.h>
12 12 #include <assert.h>
13 13
14 14 #include "parse.h"
15 15 #include "expression.h"
16 16 #include "linearize.h"
17 17 #include "flow.h"
18 18
19 19 static int find_dominating_parents(pseudo_t pseudo, struct instruction *insn,
20 20 struct basic_block *bb, unsigned long generation, struct pseudo_list **dominators,
21 21 int local)
22 22 {
23 23 struct basic_block *parent;
24 24
25 25 FOR_EACH_PTR(bb->parents, parent) {
26 26 struct instruction *one;
27 27 struct instruction *br;
28 28 pseudo_t phi;
29 29
30 30 FOR_EACH_PTR_REVERSE(parent->insns, one) {
31 31 int dominance;
32 32 if (!one->bb)
33 33 continue;
34 34 if (one == insn)
35 35 goto no_dominance;
36 36 dominance = dominates(pseudo, insn, one, local);
37 37 if (dominance < 0) {
38 38 if (one->opcode == OP_LOAD)
39 39 continue;
40 40 return 0;
41 41 }
42 42 if (!dominance)
43 43 continue;
44 44 goto found_dominator;
45 45 } END_FOR_EACH_PTR_REVERSE(one);
46 46 no_dominance:
↓ open down ↓ |
46 lines elided |
↑ open up ↑ |
47 47 if (parent->generation == generation)
48 48 continue;
49 49 parent->generation = generation;
50 50
51 51 if (!find_dominating_parents(pseudo, insn, parent, generation, dominators, local))
52 52 return 0;
53 53 continue;
54 54
55 55 found_dominator:
56 56 br = delete_last_instruction(&parent->insns);
57 - phi = alloc_phi(parent, one->target, one->size);
57 + phi = alloc_phi(parent, one->target, one->type);
58 58 phi->ident = phi->ident ? : one->target->ident;
59 59 add_instruction(&parent->insns, br);
60 60 use_pseudo(insn, phi, add_pseudo(dominators, phi));
61 61 } END_FOR_EACH_PTR(parent);
62 62 return 1;
63 63 }
64 64
65 65 static int address_taken(pseudo_t pseudo)
66 66 {
67 67 struct pseudo_user *pu;
68 68 FOR_EACH_PTR(pseudo->users, pu) {
69 69 struct instruction *insn = pu->insn;
70 70 if (insn->bb && (insn->opcode != OP_LOAD && insn->opcode != OP_STORE))
71 71 return 1;
72 + if (pu->userp != &insn->src)
73 + return 1;
72 74 } END_FOR_EACH_PTR(pu);
73 75 return 0;
74 76 }
75 77
76 78 static int local_pseudo(pseudo_t pseudo)
77 79 {
78 80 return pseudo->type == PSEUDO_SYM
79 81 && !(pseudo->sym->ctype.modifiers & (MOD_STATIC | MOD_NONLOCAL))
80 82 && !address_taken(pseudo);
81 83 }
82 84
83 85 static void simplify_loads(struct basic_block *bb)
84 86 {
85 87 struct instruction *insn;
86 88
87 89 FOR_EACH_PTR_REVERSE(bb->insns, insn) {
88 90 if (!insn->bb)
89 91 continue;
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
90 92 if (insn->opcode == OP_LOAD) {
91 93 struct instruction *dom;
92 94 pseudo_t pseudo = insn->src;
93 95 int local = local_pseudo(pseudo);
94 96 struct pseudo_list *dominators;
95 97 unsigned long generation;
96 98
97 99 /* Check for illegal offsets.. */
98 100 check_access(insn);
99 101
100 - if (insn->type->ctype.modifiers & MOD_VOLATILE)
102 + if (insn->is_volatile)
101 103 continue;
102 104
103 105 RECURSE_PTR_REVERSE(insn, dom) {
104 106 int dominance;
105 107 if (!dom->bb)
106 108 continue;
107 109 dominance = dominates(pseudo, insn, dom, local);
108 110 if (dominance) {
109 111 /* possible partial dominance? */
110 112 if (dominance < 0) {
111 113 if (dom->opcode == OP_LOAD)
112 114 continue;
113 115 goto next_load;
114 116 }
115 117 /* Yeehaa! Found one! */
116 118 convert_load_instruction(insn, dom->target);
117 119 goto next_load;
118 120 }
119 121 } END_FOR_EACH_PTR_REVERSE(dom);
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
120 122
121 123 /* OK, go find the parents */
122 124 generation = ++bb_generation;
123 125 bb->generation = generation;
124 126 dominators = NULL;
125 127 if (find_dominating_parents(pseudo, insn, bb, generation, &dominators, local)) {
126 128 /* This happens with initial assignments to structures etc.. */
127 129 if (!dominators) {
128 130 if (local) {
129 131 assert(pseudo->type != PSEUDO_ARG);
130 - convert_load_instruction(insn, value_pseudo(insn->type, 0));
132 + convert_load_instruction(insn, value_pseudo(0));
131 133 }
132 134 goto next_load;
133 135 }
134 136 rewrite_load_instruction(insn, dominators);
137 + } else { // cleanup pending phi-sources
138 + pseudo_t phi;
139 + FOR_EACH_PTR(dominators, phi) {
140 + kill_instruction(phi->def);
141 + } END_FOR_EACH_PTR(phi);
135 142 }
136 143 }
137 144 next_load:
138 145 /* Do the next one */;
139 146 } END_FOR_EACH_PTR_REVERSE(insn);
140 147 }
141 148
142 -static void kill_store(struct instruction *insn)
143 -{
144 - if (insn) {
145 - insn->bb = NULL;
146 - insn->opcode = OP_SNOP;
147 - kill_use(&insn->target);
148 - }
149 -}
150 -
151 149 static void kill_dominated_stores(struct basic_block *bb)
152 150 {
153 151 struct instruction *insn;
154 152
155 153 FOR_EACH_PTR_REVERSE(bb->insns, insn) {
156 154 if (!insn->bb)
157 155 continue;
158 156 if (insn->opcode == OP_STORE) {
159 157 struct instruction *dom;
160 158 pseudo_t pseudo = insn->src;
161 - int local = local_pseudo(pseudo);
159 + int local;
162 160
161 + if (!insn->type)
162 + continue;
163 + if (insn->is_volatile)
164 + continue;
165 +
166 + local = local_pseudo(pseudo);
163 167 RECURSE_PTR_REVERSE(insn, dom) {
164 168 int dominance;
165 169 if (!dom->bb)
166 170 continue;
167 171 dominance = dominates(pseudo, insn, dom, local);
168 172 if (dominance) {
169 173 /* possible partial dominance? */
170 174 if (dominance < 0)
171 175 goto next_store;
172 176 if (dom->opcode == OP_LOAD)
173 177 goto next_store;
174 178 /* Yeehaa! Found one! */
175 - kill_store(dom);
179 + kill_instruction_force(dom);
176 180 }
177 181 } END_FOR_EACH_PTR_REVERSE(dom);
178 182
179 183 /* OK, we should check the parents now */
180 184 }
181 185 next_store:
182 186 /* Do the next one */;
183 187 } END_FOR_EACH_PTR_REVERSE(insn);
184 188 }
185 189
186 190 void simplify_memops(struct entrypoint *ep)
187 191 {
188 192 struct basic_block *bb;
193 + pseudo_t pseudo;
189 194
190 195 FOR_EACH_PTR_REVERSE(ep->bbs, bb) {
191 196 simplify_loads(bb);
192 197 } END_FOR_EACH_PTR_REVERSE(bb);
193 198
194 199 FOR_EACH_PTR_REVERSE(ep->bbs, bb) {
195 200 kill_dominated_stores(bb);
196 201 } END_FOR_EACH_PTR_REVERSE(bb);
202 +
203 + FOR_EACH_PTR(ep->accesses, pseudo) {
204 + struct symbol *var = pseudo->sym;
205 + unsigned long mod;
206 + if (!var)
207 + continue;
208 + mod = var->ctype.modifiers;
209 + if (mod & (MOD_VOLATILE | MOD_NONLOCAL | MOD_STATIC))
210 + continue;
211 + kill_dead_stores(ep, pseudo, local_pseudo(pseudo));
212 + } END_FOR_EACH_PTR(pseudo);
197 213 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX