Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
Inline all SIMD operations and optimize the SIMD arrays load and store.
Browse files Browse the repository at this point in the history
The implementation is for ia32 and x64 ports.

Optimize Float32x4Array, Float64x2Array and Int32x4Array element loading
and storing for ia32 and x64 port by:
  1). Allocating SIMD128 registers
  2). Emitting SIMD movups instruction
  3). Adding deoptimization support for SIMD128 registers or stack slots

Inline all SIMD operations and emit SIMD instructions for ia32 and x64 port

Conflicts:
	src/hydrogen-instructions.cc
	src/hydrogen-instructions.h
	src/ia32/assembler-ia32.h
	src/ia32/deoptimizer-ia32.cc
	src/ia32/lithium-codegen-ia32.cc
	src/ia32/lithium-codegen-ia32.h
	src/ia32/macro-assembler-ia32.cc
	src/x64/assembler-x64.h
	src/x64/lithium-codegen-x64.cc
	src/x64/lithium-x64.h
	src/hydrogen-instructions.cc
	src/hydrogen-instructions.h
	src/hydrogen.cc
	src/ia32/lithium-ia32.cc
	src/x64/lithium-x64.cc
	test/cctest/test-disasm-ia32.cc
  • Loading branch information
fenghaitao authored and huningxin committed Jul 26, 2014
1 parent adeeda9 commit 3c70675
Show file tree
Hide file tree
Showing 52 changed files with 7,429 additions and 463 deletions.
29 changes: 29 additions & 0 deletions src/arm/assembler-arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,34 @@ struct QwNeonRegister {
return r;
}

static int ToAllocationIndex(QwNeonRegister reg) {
ASSERT(reg.code() < kMaxNumRegisters);
return reg.code();
}

static const char* AllocationIndexToString(int index) {
ASSERT(index >= 0 && index < kMaxNumRegisters);
const char* const names[] = {
"q0",
"q1",
"q2",
"q3",
"q4",
"q5",
"q6",
"q7",
"q8",
"q9",
"q10",
"q11",
"q12",
"q13",
"q14",
"q15",
};
return names[index];
}

