| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/wasm-compiler.h" | 5 #include "src/compiler/wasm-compiler.h" |
| 6 | 6 |
| 7 #include "src/isolate-inl.h" | 7 #include "src/isolate-inl.h" |
| 8 | 8 |
| 9 #include "src/base/platform/elapsed-timer.h" | 9 #include "src/base/platform/elapsed-timer.h" |
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
| (...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 Binop(wasm::kExprF64Mul, right, Float64Constant(1.0)), | 1132 Binop(wasm::kExprF64Mul, right, Float64Constant(1.0)), |
| 1133 Binop(wasm::kExprF64Mul, left, Float64Constant(1.0))))); | 1133 Binop(wasm::kExprF64Mul, left, Float64Constant(1.0))))); |
| 1134 } | 1134 } |
| 1135 | 1135 |
| 1136 | 1136 |
| 1137 Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input) { | 1137 Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input) { |
| 1138 MachineOperatorBuilder* m = jsgraph()->machine(); | 1138 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1139 if (module_ && module_->asm_js()) { | 1139 if (module_ && module_->asm_js()) { |
| 1140 // asm.js must use the wacky JS semantics. | 1140 // asm.js must use the wacky JS semantics. |
| 1141 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); | 1141 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); |
| 1142 return graph()->NewNode( | 1142 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); |
| 1143 m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); | |
| 1144 } | 1143 } |
| 1145 | 1144 |
| 1146 // Truncation of the input value is needed for the overflow check later. | 1145 // Truncation of the input value is needed for the overflow check later. |
| 1147 Node* trunc = Unop(wasm::kExprF32Trunc, input); | 1146 Node* trunc = Unop(wasm::kExprF32Trunc, input); |
| 1148 Node* result = graph()->NewNode(m->TruncateFloat32ToInt32(), trunc); | 1147 Node* result = graph()->NewNode(m->TruncateFloat32ToInt32(), trunc); |
| 1149 | 1148 |
| 1150 // Convert the result back to f64. If we end up at a different value than the | 1149 // Convert the result back to f64. If we end up at a different value than the |
| 1151 // truncated input value, then there has been an overflow and we trap. | 1150 // truncated input value, then there has been an overflow and we trap. |
| 1152 Node* check = Unop(wasm::kExprF32SConvertI32, result); | 1151 Node* check = Unop(wasm::kExprF32SConvertI32, result); |
| 1153 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); | 1152 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); |
| 1154 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); | 1153 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); |
| 1155 | 1154 |
| 1156 return result; | 1155 return result; |
| 1157 } | 1156 } |
| 1158 | 1157 |
| 1159 | 1158 |
| 1160 Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input) { | 1159 Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input) { |
| 1161 MachineOperatorBuilder* m = jsgraph()->machine(); | 1160 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1162 if (module_ && module_->asm_js()) { | 1161 if (module_ && module_->asm_js()) { |
| 1163 // asm.js must use the wacky JS semantics. | 1162 // asm.js must use the wacky JS semantics. |
| 1164 return graph()->NewNode( | 1163 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); |
| 1165 m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); | |
| 1166 } | 1164 } |
| 1167 // Truncation of the input value is needed for the overflow check later. | 1165 // Truncation of the input value is needed for the overflow check later. |
| 1168 Node* trunc = Unop(wasm::kExprF64Trunc, input); | 1166 Node* trunc = Unop(wasm::kExprF64Trunc, input); |
| 1169 Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), trunc); | 1167 Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), trunc); |
| 1170 | 1168 |
| 1171 // Convert the result back to f64. If we end up at a different value than the | 1169 // Convert the result back to f64. If we end up at a different value than the |
| 1172 // truncated input value, then there has been an overflow and we trap. | 1170 // truncated input value, then there has been an overflow and we trap. |
| 1173 Node* check = Unop(wasm::kExprF64SConvertI32, result); | 1171 Node* check = Unop(wasm::kExprF64SConvertI32, result); |
| 1174 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); | 1172 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); |
| 1175 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); | 1173 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); |
| 1176 | 1174 |
| 1177 return result; | 1175 return result; |
| 1178 } | 1176 } |
| 1179 | 1177 |
| 1180 | 1178 |
| 1181 Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input) { | 1179 Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input) { |
| 1182 MachineOperatorBuilder* m = jsgraph()->machine(); | 1180 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1183 if (module_ && module_->asm_js()) { | 1181 if (module_ && module_->asm_js()) { |
| 1184 // asm.js must use the wacky JS semantics. | 1182 // asm.js must use the wacky JS semantics. |
| 1185 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); | 1183 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); |
| 1186 return graph()->NewNode( | 1184 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); |
| 1187 m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); | |
| 1188 } | 1185 } |
| 1189 | 1186 |
| 1190 // Truncation of the input value is needed for the overflow check later. | 1187 // Truncation of the input value is needed for the overflow check later. |
| 1191 Node* trunc = Unop(wasm::kExprF32Trunc, input); | 1188 Node* trunc = Unop(wasm::kExprF32Trunc, input); |
| 1192 Node* result = graph()->NewNode(m->TruncateFloat32ToUint32(), trunc); | 1189 Node* result = graph()->NewNode(m->TruncateFloat32ToUint32(), trunc); |
| 1193 | 1190 |
| 1194 // Convert the result back to f32. If we end up at a different value than the | 1191 // Convert the result back to f32. If we end up at a different value than the |
| 1195 // truncated input value, then there has been an overflow and we trap. | 1192 // truncated input value, then there has been an overflow and we trap. |
| 1196 Node* check = Unop(wasm::kExprF32UConvertI32, result); | 1193 Node* check = Unop(wasm::kExprF32UConvertI32, result); |
| 1197 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); | 1194 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); |
| 1198 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); | 1195 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); |
| 1199 | 1196 |
| 1200 return result; | 1197 return result; |
| 1201 } | 1198 } |
| 1202 | 1199 |
| 1203 | 1200 |
| 1204 Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input) { | 1201 Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input) { |
| 1205 MachineOperatorBuilder* m = jsgraph()->machine(); | 1202 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1206 if (module_ && module_->asm_js()) { | 1203 if (module_ && module_->asm_js()) { |
| 1207 // asm.js must use the wacky JS semantics. | 1204 // asm.js must use the wacky JS semantics. |
| 1208 return graph()->NewNode( | 1205 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); |
| 1209 m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); | |
| 1210 } | 1206 } |
| 1211 // Truncation of the input value is needed for the overflow check later. | 1207 // Truncation of the input value is needed for the overflow check later. |
| 1212 Node* trunc = Unop(wasm::kExprF64Trunc, input); | 1208 Node* trunc = Unop(wasm::kExprF64Trunc, input); |
| 1213 Node* result = graph()->NewNode(m->TruncateFloat64ToUint32(), trunc); | 1209 Node* result = graph()->NewNode(m->TruncateFloat64ToUint32(), trunc); |
| 1214 | 1210 |
| 1215 // Convert the result back to f64. If we end up at a different value than the | 1211 // Convert the result back to f64. If we end up at a different value than the |
| 1216 // truncated input value, then there has been an overflow and we trap. | 1212 // truncated input value, then there has been an overflow and we trap. |
| 1217 Node* check = Unop(wasm::kExprF64UConvertI32, result); | 1213 Node* check = Unop(wasm::kExprF64UConvertI32, result); |
| 1218 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); | 1214 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); |
| 1219 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); | 1215 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); |
| (...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2000 Node* merge = graph()->NewNode(common->Merge(2), if_true, if_false); | 1996 Node* merge = graph()->NewNode(common->Merge(2), if_true, if_false); |
| 2001 Node* phi = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2), | 1997 Node* phi = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2), |
| 2002 vtrue, vfalse, merge); | 1998 vtrue, vfalse, merge); |
| 2003 return phi; | 1999 return phi; |
| 2004 } | 2000 } |
| 2005 | 2001 |
| 2006 Node* WasmGraphBuilder::BuildChangeFloat64ToTagged(Node* value) { | 2002 Node* WasmGraphBuilder::BuildChangeFloat64ToTagged(Node* value) { |
| 2007 MachineOperatorBuilder* machine = jsgraph()->machine(); | 2003 MachineOperatorBuilder* machine = jsgraph()->machine(); |
| 2008 CommonOperatorBuilder* common = jsgraph()->common(); | 2004 CommonOperatorBuilder* common = jsgraph()->common(); |
| 2009 | 2005 |
| 2010 Node* const value32 = graph()->NewNode( | 2006 Node* value32 = graph()->NewNode(machine->RoundFloat64ToInt32(), value); |
| 2011 machine->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value); | |
| 2012 Node* check_same = graph()->NewNode( | 2007 Node* check_same = graph()->NewNode( |
| 2013 machine->Float64Equal(), value, | 2008 machine->Float64Equal(), value, |
| 2014 graph()->NewNode(machine->ChangeInt32ToFloat64(), value32)); | 2009 graph()->NewNode(machine->ChangeInt32ToFloat64(), value32)); |
| 2015 Node* branch_same = | 2010 Node* branch_same = |
| 2016 graph()->NewNode(common->Branch(), check_same, graph()->start()); | 2011 graph()->NewNode(common->Branch(), check_same, graph()->start()); |
| 2017 | 2012 |
| 2018 Node* if_smi = graph()->NewNode(common->IfTrue(), branch_same); | 2013 Node* if_smi = graph()->NewNode(common->IfTrue(), branch_same); |
| 2019 Node* vsmi; | 2014 Node* vsmi; |
| 2020 Node* if_box = graph()->NewNode(common->IfFalse(), branch_same); | 2015 Node* if_box = graph()->NewNode(common->IfFalse(), branch_same); |
| 2021 Node* vbox; | 2016 Node* vbox; |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 wasm::LocalType type) { | 2227 wasm::LocalType type) { |
| 2233 // Do a JavaScript ToNumber. | 2228 // Do a JavaScript ToNumber. |
| 2234 Node* num = BuildJavaScriptToNumber(node, context, *effect_, *control_); | 2229 Node* num = BuildJavaScriptToNumber(node, context, *effect_, *control_); |
| 2235 | 2230 |
| 2236 // Change representation. | 2231 // Change representation. |
| 2237 SimplifiedOperatorBuilder simplified(jsgraph()->zone()); | 2232 SimplifiedOperatorBuilder simplified(jsgraph()->zone()); |
| 2238 num = BuildChangeTaggedToFloat64(num); | 2233 num = BuildChangeTaggedToFloat64(num); |
| 2239 | 2234 |
| 2240 switch (type) { | 2235 switch (type) { |
| 2241 case wasm::kAstI32: { | 2236 case wasm::kAstI32: { |
| 2242 num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToInt32( | 2237 num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToWord32(), |
| 2243 TruncationMode::kJavaScript), | |
| 2244 num); | 2238 num); |
| 2245 break; | 2239 break; |
| 2246 } | 2240 } |
| 2247 case wasm::kAstI64: | 2241 case wasm::kAstI64: |
| 2248 // TODO(titzer): JS->i64 has no good solution right now. Using 32 bits. | 2242 // TODO(titzer): JS->i64 has no good solution right now. Using 32 bits. |
| 2249 num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToInt32( | 2243 num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToWord32(), |
| 2250 TruncationMode::kJavaScript), | |
| 2251 num); | 2244 num); |
| 2252 if (jsgraph()->machine()->Is64()) { | 2245 if (jsgraph()->machine()->Is64()) { |
| 2253 // We cannot change an int32 to an int64 on a 32 bit platform. Instead | 2246 // We cannot change an int32 to an int64 on a 32 bit platform. Instead |
| 2254 // we will split the parameter node later. | 2247 // we will split the parameter node later. |
| 2255 num = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), num); | 2248 num = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), num); |
| 2256 } | 2249 } |
| 2257 break; | 2250 break; |
| 2258 case wasm::kAstF32: | 2251 case wasm::kAstF32: |
| 2259 num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToFloat32(), | 2252 num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToFloat32(), |
| 2260 num); | 2253 num); |
| (...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2971 // TODO(bradnelson): Improve histogram handling of size_t. | 2964 // TODO(bradnelson): Improve histogram handling of size_t. |
| 2972 isolate->counters()->wasm_compile_function_peak_memory_bytes()->AddSample( | 2965 isolate->counters()->wasm_compile_function_peak_memory_bytes()->AddSample( |
| 2973 static_cast<int>(zone.allocation_size())); | 2966 static_cast<int>(zone.allocation_size())); |
| 2974 return code; | 2967 return code; |
| 2975 } | 2968 } |
| 2976 | 2969 |
| 2977 | 2970 |
| 2978 } // namespace compiler | 2971 } // namespace compiler |
| 2979 } // namespace internal | 2972 } // namespace internal |
| 2980 } // namespace v8 | 2973 } // namespace v8 |
| OLD | NEW |