Reviewers: Benedikt Meurer, Jakob,

Message:
Hi all,

Thanks a lot for review.

As we discussed, I put the atom-specific tuning after ATOM flag.

Could you please have a look?

Thanks
-Weiliang

Description:
x86: avoid memory form of PUSH/CALL for ATOM

BUG=

Please review this at https://codereview.chromium.org/853703002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+54, -13 lines):
  M src/base/cpu.h
  M src/base/cpu.cc
  M src/compiler/ia32/code-generator-ia32.cc
  M src/compiler/ia32/instruction-selector-ia32.cc
  M src/compiler/x64/instruction-selector-x64.cc
  M src/flag-definitions.h
  M src/globals.h
  M src/ia32/assembler-ia32.cc
  M src/x64/assembler-x64.cc
  M src/x64/macro-assembler-x64.cc


Index: src/base/cpu.cc
diff --git a/src/base/cpu.cc b/src/base/cpu.cc
index 56e1c4633c6e28edbfc9b1e17bf3f0c67ffcd5df..63df603dec699572408bd7b1733aa948f3161510 100644
--- a/src/base/cpu.cc
+++ b/src/base/cpu.cc
@@ -312,6 +312,7 @@ CPU::CPU()
       has_ssse3_(false),
       has_sse41_(false),
       has_sse42_(false),
+      is_atom_(false),
       has_avx_(false),
       has_fma3_(false),
       has_idiva_(false),
@@ -362,6 +363,20 @@ CPU::CPU()
     has_sse42_ = (cpu_info[2] & 0x00100000) != 0;
     has_avx_ = (cpu_info[2] & 0x10000000) != 0;
     if (has_avx_) has_fma3_ = (cpu_info[2] & 0x00001000) != 0;
+
+    if (family_ == 0x6) {
+      switch (model_) {
+        case 0x1c:  // SLT
+        case 0x26:
+        case 0x36:
+        case 0x27:
+        case 0x35:
+        case 0x37:  // SLM
+        case 0x4a:
+        case 0x4d:
+          is_atom_ = true;
+      }
+    }
   }

 #if V8_HOST_ARCH_IA32
Index: src/base/cpu.h
diff --git a/src/base/cpu.h b/src/base/cpu.h
index 8c41f9d77a776739d5643bf317e6c3c6233a5a0e..081df9806109c4eff5d8e196e642504ddea24b50 100644
--- a/src/base/cpu.h
+++ b/src/base/cpu.h
@@ -72,6 +72,7 @@ class CPU FINAL {
   bool has_sse42() const { return has_sse42_; }
   bool has_avx() const { return has_avx_; }
   bool has_fma3() const { return has_fma3_; }
+  bool is_atom() const { return is_atom_; }

   // arm features
   bool has_idiva() const { return has_idiva_; }
@@ -106,6 +107,7 @@ class CPU FINAL {
   bool has_ssse3_;
   bool has_sse41_;
   bool has_sse42_;
+  bool is_atom_;
   bool has_avx_;
   bool has_fma3_;
   bool has_idiva_;
Index: src/compiler/ia32/code-generator-ia32.cc
diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc index ad6a51d0f0b988f3d437a006bc8a562fde83c6f7..8b6c303ca7834faa4936956e3b2ff749c8031c2a 100644
--- a/src/compiler/ia32/code-generator-ia32.cc
+++ b/src/compiler/ia32/code-generator-ia32.cc
@@ -292,7 +292,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         __ call(code, RelocInfo::CODE_TARGET);
       } else {
         Register reg = i.InputRegister(0);
-        __ call(Operand(reg, Code::kHeaderSize - kHeapObjectTag));
+        if (CpuFeatures::IsSupported(ATOM)) {
+          __ mov(ebx, Operand(reg, Code::kHeaderSize - kHeapObjectTag));
+          __ call(ebx);
+        } else {
+          __ call(Operand(reg, Code::kHeaderSize - kHeapObjectTag));
+        }
       }
       AddSafepointAndDeopt(instr);
       break;
@@ -305,7 +310,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
         __ Assert(equal, kWrongFunctionContext);
       }
-      __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
+      if (CpuFeatures::IsSupported(ATOM)) {
+        __ mov(ebx, FieldOperand(func, JSFunction::kCodeEntryOffset));
+        __ call(ebx);
+      } else {
+        __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
+      }
       AddSafepointAndDeopt(instr);
       break;
     }
Index: src/compiler/ia32/instruction-selector-ia32.cc
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc index e237ebf693952bee46be9e82011daa129e7d2e50..e9224831c17b812dbf808d0bb43740109ace1253 100644
--- a/src/compiler/ia32/instruction-selector-ia32.cc
+++ b/src/compiler/ia32/instruction-selector-ia32.cc
@@ -737,8 +737,11 @@ void InstructionSelector::VisitCall(Node* node) {
   for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
        input != buffer.pushed_nodes.rend(); input++) {
     // TODO(titzer): handle pushing double parameters.
-    Emit(kIA32Push, NULL,
- g.CanBeImmediate(*input) ? g.UseImmediate(*input) : g.Use(*input));
+    InstructionOperand* value =
+        g.CanBeImmediate(*input)
+            ? g.UseImmediate(*input)
+            : IsSupported(ATOM) ? g.UseRegister(*input) : g.Use(*input);
+    Emit(kIA32Push, NULL, value);
   }

   // Select the appropriate opcode based on the call type.
