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

Side by Side Diff: src/compiler/wasm-compiler.cc

Issue 1901063002: [wasm] Copy the tagged-to-int32/float64 and int32/float64-to-tagged code to the wasm compiler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « src/compiler/wasm-compiler.h ('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 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"
11 11
12 #include "src/compiler/access-builder.h" 12 #include "src/compiler/access-builder.h"
13 #include "src/compiler/change-lowering.h"
14 #include "src/compiler/common-operator.h" 13 #include "src/compiler/common-operator.h"
15 #include "src/compiler/diamond.h" 14 #include "src/compiler/diamond.h"
16 #include "src/compiler/graph.h" 15 #include "src/compiler/graph.h"
17 #include "src/compiler/graph-visualizer.h" 16 #include "src/compiler/graph-visualizer.h"
18 #include "src/compiler/instruction-selector.h" 17 #include "src/compiler/instruction-selector.h"
19 #include "src/compiler/int64-lowering.h" 18 #include "src/compiler/int64-lowering.h"
20 #include "src/compiler/js-generic-lowering.h" 19 #include "src/compiler/js-generic-lowering.h"
21 #include "src/compiler/js-graph.h" 20 #include "src/compiler/js-graph.h"
22 #include "src/compiler/js-operator.h" 21 #include "src/compiler/js-operator.h"
23 #include "src/compiler/linkage.h" 22 #include "src/compiler/linkage.h"
24 #include "src/compiler/machine-operator.h" 23 #include "src/compiler/machine-operator.h"
25 #include "src/compiler/node-matchers.h" 24 #include "src/compiler/node-matchers.h"
26 #include "src/compiler/pipeline.h" 25 #include "src/compiler/pipeline.h"
27 #include "src/compiler/simplified-lowering.h"
28 #include "src/compiler/simplified-operator.h"
29 #include "src/compiler/source-position.h" 26 #include "src/compiler/source-position.h"
30 #include "src/compiler/typer.h"
31 27
32 #include "src/code-factory.h" 28 #include "src/code-factory.h"
33 #include "src/code-stubs.h" 29 #include "src/code-stubs.h"
34 #include "src/factory.h" 30 #include "src/factory.h"
35 #include "src/log-inl.h" 31 #include "src/log-inl.h"
36 #include "src/profiler/cpu-profiler.h" 32 #include "src/profiler/cpu-profiler.h"
37 33
38 #include "src/wasm/ast-decoder.h" 34 #include "src/wasm/ast-decoder.h"
39 #include "src/wasm/wasm-module.h" 35 #include "src/wasm/wasm-module.h"
40 #include "src/wasm/wasm-opcodes.h" 36 #include "src/wasm/wasm-opcodes.h"
(...skipping 2026 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 graph()->NewNode(machine->Word32Shl(), key, 2063 graph()->NewNode(machine->Word32Shl(), key,
2068 Int32Constant(kPointerSizeLog2)), 2064 Int32Constant(kPointerSizeLog2)),
2069 Int32Constant(offset)), 2065 Int32Constant(offset)),
2070 *effect_, *control_); 2066 *effect_, *control_);
2071 2067
2072 args[0] = load_code; 2068 args[0] = load_code;
2073 wasm::FunctionSig* sig = module_->GetSignature(index); 2069 wasm::FunctionSig* sig = module_->GetSignature(index);
2074 return BuildWasmCall(sig, args); 2070 return BuildWasmCall(sig, args);
2075 } 2071 }
2076 2072
2073 Node* WasmGraphBuilder::BuildI32Rol(Node* left, Node* right) {
2074 // Implement Rol by Ror since TurboFan does not have Rol opcode.
2075 // TODO(weiliang): support Word32Rol opcode in TurboFan.
2076 Int32Matcher m(right);
2077 if (m.HasValue()) {
2078 return Binop(wasm::kExprI32Ror, left,
2079 jsgraph()->Int32Constant(32 - m.Value()));
2080 } else {
2081 return Binop(wasm::kExprI32Ror, left,
2082 Binop(wasm::kExprI32Sub, jsgraph()->Int32Constant(32), right));
2083 }
2084 }
2085
2086 Node* WasmGraphBuilder::BuildI64Rol(Node* left, Node* right) {
2087 // Implement Rol by Ror since TurboFan does not have Rol opcode.
2088 // TODO(weiliang): support Word64Rol opcode in TurboFan.
2089 Int64Matcher m(right);
2090 if (m.HasValue()) {
2091 return Binop(wasm::kExprI64Ror, left,
2092 jsgraph()->Int64Constant(64 - m.Value()));
2093 } else {
2094 return Binop(wasm::kExprI64Ror, left,
2095 Binop(wasm::kExprI64Sub, jsgraph()->Int64Constant(64), right));
2096 }
2097 }
2098
2099 Node* WasmGraphBuilder::Invert(Node* node) {
2100 return Unop(wasm::kExprI32Eqz, node);
2101 }
2102
2103 Node* WasmGraphBuilder::BuildChangeInt32ToTagged(Node* value) {
2104 MachineOperatorBuilder* machine = jsgraph()->machine();
2105 CommonOperatorBuilder* common = jsgraph()->common();
2106
2107 if (machine->Is64()) {
2108 return BuildChangeInt32ToSmi(value);
2109 }
2110
2111 Node* add = graph()->NewNode(machine->Int32AddWithOverflow(), value, value);
2112
2113 Node* ovf = graph()->NewNode(common->Projection(1), add);
2114 Node* branch = graph()->NewNode(common->Branch(BranchHint::kFalse), ovf,
2115 graph()->start());
2116
2117 Node* if_true = graph()->NewNode(common->IfTrue(), branch);
2118 Node* vtrue = BuildAllocateHeapNumberWithValue(
2119 graph()->NewNode(machine->ChangeInt32ToFloat64(), value), if_true);
2120
2121 Node* if_false = graph()->NewNode(common->IfFalse(), branch);
2122 Node* vfalse = graph()->NewNode(common->Projection(0), add);
2123
2124 Node* merge = graph()->NewNode(common->Merge(2), if_true, if_false);
2125 Node* phi = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2),
2126 vtrue, vfalse, merge);
2127 return phi;
2128 }
2129
2130 Node* WasmGraphBuilder::BuildChangeFloat64ToTagged(Node* value) {
2131 MachineOperatorBuilder* machine = jsgraph()->machine();
2132 CommonOperatorBuilder* common = jsgraph()->common();
2133
2134 Node* const value32 = graph()->NewNode(
2135 machine->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value);
2136 Node* check_same = graph()->NewNode(
2137 machine->Float64Equal(), value,
2138 graph()->NewNode(machine->ChangeInt32ToFloat64(), value32));
2139 Node* branch_same =
2140 graph()->NewNode(common->Branch(), check_same, graph()->start());
2141
2142 Node* if_smi = graph()->NewNode(common->IfTrue(), branch_same);
2143 Node* vsmi;
2144 Node* if_box = graph()->NewNode(common->IfFalse(), branch_same);
2145 Node* vbox;
2146
2147 // We only need to check for -0 if the {value} can potentially contain -0.
2148 Node* check_zero = graph()->NewNode(machine->Word32Equal(), value32,
2149 jsgraph()->Int32Constant(0));
2150 Node* branch_zero =
2151 graph()->NewNode(common->Branch(BranchHint::kFalse), check_zero, if_smi);
2152
2153 Node* if_zero = graph()->NewNode(common->IfTrue(), branch_zero);
2154 Node* if_notzero = graph()->NewNode(common->IfFalse(), branch_zero);
2155
2156 // In case of 0, we need to check the high bits for the IEEE -0 pattern.
2157 Node* check_negative = graph()->NewNode(
2158 machine->Int32LessThan(),
2159 graph()->NewNode(machine->Float64ExtractHighWord32(), value),
2160 jsgraph()->Int32Constant(0));
2161 Node* branch_negative = graph()->NewNode(common->Branch(BranchHint::kFalse),
2162 check_negative, if_zero);
2163
2164 Node* if_negative = graph()->NewNode(common->IfTrue(), branch_negative);
2165 Node* if_notnegative = graph()->NewNode(common->IfFalse(), branch_negative);
2166
2167 // We need to create a box for negative 0.
2168 if_smi = graph()->NewNode(common->Merge(2), if_notzero, if_notnegative);
2169 if_box = graph()->NewNode(common->Merge(2), if_box, if_negative);
2170
2171 // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit
2172 // machines we need to deal with potential overflow and fallback to boxing.
2173 if (machine->Is64()) {
2174 vsmi = BuildChangeInt32ToSmi(value32);
2175 } else {
2176 Node* smi_tag =
2177 graph()->NewNode(machine->Int32AddWithOverflow(), value32, value32);
2178
2179 Node* check_ovf = graph()->NewNode(common->Projection(1), smi_tag);
2180 Node* branch_ovf =
2181 graph()->NewNode(common->Branch(BranchHint::kFalse), check_ovf, if_smi);
2182
2183 Node* if_ovf = graph()->NewNode(common->IfTrue(), branch_ovf);
2184 if_box = graph()->NewNode(common->Merge(2), if_ovf, if_box);
2185
2186 if_smi = graph()->NewNode(common->IfFalse(), branch_ovf);
2187 vsmi = graph()->NewNode(common->Projection(0), smi_tag);
2188 }
2189
2190 // Allocate the box for the {value}.
2191 vbox = BuildAllocateHeapNumberWithValue(value, if_box);
2192
2193 Node* control = graph()->NewNode(common->Merge(2), if_smi, if_box);
2194 value = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2), vsmi,
2195 vbox, control);
2196 return value;
2197 }
2077 2198
2078 Node* WasmGraphBuilder::ToJS(Node* node, Node* context, wasm::LocalType type) { 2199 Node* WasmGraphBuilder::ToJS(Node* node, Node* context, wasm::LocalType type) {
2079 SimplifiedOperatorBuilder simplified(jsgraph()->zone());
2080 switch (type) { 2200 switch (type) {
2081 case wasm::kAstI32: 2201 case wasm::kAstI32:
2082 return graph()->NewNode(simplified.ChangeInt32ToTagged(), node); 2202 return BuildChangeInt32ToTagged(node);
2083 case wasm::kAstI64: 2203 case wasm::kAstI64:
2084 // TODO(titzer): i64->JS has no good solution right now. Using lower 32 2204 // TODO(titzer): i64->JS has no good solution right now. Using lower 32
2085 // bits. 2205 // bits.
2086 node = 2206 node =
2087 graph()->NewNode(jsgraph()->machine()->TruncateInt64ToInt32(), node); 2207 graph()->NewNode(jsgraph()->machine()->TruncateInt64ToInt32(), node);
2088 return graph()->NewNode(simplified.ChangeInt32ToTagged(), node); 2208 return BuildChangeInt32ToTagged(node);
2089 case wasm::kAstF32: 2209 case wasm::kAstF32:
2090 node = graph()->NewNode(jsgraph()->machine()->ChangeFloat32ToFloat64(), 2210 node = graph()->NewNode(jsgraph()->machine()->ChangeFloat32ToFloat64(),
2091 node); 2211 node);
2092 return graph()->NewNode(simplified.ChangeFloat64ToTagged(), node); 2212 return BuildChangeFloat64ToTagged(node);
2093 case wasm::kAstF64: 2213 case wasm::kAstF64:
2094 return graph()->NewNode(simplified.ChangeFloat64ToTagged(), node); 2214 return BuildChangeFloat64ToTagged(node);
2095 case wasm::kAstStmt: 2215 case wasm::kAstStmt:
2096 return jsgraph()->UndefinedConstant(); 2216 return jsgraph()->UndefinedConstant();
2097 default: 2217 default:
2098 UNREACHABLE(); 2218 UNREACHABLE();
2099 return nullptr; 2219 return nullptr;
2100 } 2220 }
2101 } 2221 }
2102 2222
2103 Node* WasmGraphBuilder::BuildJavaScriptToNumber(Node* node, Node* context, 2223 Node* WasmGraphBuilder::BuildJavaScriptToNumber(Node* node, Node* context,
2104 Node* effect, Node* control) { 2224 Node* effect, Node* control) {
2105 Callable callable = CodeFactory::ToNumber(jsgraph()->isolate()); 2225 Callable callable = CodeFactory::ToNumber(jsgraph()->isolate());
2106 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 2226 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
2107 jsgraph()->isolate(), jsgraph()->zone(), callable.descriptor(), 0, 2227 jsgraph()->isolate(), jsgraph()->zone(), callable.descriptor(), 0,
2108 CallDescriptor::kNoFlags, Operator::kNoProperties); 2228 CallDescriptor::kNoFlags, Operator::kNoProperties);
2109 Node* stub_code = jsgraph()->HeapConstant(callable.code()); 2229 Node* stub_code = jsgraph()->HeapConstant(callable.code());
2110 2230
2111 Node* result = graph()->NewNode(jsgraph()->common()->Call(desc), stub_code, 2231 Node* result = graph()->NewNode(jsgraph()->common()->Call(desc), stub_code,
2112 node, context, effect, control); 2232 node, context, effect, control);
2113 2233
2114 *control_ = result; 2234 *control_ = result;
2115 *effect_ = result; 2235 *effect_ = result;
2116 2236
2117 return result; 2237 return result;
2118 } 2238 }
2119 2239
2240 bool CanCover(Node* value, IrOpcode::Value opcode) {
2241 if (value->opcode() != opcode) return false;
2242 bool first = true;
2243 for (Edge const edge : value->use_edges()) {
2244 if (NodeProperties::IsControlEdge(edge)) continue;
2245 if (NodeProperties::IsEffectEdge(edge)) continue;
2246 DCHECK(NodeProperties::IsValueEdge(edge));
2247 if (!first) return false;
2248 first = false;
2249 }
2250 return true;
2251 }
2252
2253 Node* WasmGraphBuilder::BuildChangeTaggedToFloat64(Node* value) {
2254 MachineOperatorBuilder* machine = jsgraph()->machine();
2255 CommonOperatorBuilder* common = jsgraph()->common();
2256
2257 if (CanCover(value, IrOpcode::kJSToNumber)) {
2258 // ChangeTaggedToFloat64(JSToNumber(x)) =>
2259 // if IsSmi(x) then ChangeSmiToFloat64(x)
2260 // else let y = JSToNumber(x) in
2261 // if IsSmi(y) then ChangeSmiToFloat64(y)
2262 // else BuildLoadHeapNumberValue(y)
2263 Node* object = NodeProperties::GetValueInput(value, 0);
2264 Node* context = NodeProperties::GetContextInput(value);
2265 Node* frame_state = NodeProperties::GetFrameStateInput(value, 0);
2266 Node* effect = NodeProperties::GetEffectInput(value);
2267 Node* control = NodeProperties::GetControlInput(value);
2268
2269 const Operator* merge_op = common->Merge(2);
2270 const Operator* ephi_op = common->EffectPhi(2);
2271 const Operator* phi_op = common->Phi(MachineRepresentation::kFloat64, 2);
2272
2273 Node* check1 = BuildTestNotSmi(object);
2274 Node* branch1 =
2275 graph()->NewNode(common->Branch(BranchHint::kFalse), check1, control);
2276
2277 Node* if_true1 = graph()->NewNode(common->IfTrue(), branch1);
2278 Node* vtrue1 = graph()->NewNode(value->op(), object, context, frame_state,
2279 effect, if_true1);
2280 Node* etrue1 = vtrue1;
2281
2282 Node* check2 = BuildTestNotSmi(vtrue1);
2283 Node* branch2 = graph()->NewNode(common->Branch(), check2, if_true1);
2284
2285 Node* if_true2 = graph()->NewNode(common->IfTrue(), branch2);
2286 Node* vtrue2 = BuildLoadHeapNumberValue(vtrue1, if_true2);
2287
2288 Node* if_false2 = graph()->NewNode(common->IfFalse(), branch2);
2289 Node* vfalse2 = BuildChangeSmiToFloat64(vtrue1);
2290
2291 if_true1 = graph()->NewNode(merge_op, if_true2, if_false2);
2292 vtrue1 = graph()->NewNode(phi_op, vtrue2, vfalse2, if_true1);
2293
2294 Node* if_false1 = graph()->NewNode(common->IfFalse(), branch1);
2295 Node* vfalse1 = BuildChangeSmiToFloat64(object);
2296 Node* efalse1 = effect;
2297
2298 Node* merge1 = graph()->NewNode(merge_op, if_true1, if_false1);
2299 Node* ephi1 = graph()->NewNode(ephi_op, etrue1, efalse1, merge1);
2300 Node* phi1 = graph()->NewNode(phi_op, vtrue1, vfalse1, merge1);
2301
2302 // Wire the new diamond into the graph, {JSToNumber} can still throw.
2303 NodeProperties::ReplaceUses(value, phi1, ephi1, etrue1, etrue1);
2304
2305 // TODO(mstarzinger): This iteration cuts out the IfSuccess projection from
2306 // the node and places it inside the diamond. Come up with a helper method!
2307 for (Node* use : etrue1->uses()) {
2308 if (use->opcode() == IrOpcode::kIfSuccess) {
2309 use->ReplaceUses(merge1);
2310 NodeProperties::ReplaceControlInput(branch2, use);
2311 }
2312 }
2313 return phi1;
2314 }
2315
2316 Node* check = BuildTestNotSmi(value);
2317 Node* branch = graph()->NewNode(common->Branch(BranchHint::kFalse), check,
2318 graph()->start());
2319
2320 Node* if_not_smi = graph()->NewNode(common->IfTrue(), branch);
2321
2322 Node* vnot_smi;
2323 Node* check_undefined = graph()->NewNode(machine->WordEqual(), value,
2324 jsgraph()->UndefinedConstant());
2325 Node* branch_undefined = graph()->NewNode(common->Branch(BranchHint::kFalse),
2326 check_undefined, if_not_smi);
2327
2328 Node* if_undefined = graph()->NewNode(common->IfTrue(), branch_undefined);
2329 Node* vundefined =
2330 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN());
2331
2332 Node* if_not_undefined =
2333 graph()->NewNode(common->IfFalse(), branch_undefined);
2334 Node* vheap_number = BuildLoadHeapNumberValue(value, if_not_undefined);
2335
2336 if_not_smi =
2337 graph()->NewNode(common->Merge(2), if_undefined, if_not_undefined);
2338 vnot_smi = graph()->NewNode(common->Phi(MachineRepresentation::kFloat64, 2),
2339 vundefined, vheap_number, if_not_smi);
2340
2341 Node* if_smi = graph()->NewNode(common->IfFalse(), branch);
2342 Node* vfrom_smi = BuildChangeSmiToFloat64(value);
2343
2344 Node* merge = graph()->NewNode(common->Merge(2), if_not_smi, if_smi);
2345 Node* phi = graph()->NewNode(common->Phi(MachineRepresentation::kFloat64, 2),
2346 vnot_smi, vfrom_smi, merge);
2347
2348 return phi;
2349 }
2350
2120 Node* WasmGraphBuilder::FromJS(Node* node, Node* context, 2351 Node* WasmGraphBuilder::FromJS(Node* node, Node* context,
2121 wasm::LocalType type) { 2352 wasm::LocalType type) {
2122 // Do a JavaScript ToNumber. 2353 // Do a JavaScript ToNumber.
2123 Node* num = BuildJavaScriptToNumber(node, context, *effect_, *control_); 2354 Node* num = BuildJavaScriptToNumber(node, context, *effect_, *control_);
2124 2355
2125 // Change representation. 2356 // Change representation.
2126 SimplifiedOperatorBuilder simplified(jsgraph()->zone()); 2357 SimplifiedOperatorBuilder simplified(jsgraph()->zone());
2127 num = graph()->NewNode(simplified.ChangeTaggedToFloat64(), num); 2358 num = BuildChangeTaggedToFloat64(num);
2128 2359
2129 switch (type) { 2360 switch (type) {
2130 case wasm::kAstI32: { 2361 case wasm::kAstI32: {
2131 num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToInt32( 2362 num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToInt32(
2132 TruncationMode::kJavaScript), 2363 TruncationMode::kJavaScript),
2133 num); 2364 num);
2134 break; 2365 break;
2135 } 2366 }
2136 case wasm::kAstI64: 2367 case wasm::kAstI64:
2137 // TODO(titzer): JS->i64 has no good solution right now. Using 32 bits. 2368 // TODO(titzer): JS->i64 has no good solution right now. Using 32 bits.
(...skipping 11 matching lines...) Expand all
2149 case wasm::kAstStmt: 2380 case wasm::kAstStmt:
2150 num = jsgraph()->Int32Constant(0); 2381 num = jsgraph()->Int32Constant(0);
2151 break; 2382 break;
2152 default: 2383 default:
2153 UNREACHABLE(); 2384 UNREACHABLE();
2154 return nullptr; 2385 return nullptr;
2155 } 2386 }
2156 return num; 2387 return num;
2157 } 2388 }
2158 2389
2159 Node* WasmGraphBuilder::BuildI32Rol(Node* left, Node* right) { 2390 Node* WasmGraphBuilder::BuildChangeInt32ToSmi(Node* value) {
2160 // Implement Rol by Ror since TurboFan does not have Rol opcode. 2391 if (jsgraph()->machine()->Is64()) {
2161 // TODO(weiliang): support Word32Rol opcode in TurboFan. 2392 value = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), value);
2162 Int32Matcher m(right);
2163 if (m.HasValue()) {
2164 return Binop(wasm::kExprI32Ror, left,
2165 jsgraph()->Int32Constant(32 - m.Value()));
2166 } else {
2167 return Binop(wasm::kExprI32Ror, left,
2168 Binop(wasm::kExprI32Sub, jsgraph()->Int32Constant(32), right));
2169 } 2393 }
2394 return graph()->NewNode(jsgraph()->machine()->WordShl(), value,
2395 BuildSmiShiftBitsConstant());
2170 } 2396 }
2171 2397
2172 Node* WasmGraphBuilder::BuildI64Rol(Node* left, Node* right) { 2398 Node* WasmGraphBuilder::BuildChangeSmiToInt32(Node* value) {
2173 // Implement Rol by Ror since TurboFan does not have Rol opcode. 2399 value = graph()->NewNode(jsgraph()->machine()->WordSar(), value,
2174 // TODO(weiliang): support Word64Rol opcode in TurboFan. 2400 BuildSmiShiftBitsConstant());
2175 Int64Matcher m(right); 2401 if (jsgraph()->machine()->Is64()) {
2176 if (m.HasValue()) { 2402 value =
2177 return Binop(wasm::kExprI64Ror, left, 2403 graph()->NewNode(jsgraph()->machine()->TruncateInt64ToInt32(), value);
2178 jsgraph()->Int64Constant(64 - m.Value()));
2179 } else {
2180 return Binop(wasm::kExprI64Ror, left,
2181 Binop(wasm::kExprI64Sub, jsgraph()->Int64Constant(64), right));
2182 } 2404 }
2405 return value;
2183 } 2406 }
2184 2407
2185 Node* WasmGraphBuilder::Invert(Node* node) { 2408 Node* WasmGraphBuilder::BuildChangeSmiToFloat64(Node* value) {
2186 return Unop(wasm::kExprI32Eqz, node); 2409 return graph()->NewNode(jsgraph()->machine()->ChangeInt32ToFloat64(),
2410 BuildChangeSmiToInt32(value));
2187 } 2411 }
2188 2412
2413 Node* WasmGraphBuilder::BuildTestNotSmi(Node* value) {
2414 STATIC_ASSERT(kSmiTag == 0);
2415 STATIC_ASSERT(kSmiTagMask == 1);
2416 return graph()->NewNode(jsgraph()->machine()->WordAnd(), value,
2417 jsgraph()->IntPtrConstant(kSmiTagMask));
2418 }
2419
2420 Node* WasmGraphBuilder::BuildSmiShiftBitsConstant() {
2421 return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize);
2422 }
2423
2424 Node* WasmGraphBuilder::BuildAllocateHeapNumberWithValue(Node* value,
2425 Node* control) {
2426 MachineOperatorBuilder* machine = jsgraph()->machine();
2427 CommonOperatorBuilder* common = jsgraph()->common();
2428 // The AllocateHeapNumberStub does not use the context, so we can safely pass
2429 // in Smi zero here.
2430 Callable callable = CodeFactory::AllocateHeapNumber(jsgraph()->isolate());
2431 Node* target = jsgraph()->HeapConstant(callable.code());
2432 Node* context = jsgraph()->NoContextConstant();
2433 Node* effect = graph()->NewNode(common->BeginRegion(), graph()->start());
2434 if (!allocate_heap_number_operator_.is_set()) {
2435 CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
2436 jsgraph()->isolate(), jsgraph()->zone(), callable.descriptor(), 0,
2437 CallDescriptor::kNoFlags, Operator::kNoThrow);
2438 allocate_heap_number_operator_.set(common->Call(descriptor));
2439 }
2440 Node* heap_number = graph()->NewNode(allocate_heap_number_operator_.get(),
2441 target, context, effect, control);
2442 Node* store =
2443 graph()->NewNode(machine->Store(StoreRepresentation(
2444 MachineRepresentation::kFloat64, kNoWriteBarrier)),
2445 heap_number, BuildHeapNumberValueIndexConstant(), value,
2446 heap_number, control);
2447 return graph()->NewNode(common->FinishRegion(), heap_number, store);
2448 }
2449
2450 Node* WasmGraphBuilder::BuildLoadHeapNumberValue(Node* value, Node* control) {
2451 return graph()->NewNode(jsgraph()->machine()->Load(MachineType::Float64()),
2452 value, BuildHeapNumberValueIndexConstant(),
2453 graph()->start(), control);
2454 }
2455
2456 Node* WasmGraphBuilder::BuildHeapNumberValueIndexConstant() {
2457 return jsgraph()->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag);
2458 }
2189 2459
2190 void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code, 2460 void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code,
2191 wasm::FunctionSig* sig) { 2461 wasm::FunctionSig* sig) {
2192 int params = static_cast<int>(sig->parameter_count()); 2462 int params = static_cast<int>(sig->parameter_count());
2193 int count = params + 3; 2463 int count = params + 3;
2194 Node** args = Buffer(count); 2464 Node** args = Buffer(count);
2195 2465
2196 // Build the start and the JS parameter nodes. 2466 // Build the start and the JS parameter nodes.
2197 Node* start = Start(params + 5); 2467 Node* start = Start(params + 5);
2198 *control_ = start; 2468 *control_ = start;
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
2529 WasmGraphBuilder builder(&zone, &jsgraph, func->sig); 2799 WasmGraphBuilder builder(&zone, &jsgraph, func->sig);
2530 builder.set_control_ptr(&control); 2800 builder.set_control_ptr(&control);
2531 builder.set_effect_ptr(&effect); 2801 builder.set_effect_ptr(&effect);
2532 builder.set_module(module); 2802 builder.set_module(module);
2533 builder.BuildJSToWasmWrapper(wasm_code, func->sig); 2803 builder.BuildJSToWasmWrapper(wasm_code, func->sig);
2534 2804
2535 //---------------------------------------------------------------------------- 2805 //----------------------------------------------------------------------------
2536 // Run the compilation pipeline. 2806 // Run the compilation pipeline.
2537 //---------------------------------------------------------------------------- 2807 //----------------------------------------------------------------------------
2538 { 2808 {
2539 // Changes lowering requires types.
2540 Typer typer(isolate, &graph);
2541 NodeVector roots(&zone);
2542 jsgraph.GetCachedNodes(&roots);
2543 typer.Run(roots);
2544
2545 // Run generic and change lowering.
2546 ChangeLowering changes(&jsgraph);
2547 GraphReducer graph_reducer(&zone, &graph, jsgraph.Dead());
2548 graph_reducer.AddReducer(&changes);
2549 graph_reducer.ReduceGraph();
2550
2551 if (FLAG_trace_turbo_graph) { // Simple textual RPO. 2809 if (FLAG_trace_turbo_graph) { // Simple textual RPO.
2552 OFStream os(stdout); 2810 OFStream os(stdout);
2553 os << "-- Graph after change lowering -- " << std::endl; 2811 os << "-- Graph after change lowering -- " << std::endl;
2554 os << AsRPO(graph); 2812 os << AsRPO(graph);
2555 } 2813 }
2556 2814
2557 // Schedule and compile to machine code. 2815 // Schedule and compile to machine code.
2558 int params = static_cast<int>( 2816 int params = static_cast<int>(
2559 module->GetFunctionSignature(index)->parameter_count()); 2817 module->GetFunctionSignature(index)->parameter_count());
2560 CallDescriptor* incoming = Linkage::GetJSCallDescriptor( 2818 CallDescriptor* incoming = Linkage::GetJSCallDescriptor(
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2616 Node* effect = nullptr; 2874 Node* effect = nullptr;
2617 2875
2618 WasmGraphBuilder builder(&zone, &jsgraph, sig); 2876 WasmGraphBuilder builder(&zone, &jsgraph, sig);
2619 builder.set_control_ptr(&control); 2877 builder.set_control_ptr(&control);
2620 builder.set_effect_ptr(&effect); 2878 builder.set_effect_ptr(&effect);
2621 builder.set_module(module); 2879 builder.set_module(module);
2622 builder.BuildWasmToJSWrapper(function, sig); 2880 builder.BuildWasmToJSWrapper(function, sig);
2623 2881
2624 Handle<Code> code = Handle<Code>::null(); 2882 Handle<Code> code = Handle<Code>::null();
2625 { 2883 {
2626 // Changes lowering requires types.
2627 Typer typer(isolate, &graph);
2628 NodeVector roots(&zone);
2629 jsgraph.GetCachedNodes(&roots);
2630 typer.Run(roots);
2631
2632 // Run generic and change lowering.
2633 ChangeLowering changes(&jsgraph);
2634 GraphReducer graph_reducer(&zone, &graph, jsgraph.Dead());
2635 graph_reducer.AddReducer(&changes);
2636 graph_reducer.ReduceGraph();
2637
2638 if (FLAG_trace_turbo_graph) { // Simple textual RPO. 2884 if (FLAG_trace_turbo_graph) { // Simple textual RPO.
2639 OFStream os(stdout); 2885 OFStream os(stdout);
2640 os << "-- Graph after change lowering -- " << std::endl; 2886 os << "-- Graph after change lowering -- " << std::endl;
2641 os << AsRPO(graph); 2887 os << AsRPO(graph);
2642 } 2888 }
2643 2889
2644 // Schedule and compile to machine code. 2890 // Schedule and compile to machine code.
2645 CallDescriptor* incoming = 2891 CallDescriptor* incoming =
2646 wasm::ModuleEnv::GetWasmCallDescriptor(&zone, sig); 2892 wasm::ModuleEnv::GetWasmCallDescriptor(&zone, sig);
2647 Code::Flags flags = Code::ComputeFlags(Code::WASM_TO_JS_FUNCTION); 2893 Code::Flags flags = Code::ComputeFlags(Code::WASM_TO_JS_FUNCTION);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
2791 // TODO(bradnelson): Improve histogram handling of size_t. 3037 // TODO(bradnelson): Improve histogram handling of size_t.
2792 isolate->counters()->wasm_compile_function_peak_memory_bytes()->AddSample( 3038 isolate->counters()->wasm_compile_function_peak_memory_bytes()->AddSample(
2793 static_cast<int>(zone.allocation_size())); 3039 static_cast<int>(zone.allocation_size()));
2794 return code; 3040 return code;
2795 } 3041 }
2796 3042
2797 3043
2798 } // namespace compiler 3044 } // namespace compiler
2799 } // namespace internal 3045 } // namespace internal
2800 } // namespace v8 3046 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698