bool is_valid() const {
return (0 <= code_) && (code_ < kMaxNumRegisters);
}
Expand All @@ -322,6 +350,7 @@ struct QwNeonRegister {


typedef QwNeonRegister QuadRegister;
typedef QwNeonRegister SIMD128Register;


// Support for the VFP registers s0 to s31 (d0 to d15).
Expand Down
18 changes: 15 additions & 3 deletions src/arm/deoptimizer-arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ void Deoptimizer::SetPlatformCompiledStubRegisters(
}


void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
void Deoptimizer::CopySIMD128Registers(FrameDescription* output_frame) {
for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) {
double double_value = input_->GetDoubleRegister(i);
output_frame->SetDoubleRegister(i, double_value);
Expand Down Expand Up @@ -206,7 +206,7 @@ void Deoptimizer::EntryGenerator::Generate() {

// Copy VFP registers to
// double_registers_[DoubleRegister::kMaxNumAllocatableRegisters]
int double_regs_offset = FrameDescription::double_registers_offset();
int double_regs_offset = FrameDescription::simd128_registers_offset();
for (int i = 0; i < DwVfpRegister::kMaxNumAllocatableRegisters; ++i) {
int dst_offset = i * kDoubleSize + double_regs_offset;
int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
Expand Down Expand Up @@ -280,7 +280,7 @@ void Deoptimizer::EntryGenerator::Generate() {
__ CheckFor32DRegs(ip);

__ ldr(r1, MemOperand(r0, Deoptimizer::input_offset()));
int src_offset = FrameDescription::double_registers_offset();
int src_offset = FrameDescription::simd128_registers_offset();
for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) {
if (i == kDoubleRegZero.code()) continue;
if (i == kScratchDoubleReg.code()) continue;
Expand Down Expand Up @@ -352,6 +352,18 @@ void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
}


double FrameDescription::GetDoubleRegister(unsigned n) const {
ASSERT(n < 2 * ARRAY_SIZE(simd128_registers_));
return simd128_registers_[n / 2].d[n % 2];
}


void FrameDescription::SetDoubleRegister(unsigned n, double value) {
ASSERT(n < 2 * ARRAY_SIZE(simd128_registers_));
simd128_registers_[n / 2].d[n % 2] = value;
}


#undef __

} } // namespace v8::internal
35 changes: 35 additions & 0 deletions src/arm/lithium-arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,41 @@ LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
}


LInstruction* LChunkBuilder::DoNullarySIMDOperation(
HNullarySIMDOperation* instr) {
UNIMPLEMENTED();
return NULL;
}


LInstruction* LChunkBuilder::DoUnarySIMDOperation(
HUnarySIMDOperation* instr) {
UNIMPLEMENTED();
return NULL;
}


LInstruction* LChunkBuilder::DoBinarySIMDOperation(
HBinarySIMDOperation* instr) {
UNIMPLEMENTED();
return NULL;
}


LInstruction* LChunkBuilder::DoTernarySIMDOperation(
HTernarySIMDOperation* instr) {
UNIMPLEMENTED();
return NULL;
}


LInstruction* LChunkBuilder::DoQuarternarySIMDOperation(
HQuarternarySIMDOperation* instr) {
UNIMPLEMENTED();
return NULL;
}


LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* constructor = UseFixed(instr->constructor(), r1);
Expand Down
65 changes: 65 additions & 0 deletions src/bootstrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ class Genesis BASE_EMBEDDED {
Handle<Map>* external_map);
bool InstallExperimentalNatives();
void InstallBuiltinFunctionIds();
void InstallExperimentalSIMDBuiltinFunctionIds();
void InstallJSFunctionResultCaches();
void InitializeNormalizedMapCaches();

Expand Down Expand Up @@ -2119,6 +2120,7 @@ bool Genesis::InstallExperimentalNatives() {
if (!CompileExperimentalBuiltin(isolate(), i)) return false;
// Store the map for the float32x4, float64x2 and int32x4 function
// prototype after the float32x4 and int32x4 function has been set up.
InstallExperimentalSIMDBuiltinFunctionIds();
JSObject* float32x4_function_prototype = JSObject::cast(
native_context()->float32x4_function()->instance_prototype());
native_context()->set_float32x4_function_prototype_map(
Expand Down Expand Up @@ -2162,6 +2164,35 @@ static Handle<JSObject> ResolveBuiltinIdHolder(
}


static Handle<JSObject> ResolveBuiltinSIMDIdHolder(
Handle<Context> native_context,
const char* holder_expr) {
Isolate* isolate = native_context->GetIsolate();
Factory* factory = isolate->factory();
Handle<GlobalObject> global(native_context->global_object());
Handle<Object> holder = global;
char* name = const_cast<char*>(holder_expr);
char* period_pos = strchr(name, '.');
while (period_pos != NULL) {
Vector<const char> property(name,
static_cast<int>(period_pos - name));
Handle<String> property_string = factory->InternalizeUtf8String(property);
ASSERT(!property_string.is_null());
holder = Object::GetProperty(holder, property_string).ToHandleChecked();
if (strcmp(".prototype", period_pos) == 0) {
Handle<JSFunction> function = Handle<JSFunction>::cast(holder);
return Handle<JSObject>(JSObject::cast(function->prototype()));
} else {
name = period_pos + 1;
period_pos = strchr(name, '.');
}
}

return Handle<JSObject>::cast(Object::GetPropertyOrElement(
holder, factory->InternalizeUtf8String(name)).ToHandleChecked());
}


static void InstallBuiltinFunctionId(Handle<JSObject> holder,
const char* function_name,
BuiltinFunctionId id) {
Expand Down Expand Up @@ -2196,6 +2227,40 @@ void Genesis::InstallExperimentalBuiltinFunctionIds() {
}


void Genesis::InstallExperimentalSIMDBuiltinFunctionIds() {
HandleScope scope(isolate());
#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
{ \
Handle<JSObject> holder = ResolveBuiltinSIMDIdHolder( \
native_context(), #holder_expr); \
BuiltinFunctionId id = k##name; \
InstallBuiltinFunctionId(holder, #fun_name, id); \
}
SIMD_ARRAY_OPERATIONS(INSTALL_BUILTIN_ID)
#define INSTALL_SIMD_NULLARY_FUNCTION_ID(p1, p2, p3, p4) \
INSTALL_BUILTIN_ID(p1, p2, p3)
SIMD_NULLARY_OPERATIONS(INSTALL_SIMD_NULLARY_FUNCTION_ID)
#undef INSTALL_SIMD_NULLARY_FUNCTION_ID
#define INSTALL_SIMD_UNARY_FUNCTION_ID(p1, p2, p3, p4, p5) \
INSTALL_BUILTIN_ID(p1, p2, p3)
SIMD_UNARY_OPERATIONS(INSTALL_SIMD_UNARY_FUNCTION_ID)
#undef INSTALL_SIMD_UNARY_FUNCTION_ID
#define INSTALL_SIMD_BINARY_FUNCTION_ID(p1, p2, p3, p4, p5, p6) \
INSTALL_BUILTIN_ID(p1, p2, p3)
SIMD_BINARY_OPERATIONS(INSTALL_SIMD_BINARY_FUNCTION_ID)
#undef INSTALL_SIMD_BINARY_FUNCTION_ID
#define INSTALL_SIMD_TERNARY_FUNCTION_ID(p1, p2, p3, p4, p5, p6, p7) \
INSTALL_BUILTIN_ID(p1, p2, p3)
SIMD_TERNARY_OPERATIONS(INSTALL_SIMD_TERNARY_FUNCTION_ID)
#undef INSTALL_SIMD_TERNARY_FUNCTION_ID
#define INSTALL_SIMD_QUARTERNARY_FUNCTION_ID(p1, p2, p3, p4, p5, p6, p7, p8) \
INSTALL_BUILTIN_ID(p1, p2, p3)
SIMD_QUARTERNARY_OPERATIONS(INSTALL_SIMD_QUARTERNARY_FUNCTION_ID)
#undef INSTALL_SIMD_QUARTERNARY_FUNCTION_ID
#undef INSTALL_BUILTIN_ID
}


// Do not forget to update macros.py with named constant
// of cache id.
#define JSFUNCTION_RESULT_CACHE_LIST(F) \
Expand Down
Loading

0 comments on commit 3c70675

Please sign in to comment.