@@ -760,9 +763,11 @@ void InstructionSelector::VisitCall(Node* node) {
   // Emit the call instruction.
   InstructionOperand** first_output =
       buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
+  InstructionOperand* temps[] = {g.TempRegister(ebx)};
   Instruction* call_instr =
       Emit(opcode, buffer.outputs.size(), first_output,
- buffer.instruction_args.size(), &buffer.instruction_args.front()); + buffer.instruction_args.size(), &buffer.instruction_args.front(),
+           arraysize(temps), temps);
   call_instr->MarkAsCall();
 }

Index: src/compiler/x64/instruction-selector-x64.cc
diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc index bf6b170e414b1eb568fb727e20ed69550ff512e8..90385e3538cfb3ddb4a2474182901ca8017dd51b 100644
--- a/src/compiler/x64/instruction-selector-x64.cc
+++ b/src/compiler/x64/instruction-selector-x64.cc
@@ -941,8 +941,11 @@ void InstructionSelector::VisitCall(Node* node) {
   for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
        input != buffer.pushed_nodes.rend(); input++) {
     // TODO(titzer): handle pushing double parameters.
-    Emit(kX64Push, NULL,
- g.CanBeImmediate(*input) ? g.UseImmediate(*input) : g.Use(*input));
+    InstructionOperand* value =
+        g.CanBeImmediate(*input)
+            ? g.UseImmediate(*input)
+            : IsSupported(ATOM) ? g.UseRegister(*input) : g.Use(*input);
+    Emit(kX64Push, NULL, value);
   }

   // Select the appropriate opcode based on the call type.
Index: src/flag-definitions.h
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 241729ede731a34f7c4dd44eaf38233ee8156b96..970a760dfd6b0944b729b30bf809e68f644caddd 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -435,6 +435,8 @@ DEFINE_BOOL(enable_sahf, true,
             "enable use of SAHF instruction if available (X64 only)")
DEFINE_BOOL(enable_avx, true, "enable use of AVX instructions if available") DEFINE_BOOL(enable_fma3, true, "enable use of FMA3 instructions if available")
+DEFINE_BOOL(enable_atom, true,
+            "enable specific optimization for Atom if available")
 DEFINE_BOOL(enable_vfp3, ENABLE_VFP3_DEFAULT,
             "enable use of VFP3 instructions if available")
 DEFINE_BOOL(enable_armv7, ENABLE_ARMV7_DEFAULT,
Index: src/globals.h
diff --git a/src/globals.h b/src/globals.h
index 48bb030b826f649d99173272597a678f3335bc9a..53c6f7c57d89fa42f618928294a85664866f87e5 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -606,6 +606,7 @@ enum CpuFeature {
   SAHF,
   AVX,
   FMA3,
+  ATOM,
   // ARM
   VFP3,
   ARMv7,
Index: src/ia32/assembler-ia32.cc
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index 86a77f964053ea4d221f752ffb5c3a489265fcb7..1c672f0918bf22b347d0a940c806ae212ab57920 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -92,14 +92,16 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
   if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
   if (cpu.has_avx() && EnableAVX()) supported_ |= 1u << AVX;
   if (cpu.has_fma3() && FLAG_enable_fma3) supported_ |= 1u << FMA3;
+  if (cpu.is_atom() && FLAG_enable_atom) supported_ |= 1u << ATOM;
 }


 void CpuFeatures::PrintTarget() { }
 void CpuFeatures::PrintFeatures() {
- printf("SSE3=%d SSE4_1=%d AVX=%d FMA3=%d\n", CpuFeatures::IsSupported(SSE3),
-         CpuFeatures::IsSupported(SSE4_1), CpuFeatures::IsSupported(AVX),
-         CpuFeatures::IsSupported(FMA3));
+  printf("SSE3=%d SSE4_1=%d AVX=%d FMA3=%d ATOM=%d\n",
+         CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSE4_1),
+         CpuFeatures::IsSupported(AVX), CpuFeatures::IsSupported(FMA3),
+         CpuFeatures::IsSupported(ATOM));
 }


Index: src/x64/assembler-x64.cc
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 96422f6863fa86b90b655f3568680a48e61f6731..241103f5245c094f4f17969e0c519f467317733e 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -60,15 +60,16 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
   if (cpu.has_sahf() && FLAG_enable_sahf) supported_ |= 1u << SAHF;
   if (cpu.has_avx() && EnableAVX()) supported_ |= 1u << AVX;
   if (cpu.has_fma3() && FLAG_enable_fma3) supported_ |= 1u << FMA3;
+  if (cpu.is_atom() && FLAG_enable_atom) supported_ |= 1u << ATOM;
 }


 void CpuFeatures::PrintTarget() { }
 void CpuFeatures::PrintFeatures() {
-  printf("SSE3=%d SSE4_1=%d SAHF=%d AVX=%d FMA3=%d\n",
+  printf("SSE3=%d SSE4_1=%d SAHF=%d AVX=%d FMA3=%d ATOM=%d\n",
          CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSE4_1),
          CpuFeatures::IsSupported(SAHF), CpuFeatures::IsSupported(AVX),
-         CpuFeatures::IsSupported(FMA3));
+         CpuFeatures::IsSupported(FMA3), CpuFeatures::IsSupported(ATOM));
 }


Index: src/x64/macro-assembler-x64.cc
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index b6378bf7d56311ba8716d5d8b8f19fd558a366fc..73da82c23d64103be475c1e67ebfaf644f571cc6 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -3061,7 +3061,7 @@ void MacroAssembler::Call(ExternalReference ext) {


 void MacroAssembler::Call(const Operand& op) {
-  if (kPointerSize == kInt64Size) {
+  if (kPointerSize == kInt64Size && !CpuFeatures::IsSupported(ATOM)) {
     call(op);
   } else {
     movp(kScratchRegister, op);


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to