Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: lib/compiler/implementation/ssa/codegen_helpers.dart

Issue 10539042: Recognize nested logical operations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/compiler/implementation/ssa/codegen.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * Instead of emitting each SSA instruction with a temporary variable 6 * Instead of emitting each SSA instruction with a temporary variable
7 * mark instructions that can be emitted at their use-site. 7 * mark instructions that can be emitted at their use-site.
8 * For example, in: 8 * For example, in:
9 * t0 = 4; 9 * t0 = 4;
10 * t1 = 3; 10 * t1 = 3;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 /** 144 /**
145 * Check if a block has at least one statement other than 145 * Check if a block has at least one statement other than
146 * [instruction]. 146 * [instruction].
147 */ 147 */
148 bool hasStatement(HBasicBlock block, HInstruction instruction) { 148 bool hasStatement(HBasicBlock block, HInstruction instruction) {
149 // If [instruction] is not in [block], then if the block is not 149 // If [instruction] is not in [block], then if the block is not
150 // empty, we know there will be a statement to emit. 150 // empty, we know there will be a statement to emit.
151 if (instruction.block !== block) return block.last !== block.first; 151 if (instruction.block !== block) return block.last !== block.first;
152 152
153 // If [instruction] is not the last instruction of the block 153 // If [instruction] is not the last instruction of the block
154 // before the control flow instruction, then we will have to emit 154 // before the control flow instruction, or the last instruction,
155 // a statement for that last instruction. 155 // then we will have to emit a statement for that last instruction.
156 if (instruction !== block.last.previous) return true; 156 if (instruction != block.last
157 && instruction !== block.last.previous) return true;
157 158
158 // If one of the instructions in the block until [instruction] is 159 // If one of the instructions in the block until [instruction] is
159 // not generated at use site, then we will have to emit a 160 // not generated at use site, then we will have to emit a
160 // statement for it. 161 // statement for it.
161 // TODO(ngeoffray): we could generate a comma separated 162 // TODO(ngeoffray): we could generate a comma separated
162 // list of expressions. 163 // list of expressions.
163 for (HInstruction temp = block.first; 164 for (HInstruction temp = block.first;
164 temp !== instruction; 165 temp !== instruction;
165 temp = temp.next) { 166 temp = temp.next) {
166 if (!generateAtUseSite.contains(temp)) return true; 167 if (!generateAtUseSite.contains(temp)) return true;
(...skipping 12 matching lines...) Expand all
179 // / \ 180 // / \
180 // / \ 181 // / \
181 // 1 expr goto 182 // 1 expr goto
182 // goto / 183 // goto /
183 // \ / 184 // \ /
184 // \ / 185 // \ /
185 // phi(expr, true|false) 186 // phi(expr, true|false)
186 if (end == null) return; 187 if (end == null) return;
187 if (end.phis.isEmpty()) return; 188 if (end.phis.isEmpty()) return;
188 if (end.phis.first !== end.phis.last) return; 189 if (end.phis.first !== end.phis.last) return;
189 HBasicBlock thenBlock = startIf.thenBlock;
190 HBasicBlock elseBlock = startIf.elseBlock; 190 HBasicBlock elseBlock = startIf.elseBlock;
191 if (end.predecessors[0] !== thenBlock) return; 191
192 if (end.predecessors[1] !== elseBlock) return; 192 if (end.predecessors[1] !== elseBlock) return;
193 HPhi phi = end.phis.first; 193 HPhi phi = end.phis.first;
194 if (!phi.inputs[1].isConstantBoolean()) return; 194 if (!phi.inputs[1].isConstantBoolean()) return;
195 if (elseBlock.first is !HGoto) return;
196 assert(elseBlock.successors.length == 1);
197 assert(end.predecessors.length == 2);
198
199 HBasicBlock thenBlock = startIf.thenBlock;
200 // Skip trivial goto blocks.
201 while (thenBlock.successors[0] != end && thenBlock.first is HGoto) {
202 thenBlock = thenBlock.successors[0];
203 }
195 204
196 HInstruction thenInput = phi.inputs[0]; 205 HInstruction thenInput = phi.inputs[0];
197 if (hasStatement(thenBlock, thenInput)) return; 206
198 if (elseBlock.first !== elseBlock.last) return; 207 // If the [thenBlock] is already a logical operation, and does not
199 208 // have any statement, we can emit a sequence of logical operation.
209 if (logicalOperations.contains(thenBlock.last)) {
210 if (hasStatement(thenBlock, thenBlock.last)) return;
211 assert(thenInput.usedBy.length == 1);
212 generateAtUseSite.add(thenInput);
213 } else {
214 if (end.predecessors[0] !== thenBlock) return;
215 if (hasStatement(thenBlock, thenInput)) return;
216 // If [thenInput] is defined in [thenBlock], then it is only used
217 // by [phi] and can be generated at use site.
218 if (thenInput.block === thenBlock) {
219 // The instruction cannot be used by anyone else otherwise it
220 // would not be the last non control-flow instruction of [thenBlock].
221 assert(thenInput.usedBy.length == 1);
222 generateAtUseSite.add(thenInput);
223 }
224 assert(thenBlock.successors.length == 1);
225 }
226
200 // From now on, we have recognized a logical operation built from 227 // From now on, we have recognized a logical operation built from
201 // the builder. We don't expect the builder and the optimizers to 228 // the builder. Mark the if instruction as such.
202 // generate the then and else branches with multiple successors,
203 // and the join branch to have more than two predecessors.
204
205 // Mark the if instruction as a logical operation.
206 logicalOperations.add(startIf); 229 logicalOperations.add(startIf);
207 230
208 // If the logical operation is only used by the first instruction 231 // If the logical operation is only used by the first instruction
209 // of its block, it can be generated at use site. 232 // of its block, it can be generated at use site.
210 if (phi.usedBy.length == 1 && phi.usedBy[0] === phi.block.first) { 233 if (phi.usedBy.length == 1 && phi.usedBy[0] === phi.block.first) {
211 generateAtUseSite.add(phi); 234 generateAtUseSite.add(phi);
212 } 235 }
213
214 // If [thenInput] is defined in [thenBlock], then it is only used
215 // by [phi] and can be generated at use site.
216 if (thenInput.block === thenBlock) {
217 assert(thenInput.usedBy.length == 1);
218 generateAtUseSite.add(thenInput);
219 }
220 } 236 }
221 } 237 }
222 238
223 // Precedence information for JavaScript operators. 239 // Precedence information for JavaScript operators.
224 class JSPrecedence { 240 class JSPrecedence {
225 // Used as precedence for something that's not even an expression. 241 // Used as precedence for something that's not even an expression.
226 static final int STATEMENT_PRECEDENCE = 0; 242 static final int STATEMENT_PRECEDENCE = 0;
227 // Precedences of JS operators. 243 // Precedences of JS operators.
228 static final int EXPRESSION_PRECEDENCE = 1; 244 static final int EXPRESSION_PRECEDENCE = 1;
229 static final int ASSIGNMENT_PRECEDENCE = 2; 245 static final int ASSIGNMENT_PRECEDENCE = 2;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 }; 309 };
294 } 310 }
295 311
296 class JSBinaryOperatorPrecedence { 312 class JSBinaryOperatorPrecedence {
297 final int left; 313 final int left;
298 final int right; 314 final int right;
299 const JSBinaryOperatorPrecedence(this.left, this.right); 315 const JSBinaryOperatorPrecedence(this.left, this.right);
300 // All binary operators (excluding assignment) are left associative. 316 // All binary operators (excluding assignment) are left associative.
301 int get precedence() => left; 317 int get precedence() => left;
302 } 318 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/codegen.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698