| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/change-lowering.h" | 5 #include "src/compiler/change-lowering.h" |
| 6 | 6 |
| 7 #include "src/address-map.h" | 7 #include "src/address-map.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 | 22 |
| 23 Reduction ChangeLowering::Reduce(Node* node) { | 23 Reduction ChangeLowering::Reduce(Node* node) { |
| 24 Node* control = graph()->start(); | 24 Node* control = graph()->start(); |
| 25 switch (node->opcode()) { | 25 switch (node->opcode()) { |
| 26 case IrOpcode::kChangeBitToBool: | 26 case IrOpcode::kChangeBitToBool: |
| 27 return ChangeBitToBool(node->InputAt(0), control); | 27 return ChangeBitToBool(node->InputAt(0), control); |
| 28 case IrOpcode::kChangeBoolToBit: | 28 case IrOpcode::kChangeBoolToBit: |
| 29 return ChangeBoolToBit(node->InputAt(0)); | 29 return ChangeBoolToBit(node->InputAt(0)); |
| 30 case IrOpcode::kChangeFloat64ToTagged: | 30 case IrOpcode::kChangeFloat64ToTagged: |
| 31 return ChangeFloat64ToTagged(node->InputAt(0), control); | 31 return ChangeFloat64ToTagged(node->InputAt(0), control); |
| 32 case IrOpcode::kChangeInt31ToTagged: |
| 33 return ChangeInt31ToTagged(node->InputAt(0), control); |
| 32 case IrOpcode::kChangeInt32ToTagged: | 34 case IrOpcode::kChangeInt32ToTagged: |
| 33 return ChangeInt32ToTagged(node->InputAt(0), control); | 35 return ChangeInt32ToTagged(node->InputAt(0), control); |
| 34 case IrOpcode::kChangeSmiToInt32: | 36 case IrOpcode::kChangeSmiToInt32: |
| 35 return ChangeSmiToInt32(node->InputAt(0)); | 37 return ChangeSmiToInt32(node->InputAt(0)); |
| 36 case IrOpcode::kChangeTaggedToFloat64: | 38 case IrOpcode::kChangeTaggedToFloat64: |
| 37 return ChangeTaggedToFloat64(node->InputAt(0), control); | 39 return ChangeTaggedToFloat64(node->InputAt(0), control); |
| 38 case IrOpcode::kChangeTaggedToInt32: | 40 case IrOpcode::kChangeTaggedToInt32: |
| 39 return ChangeTaggedToUI32(node->InputAt(0), control, kSigned); | 41 return ChangeTaggedToUI32(node->InputAt(0), control, kSigned); |
| 40 case IrOpcode::kChangeTaggedToUint32: | 42 case IrOpcode::kChangeTaggedToUint32: |
| 41 return ChangeTaggedToUI32(node->InputAt(0), control, kUnsigned); | 43 return ChangeTaggedToUI32(node->InputAt(0), control, kUnsigned); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 } | 172 } |
| 171 | 173 |
| 172 | 174 |
| 173 Reduction ChangeLowering::ChangeBoolToBit(Node* value) { | 175 Reduction ChangeLowering::ChangeBoolToBit(Node* value) { |
| 174 return Replace(graph()->NewNode(machine()->WordEqual(), value, | 176 return Replace(graph()->NewNode(machine()->WordEqual(), value, |
| 175 jsgraph()->TrueConstant())); | 177 jsgraph()->TrueConstant())); |
| 176 } | 178 } |
| 177 | 179 |
| 178 | 180 |
| 179 Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) { | 181 Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) { |
| 180 Type* const value_type = NodeProperties::GetType(value); | 182 Node* value32 = graph()->NewNode( |
| 181 Node* const value32 = graph()->NewNode( | |
| 182 machine()->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value); | 183 machine()->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value); |
| 183 // TODO(bmeurer): This fast case must be disabled until we kill the asm.js | |
| 184 // support in the generic JavaScript pipeline, because LoadBuffer is lying | |
| 185 // about its result. | |
| 186 // if (value_type->Is(Type::Signed32())) { | |
| 187 // return ChangeInt32ToTagged(value32, control); | |
| 188 // } | |
| 189 Node* check_same = graph()->NewNode( | 184 Node* check_same = graph()->NewNode( |
| 190 machine()->Float64Equal(), value, | 185 machine()->Float64Equal(), value, |
| 191 graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32)); | 186 graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32)); |
| 192 Node* branch_same = graph()->NewNode(common()->Branch(), check_same, control); | 187 Node* branch_same = graph()->NewNode(common()->Branch(), check_same, control); |
| 193 | 188 |
| 194 Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_same); | 189 Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_same); |
| 195 Node* vsmi; | 190 Node* vsmi; |
| 196 Node* if_box = graph()->NewNode(common()->IfFalse(), branch_same); | 191 Node* if_box = graph()->NewNode(common()->IfFalse(), branch_same); |
| 197 Node* vbox; | 192 Node* vbox; |
| 198 | 193 |
| 199 // We only need to check for -0 if the {value} can potentially contain -0. | 194 // Check if {value} is -0. |
| 200 if (value_type->Maybe(Type::MinusZero())) { | 195 Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32, |
| 201 Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32, | 196 jsgraph()->Int32Constant(0)); |
| 202 jsgraph()->Int32Constant(0)); | 197 Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 203 Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), | 198 check_zero, if_smi); |
| 204 check_zero, if_smi); | |
| 205 | 199 |
| 206 Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); | 200 Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); |
| 207 Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero); | 201 Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero); |
| 208 | 202 |
| 209 // In case of 0, we need to check the high bits for the IEEE -0 pattern. | 203 // In case of 0, we need to check the high bits for the IEEE -0 pattern. |
| 210 Node* check_negative = graph()->NewNode( | 204 Node* check_negative = graph()->NewNode( |
| 211 machine()->Int32LessThan(), | 205 machine()->Int32LessThan(), |
| 212 graph()->NewNode(machine()->Float64ExtractHighWord32(), value), | 206 graph()->NewNode(machine()->Float64ExtractHighWord32(), value), |
| 213 jsgraph()->Int32Constant(0)); | 207 jsgraph()->Int32Constant(0)); |
| 214 Node* branch_negative = graph()->NewNode( | 208 Node* branch_negative = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 215 common()->Branch(BranchHint::kFalse), check_negative, if_zero); | 209 check_negative, if_zero); |
| 216 | 210 |
| 217 Node* if_negative = graph()->NewNode(common()->IfTrue(), branch_negative); | 211 Node* if_negative = graph()->NewNode(common()->IfTrue(), branch_negative); |
| 218 Node* if_notnegative = | 212 Node* if_notnegative = graph()->NewNode(common()->IfFalse(), branch_negative); |
| 219 graph()->NewNode(common()->IfFalse(), branch_negative); | |
| 220 | 213 |
| 221 // We need to create a box for negative 0. | 214 // We need to create a box for negative 0. |
| 222 if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative); | 215 if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative); |
| 223 if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative); | 216 if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative); |
| 224 } | |
| 225 | 217 |
| 226 // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit | 218 // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit |
| 227 // machines we need to deal with potential overflow and fallback to boxing. | 219 // machines we need to deal with potential overflow and fallback to boxing. |
| 228 if (machine()->Is64() || value_type->Is(Type::SignedSmall())) { | 220 if (machine()->Is64()) { |
| 229 vsmi = ChangeInt32ToSmi(value32); | 221 vsmi = ChangeInt32ToSmi(value32); |
| 230 } else { | 222 } else { |
| 231 Node* smi_tag = | 223 Node* smi_tag = |
| 232 graph()->NewNode(machine()->Int32AddWithOverflow(), value32, value32); | 224 graph()->NewNode(machine()->Int32AddWithOverflow(), value32, value32); |
| 233 | 225 |
| 234 Node* check_ovf = graph()->NewNode(common()->Projection(1), smi_tag); | 226 Node* check_ovf = graph()->NewNode(common()->Projection(1), smi_tag); |
| 235 Node* branch_ovf = graph()->NewNode(common()->Branch(BranchHint::kFalse), | 227 Node* branch_ovf = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 236 check_ovf, if_smi); | 228 check_ovf, if_smi); |
| 237 | 229 |
| 238 Node* if_ovf = graph()->NewNode(common()->IfTrue(), branch_ovf); | 230 Node* if_ovf = graph()->NewNode(common()->IfTrue(), branch_ovf); |
| 239 if_box = graph()->NewNode(common()->Merge(2), if_ovf, if_box); | 231 if_box = graph()->NewNode(common()->Merge(2), if_ovf, if_box); |
| 240 | 232 |
| 241 if_smi = graph()->NewNode(common()->IfFalse(), branch_ovf); | 233 if_smi = graph()->NewNode(common()->IfFalse(), branch_ovf); |
| 242 vsmi = graph()->NewNode(common()->Projection(0), smi_tag); | 234 vsmi = graph()->NewNode(common()->Projection(0), smi_tag); |
| 243 } | 235 } |
| 244 | 236 |
| 245 // Allocate the box for the {value}. | 237 // Allocate the box for the {value}. |
| 246 vbox = AllocateHeapNumberWithValue(value, if_box); | 238 vbox = AllocateHeapNumberWithValue(value, if_box); |
| 247 | 239 |
| 248 control = graph()->NewNode(common()->Merge(2), if_smi, if_box); | 240 control = graph()->NewNode(common()->Merge(2), if_smi, if_box); |
| 249 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | 241 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
| 250 vsmi, vbox, control); | 242 vsmi, vbox, control); |
| 251 return Replace(value); | 243 return Replace(value); |
| 252 } | 244 } |
| 253 | 245 |
| 246 Reduction ChangeLowering::ChangeInt31ToTagged(Node* value, Node* control) { |
| 247 return Replace(ChangeInt32ToSmi(value)); |
| 248 } |
| 254 | 249 |
| 255 Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) { | 250 Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) { |
| 256 if (machine()->Is64() || | 251 if (machine()->Is64()) { |
| 257 NodeProperties::GetType(value)->Is(Type::SignedSmall())) { | 252 value = ChangeInt32ToSmi(value); |
| 258 return Replace(ChangeInt32ToSmi(value)); | 253 } else { |
| 254 Node* add = |
| 255 graph()->NewNode(machine()->Int32AddWithOverflow(), value, value); |
| 256 |
| 257 Node* ovf = graph()->NewNode(common()->Projection(1), add); |
| 258 Node* branch = |
| 259 graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control); |
| 260 |
| 261 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 262 Node* vtrue = |
| 263 AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), if_true); |
| 264 |
| 265 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 266 Node* vfalse = graph()->NewNode(common()->Projection(0), add); |
| 267 |
| 268 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 269 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
| 270 vtrue, vfalse, control); |
| 259 } | 271 } |
| 260 | 272 return Replace(value); |
| 261 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value); | |
| 262 | |
| 263 Node* ovf = graph()->NewNode(common()->Projection(1), add); | |
| 264 Node* branch = | |
| 265 graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control); | |
| 266 | |
| 267 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
| 268 Node* vtrue = | |
| 269 AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), if_true); | |
| 270 | |
| 271 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
| 272 Node* vfalse = graph()->NewNode(common()->Projection(0), add); | |
| 273 | |
| 274 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
| 275 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | |
| 276 vtrue, vfalse, merge); | |
| 277 | |
| 278 return Replace(phi); | |
| 279 } | 273 } |
| 280 | 274 |
| 281 Reduction ChangeLowering::ChangeSmiToInt32(Node* value) { | 275 Reduction ChangeLowering::ChangeSmiToInt32(Node* value) { |
| 282 return Replace(ChangeSmiToWord32(value)); | 276 return Replace(ChangeSmiToWord32(value)); |
| 283 } | 277 } |
| 284 | 278 |
| 285 Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control, | 279 Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control, |
| 286 Signedness signedness) { | 280 Signedness signedness) { |
| 287 if (NodeProperties::GetType(value)->Is(Type::TaggedSigned())) { | 281 if (NodeProperties::GetType(value)->Is(Type::TaggedSigned())) { |
| 288 return ChangeSmiToInt32(value); | 282 return ChangeSmiToInt32(value); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 Node* merge = graph()->NewNode(common()->Merge(2), if_not_smi, if_smi); | 369 Node* merge = graph()->NewNode(common()->Merge(2), if_not_smi, if_smi); |
| 376 Node* phi = | 370 Node* phi = |
| 377 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | 371 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
| 378 vnot_smi, vfrom_smi, merge); | 372 vnot_smi, vfrom_smi, merge); |
| 379 | 373 |
| 380 return Replace(phi); | 374 return Replace(phi); |
| 381 } | 375 } |
| 382 | 376 |
| 383 | 377 |
| 384 Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) { | 378 Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) { |
| 385 if (NodeProperties::GetType(value)->Is(Type::UnsignedSmall())) { | |
| 386 return Replace(ChangeUint32ToSmi(value)); | |
| 387 } | |
| 388 | |
| 389 Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, | 379 Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, |
| 390 SmiMaxValueConstant()); | 380 SmiMaxValueConstant()); |
| 391 Node* branch = | 381 Node* branch = |
| 392 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 382 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 393 | 383 |
| 394 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 384 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 395 Node* vtrue = ChangeUint32ToSmi(value); | 385 Node* vtrue = ChangeUint32ToSmi(value); |
| 396 | 386 |
| 397 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 387 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 398 Node* vfalse = | 388 Node* vfalse = |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 } | 697 } |
| 708 | 698 |
| 709 | 699 |
| 710 MachineOperatorBuilder* ChangeLowering::machine() const { | 700 MachineOperatorBuilder* ChangeLowering::machine() const { |
| 711 return jsgraph()->machine(); | 701 return jsgraph()->machine(); |
| 712 } | 702 } |
| 713 | 703 |
| 714 } // namespace compiler | 704 } // namespace compiler |
| 715 } // namespace internal | 705 } // namespace internal |
| 716 } // namespace v8 | 706 } // namespace v8 |
| OLD | NEW |