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 |