Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 class SsaCodeGeneratorTask extends CompilerTask { | 5 class SsaCodeGeneratorTask extends CompilerTask { |
| 6 final JavaScriptBackend backend; | 6 final JavaScriptBackend backend; |
| 7 SsaCodeGeneratorTask(JavaScriptBackend backend) | 7 SsaCodeGeneratorTask(JavaScriptBackend backend) |
| 8 : this.backend = backend, | 8 : this.backend = backend, |
| 9 super(backend.compiler); | 9 super(backend.compiler); |
| 10 String get name() => 'SSA code generator'; | 10 String get name() => 'SSA code generator'; |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 | 191 |
| 192 LibraryElement get currentLibrary() => work.element.getLibrary(); | 192 LibraryElement get currentLibrary() => work.element.getLibrary(); |
| 193 Compiler get compiler() => backend.compiler; | 193 Compiler get compiler() => backend.compiler; |
| 194 NativeEmitter get nativeEmitter() => backend.emitter.nativeEmitter; | 194 NativeEmitter get nativeEmitter() => backend.emitter.nativeEmitter; |
| 195 Enqueuer get world() => backend.compiler.enqueuer.codegen; | 195 Enqueuer get world() => backend.compiler.enqueuer.codegen; |
| 196 | 196 |
| 197 bool isGenerateAtUseSite(HInstruction instruction) { | 197 bool isGenerateAtUseSite(HInstruction instruction) { |
| 198 return generateAtUseSite.contains(instruction); | 198 return generateAtUseSite.contains(instruction); |
| 199 } | 199 } |
| 200 | 200 |
| 201 bool isNonNegativeInt32Constant(HInstruction instruction) { | |
| 202 if (instruction.isConstantInteger()) { | |
| 203 int value = instruction.constant.value; | |
| 204 if (value >= 0 && value < Math.pow(2, 31)) { | |
|
floitsch
2012/06/28 22:57:18
(1 << 31) would be a compile time constant. Math.p
Mads Ager (google)
2012/06/29 00:03:23
Done.
| |
| 205 return true; | |
| 206 } | |
| 207 } | |
| 208 return false; | |
| 209 } | |
| 210 | |
| 211 // We want the outcome of bit-operations to be positive. However, if | |
| 212 // the result of a bit-operation is only used by other bit | |
| 213 // operations we do not have to convert to an unsigned | |
| 214 // integer. Also, if we are using & with a positive constant we know | |
| 215 // that the result is positive already and need no conversion. | |
| 216 bool requiresUintConversion(HInstruction instruction) { | |
| 217 if (instruction is HBitAnd && | |
| 218 (isNonNegativeInt32Constant(instruction.left) || | |
| 219 isNonNegativeInt32Constant(instruction.right))) { | |
| 220 return false; | |
| 221 } | |
| 222 bool result = false; | |
| 223 for (HInstruction use in instruction.usedBy) { | |
| 224 if (use is! HBitNot && use is! HBinaryBitOp) { | |
| 225 result = true; | |
| 226 break; | |
| 227 } | |
| 228 } | |
| 229 return result; | |
| 230 } | |
| 231 | |
| 201 SsaCodeGenerator(this.backend, | 232 SsaCodeGenerator(this.backend, |
| 202 this.work, | 233 this.work, |
| 203 this.parameters, | 234 this.parameters, |
| 204 this.parameterNames) | 235 this.parameterNames) |
| 205 : declaredVariables = new Set<String>(), | 236 : declaredVariables = new Set<String>(), |
| 206 delayedVariableDeclarations = new Set<String>(), | 237 delayedVariableDeclarations = new Set<String>(), |
| 207 buffer = new StringBuffer(), | 238 buffer = new StringBuffer(), |
| 208 generateAtUseSite = new Set<HInstruction>(), | 239 generateAtUseSite = new Set<HInstruction>(), |
| 209 controlFlowOperators = new Set<HInstruction>(), | 240 controlFlowOperators = new Set<HInstruction>(), |
| 210 breakAction = new Map<Element, ElementAction>(), | 241 breakAction = new Map<Element, ElementAction>(), |
| (...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1141 use(node.right, operatorPrecedences.right); | 1172 use(node.right, operatorPrecedences.right); |
| 1142 endExpression(operatorPrecedences.precedence); | 1173 endExpression(operatorPrecedences.precedence); |
| 1143 } else { | 1174 } else { |
| 1144 visitInvokeStatic(node); | 1175 visitInvokeStatic(node); |
| 1145 } | 1176 } |
| 1146 } | 1177 } |
| 1147 | 1178 |
| 1148 // We want the outcome of bit-operations to be positive. We use the unsigned | 1179 // We want the outcome of bit-operations to be positive. We use the unsigned |
| 1149 // shift operator to achieve this. | 1180 // shift operator to achieve this. |
| 1150 visitBitInvokeBinary(HBinaryBitOp node, String op) { | 1181 visitBitInvokeBinary(HBinaryBitOp node, String op) { |
| 1151 if (node.builtin) { | 1182 if (node.builtin && requiresUintConversion(node)) { |
| 1152 beginExpression(unsignedShiftPrecedences.precedence); | 1183 beginExpression(unsignedShiftPrecedences.precedence); |
| 1153 int oldPrecedence = this.expectedPrecedence; | 1184 int oldPrecedence = this.expectedPrecedence; |
| 1154 this.expectedPrecedence = JSPrecedence.SHIFT_PRECEDENCE; | 1185 this.expectedPrecedence = JSPrecedence.SHIFT_PRECEDENCE; |
| 1155 visitInvokeBinary(node, op); | 1186 visitInvokeBinary(node, op); |
| 1156 buffer.add(' >>> 0'); | 1187 buffer.add(' >>> 0'); |
| 1157 this.expectedPrecedence = oldPrecedence; | 1188 this.expectedPrecedence = oldPrecedence; |
| 1158 endExpression(unsignedShiftPrecedences.precedence); | 1189 endExpression(unsignedShiftPrecedences.precedence); |
| 1159 } else { | 1190 } else { |
| 1160 visitInvokeBinary(node, op); | 1191 visitInvokeBinary(node, op); |
| 1161 } | 1192 } |
| 1162 } | 1193 } |
| 1163 | 1194 |
| 1164 visitInvokeUnary(HInvokeUnary node, String op) { | 1195 visitInvokeUnary(HInvokeUnary node, String op) { |
| 1165 if (node.builtin) { | 1196 if (node.builtin) { |
| 1166 beginExpression(JSPrecedence.PREFIX_PRECEDENCE); | 1197 beginExpression(JSPrecedence.PREFIX_PRECEDENCE); |
| 1167 buffer.add('$op'); | 1198 buffer.add('$op'); |
| 1168 use(node.operand, JSPrecedence.PREFIX_PRECEDENCE); | 1199 use(node.operand, JSPrecedence.PREFIX_PRECEDENCE); |
| 1169 endExpression(JSPrecedence.PREFIX_PRECEDENCE); | 1200 endExpression(JSPrecedence.PREFIX_PRECEDENCE); |
| 1170 } else { | 1201 } else { |
| 1171 visitInvokeStatic(node); | 1202 visitInvokeStatic(node); |
| 1172 } | 1203 } |
| 1173 } | 1204 } |
| 1174 | 1205 |
| 1175 // We want the outcome of bit-operations to be positive. We use the unsigned | 1206 // We want the outcome of bit-operations to be positive. We use the unsigned |
| 1176 // shift operator to achieve this. | 1207 // shift operator to achieve this. |
| 1177 visitBitInvokeUnary(HInvokeUnary node, String op) { | 1208 visitBitInvokeUnary(HInvokeUnary node, String op) { |
| 1178 if (node.builtin){ | 1209 if (node.builtin && requiresUintConversion(node)) { |
| 1179 beginExpression(unsignedShiftPrecedences.precedence); | 1210 beginExpression(unsignedShiftPrecedences.precedence); |
| 1180 int oldPrecedence = this.expectedPrecedence; | 1211 int oldPrecedence = this.expectedPrecedence; |
| 1181 this.expectedPrecedence = JSPrecedence.SHIFT_PRECEDENCE; | 1212 this.expectedPrecedence = JSPrecedence.SHIFT_PRECEDENCE; |
| 1182 visitInvokeUnary(node, op); | 1213 visitInvokeUnary(node, op); |
| 1183 buffer.add(' >>> 0'); | 1214 buffer.add(' >>> 0'); |
| 1184 this.expectedPrecedence = oldPrecedence; | 1215 this.expectedPrecedence = oldPrecedence; |
| 1185 endExpression(unsignedShiftPrecedences.precedence); | 1216 endExpression(unsignedShiftPrecedences.precedence); |
| 1186 } else { | 1217 } else { |
| 1187 visitInvokeUnary(node, op); | 1218 visitInvokeUnary(node, op); |
| 1188 } | 1219 } |
| (...skipping 1883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3072 startBailoutSwitch(); | 3103 startBailoutSwitch(); |
| 3073 } | 3104 } |
| 3074 } | 3105 } |
| 3075 | 3106 |
| 3076 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 3107 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
| 3077 if (labeledBlockInfo.body.start.hasGuards()) { | 3108 if (labeledBlockInfo.body.start.hasGuards()) { |
| 3078 endBailoutSwitch(); | 3109 endBailoutSwitch(); |
| 3079 } | 3110 } |
| 3080 } | 3111 } |
| 3081 } | 3112 } |
| OLD | NEW |