Chromium Code Reviews| Index: src/compiler/wasm-compiler.cc |
| diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc |
| index e7508c26ddffe32340289b2ed64342fb4d809590..60feeee2b319fd22c40e967c8edf33d487997465 100644 |
| --- a/src/compiler/wasm-compiler.cc |
| +++ b/src/compiler/wasm-compiler.cc |
| @@ -23,6 +23,7 @@ |
| #include "src/compiler/machine-operator.h" |
| #include "src/compiler/node-matchers.h" |
| #include "src/compiler/pipeline.h" |
| +#include "src/compiler/simd-lowering.h" |
| #include "src/compiler/source-position.h" |
| #include "src/compiler/zone-pool.h" |
| @@ -611,6 +612,10 @@ Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, Node* right, |
| break; |
| case wasm::kExprF64Mod: |
| return BuildF64Mod(left, right); |
| + case wasm::kExprI32x4ExtractLane: |
| + set_has_simd_ops(true); |
|
titzer
2016/07/08 14:16:03
Can you add a helper method called simd() that ret
gdeepti
2016/07/11 09:50:34
Added simd() helper method, a little fuzzy on what
|
| + return graph()->NewNode(jsgraph()->machine()->Int32x4ExtractLane(), left, |
| + right); |
| case wasm::kExprI32AsmjsDivS: |
| return BuildI32AsmjsDivS(left, right); |
| case wasm::kExprI32AsmjsDivU: |
| @@ -886,6 +891,10 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input, |
| return BuildI64UConvertF64(input, position); |
| case wasm::kExprGrowMemory: |
| return BuildGrowMemory(input); |
| + case wasm::kExprI32x4Splat: |
| + set_has_simd_ops(true); |
| + return graph()->NewNode(jsgraph()->machine()->CreateInt32x4(), input, |
| + input, input, input); |
| case wasm::kExprI32AsmjsLoadMem8S: |
| return BuildAsmjsLoadMem(MachineType::Int8(), input); |
| case wasm::kExprI32AsmjsLoadMem8U: |
| @@ -2248,6 +2257,12 @@ Node* WasmGraphBuilder::ToJS(Node* node, Node* context, wasm::LocalType type) { |
| } |
| } |
| +Node* WasmGraphBuilder::BuildChangeTaggedToInt32(Node* value) { |
| + value = BuildChangeTaggedToFloat64(value); |
| + value = graph()->NewNode(jsgraph()->machine()->ChangeFloat64ToInt32(), value); |
| + return value; |
| +} |
| + |
| Node* WasmGraphBuilder::BuildJavaScriptToNumber(Node* node, Node* context, |
| Node* effect, Node* control) { |
| Callable callable = CodeFactory::ToNumber(jsgraph()->isolate()); |
| @@ -2687,6 +2702,12 @@ Node* WasmGraphBuilder::MemSize(uint32_t offset) { |
| } |
| } |
| +Node* WasmGraphBuilder::DefaultS128Value() { |
| + Node* zero = jsgraph()->Int32Constant(0); |
| + return graph()->NewNode(jsgraph()->machine()->CreateInt32x4(), zero, zero, |
| + zero, zero); |
| +} |
| + |
| Node* WasmGraphBuilder::FunctionTable() { |
| DCHECK(module_ && module_->instance && |
| !module_->instance->function_table.is_null()); |
| @@ -2696,6 +2717,79 @@ Node* WasmGraphBuilder::FunctionTable() { |
| return function_table_; |
| } |
| +Node* WasmGraphBuilder::ChangeToRuntimeCall(Node* node, |
| + Runtime::FunctionId function_id, |
| + const Conversion* signature) { |
| + SimplifiedOperatorBuilder simplified(jsgraph()->zone()); |
| + const Runtime::Function* function = Runtime::FunctionForId(function_id); |
| + CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( |
| + jsgraph()->zone(), function_id, function->nargs, Operator::kNoProperties, |
| + CallDescriptor::kNoFlags); |
| + const int kInputSize = 16; |
| + const int kDefaultFunctionParams = 6; |
| + Node* inputs[kInputSize + kDefaultFunctionParams]; |
| + DCHECK_LE(function->nargs + kDefaultFunctionParams, |
| + static_cast<int>(arraysize(inputs))); |
| + // Either there are control + effect or not. |
|
titzer
2016/07/08 14:16:03
When do runtime calls not have effect and control
gdeepti
2016/07/11 09:50:34
Runtime calls always have effect and control, this
|
| + DCHECK(node->InputCount() == function->nargs || |
| + node->InputCount() == function->nargs + 2); |
| + int index = 0; |
| + inputs[index++] = jsgraph()->CEntryStubConstant(function->result_size); |
| + for (int i = 0; i < function->nargs; ++i) { |
| + Node* arg = node->InputAt(i); |
| + switch (signature[i + 1]) { |
| + case Conversion::kInt32: |
| + arg = BuildChangeInt32ToTagged(arg); |
| + break; |
| + case Conversion::kFloat32: |
| + arg = jsgraph()->graph()->NewNode( |
| + jsgraph()->machine()->ChangeFloat32ToFloat64(), arg); |
| + arg = BuildChangeFloat64ToTagged(arg); |
| + break; |
| + case Conversion::kFloat64: |
| + arg = BuildChangeFloat64ToTagged(arg); |
| + break; |
| + default: |
| + break; |
| + } |
| + inputs[index++] = arg; |
| + } |
| + inputs[index++] = jsgraph()->ExternalConstant( |
| + ExternalReference(function_id, jsgraph()->isolate())); |
| + inputs[index++] = jsgraph()->Int32Constant(function->nargs); |
| + inputs[index++] = jsgraph()->Constant(module_->instance->context); |
| + // Loads and stores have control and effect, others do not and use |
| + // the start node instead. |
| + if (node->InputCount() == function->nargs + 2) { |
| + inputs[index++] = node->InputAt(function->nargs + 1); // effect |
| + inputs[index++] = node->InputAt(function->nargs + 2); // control |
| + } else { |
| + inputs[index++] = jsgraph()->graph()->start(); // effect |
| + inputs[index++] = jsgraph()->graph()->start(); // control |
| + } |
| + Node* ret = jsgraph()->graph()->NewNode(jsgraph()->common()->Call(desc), |
| + index, inputs); |
| + |
| + Conversion return_type = signature[0]; |
| + switch (return_type) { |
| + case Conversion::kInt32: |
| + ret = BuildChangeTaggedToInt32(ret); |
| + break; |
| + case Conversion::kFloat32: |
| + NodeProperties::SetType(ret, Type::Number()); |
| + ret = BuildChangeTaggedToFloat64(ret); |
| + ret = jsgraph()->graph()->NewNode( |
| + jsgraph()->machine()->TruncateInt64ToInt32(), ret); |
| + break; |
| + case Conversion::kFloat64: |
| + ret = BuildChangeTaggedToFloat64(ret); |
| + break; |
| + default: |
| + break; |
| + } |
| + return ret; |
| +} |
| + |
| Node* WasmGraphBuilder::LoadGlobal(uint32_t index) { |
| MachineType mem_type = module_->GetGlobalType(index); |
| Node* addr = jsgraph()->RelocatableIntPtrConstant( |
| @@ -3325,6 +3419,21 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction( |
| } |
| int index = static_cast<int>(function_->func_index); |
| + |
| + // Run lowering pass if SIMD ops are present in the function |
| + if (builder.has_simd_ops()) { |
| + SimdLowering simd(&builder); |
| + GraphReducer graph_reducer(jsgraph_->zone(), graph); |
| + graph_reducer.AddReducer(&simd); |
| + graph_reducer.ReduceGraph(); |
| + |
| + if (FLAG_trace_turbo_graph) { // Simple textual RPO. |
| + OFStream os(stdout); |
| + os << "-- Graph after simd lowering -- " << std::endl; |
| + os << AsRPO(*graph); |
| + } |
| + } |
| + |
| if (index >= FLAG_trace_wasm_ast_start && index < FLAG_trace_wasm_ast_end) { |
| OFStream os(stdout); |
| PrintAst(isolate_->allocator(), body, os, nullptr); |