changeset 12250:c1715eaaa820

8166561: [s390] Adaptions needed for s390 port in C1 and C2. Reviewed-by: kvn
author goetz
date Thu, 22 Sep 2016 18:29:15 +0200
parents 59da89afe788
children a0cf41abef5d
files src/cpu/aarch64/vm/c2_globals_aarch64.hpp src/cpu/ppc/vm/c2_globals_ppc.hpp src/cpu/sparc/vm/c2_globals_sparc.hpp src/cpu/x86/vm/c2_globals_x86.hpp src/share/vm/adlc/formssel.cpp src/share/vm/adlc/main.cpp src/share/vm/c1/c1_LIR.cpp src/share/vm/c1/c1_LIRGenerator.cpp src/share/vm/c1/c1_LIRGenerator.hpp src/share/vm/c1/c1_LinearScan.cpp src/share/vm/opto/c2_globals.hpp src/share/vm/opto/memnode.cpp src/share/vm/opto/output.cpp src/share/vm/opto/type.cpp src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp
diffstat 15 files changed, 69 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/c2_globals_aarch64.hpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/cpu/aarch64/vm/c2_globals_aarch64.hpp	Thu Sep 22 18:29:15 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -72,6 +72,7 @@
 define_pd_global(bool, OptoBundling,                 false);
 define_pd_global(bool, OptoRegScheduling,            false);
 define_pd_global(bool, SuperWordLoopUnrollAnalysis,  true);
+define_pd_global(bool, IdealizeClearArrayNode,       true);
 
 define_pd_global(intx, ReservedCodeCacheSize,        48*M);
 define_pd_global(intx, NonProfiledCodeHeapSize,      21*M);
--- a/src/cpu/ppc/vm/c2_globals_ppc.hpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/cpu/ppc/vm/c2_globals_ppc.hpp	Thu Sep 22 18:29:15 2016 +0200
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -80,6 +80,7 @@
 //   loc = x.f
 //   NullCheck loc
 define_pd_global(bool, OptoScheduling,               false);
+define_pd_global(bool, IdealizeClearArrayNode,       true);
 
 define_pd_global(intx, InitialCodeCacheSize,         2048*K); // Integral multiple of CodeCacheExpansionSize
 define_pd_global(intx, ReservedCodeCacheSize,        256*M);
--- a/src/cpu/sparc/vm/c2_globals_sparc.hpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/cpu/sparc/vm/c2_globals_sparc.hpp	Thu Sep 22 18:29:15 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,6 +64,7 @@
 define_pd_global(bool, OptoScheduling,               true);
 define_pd_global(bool, OptoRegScheduling,            false);
 define_pd_global(bool, SuperWordLoopUnrollAnalysis,  false);
+define_pd_global(bool, IdealizeClearArrayNode,       true);
 
 #ifdef _LP64
 // We need to make sure that all generated code is within
--- a/src/cpu/x86/vm/c2_globals_x86.hpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/cpu/x86/vm/c2_globals_x86.hpp	Thu Sep 22 18:29:15 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -83,6 +83,7 @@
 define_pd_global(bool, OptoBundling,                 false);
 define_pd_global(bool, OptoRegScheduling,            true);
 define_pd_global(bool, SuperWordLoopUnrollAnalysis,  true);
+define_pd_global(bool, IdealizeClearArrayNode,       true);
 
 define_pd_global(intx, ReservedCodeCacheSize,        48*M);
 define_pd_global(intx, NonProfiledCodeHeapSize,      21*M);
--- a/src/share/vm/adlc/formssel.cpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/share/vm/adlc/formssel.cpp	Thu Sep 22 18:29:15 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -722,6 +722,11 @@
         // // unique def, some uses
         // // must return bottom unless all uses match def
         // unique = NULL;
+#ifdef S390
+        // This case is important for move instructions on s390x.
+        // On other platforms (e.g. x86), all uses always match the def.
+        unique = NULL;
+#endif
       }
     } else if( DEF_of_memory > 0 ) {
       // multiple defs, don't care about uses
--- a/src/share/vm/adlc/main.cpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/share/vm/adlc/main.cpp	Thu Sep 22 18:29:15 2016 +0200
@@ -259,6 +259,7 @@
   AD.addInclude(AD._DFA_file, "opto/cfgnode.hpp");  // Use PROB_MAX in predicate.
   AD.addInclude(AD._DFA_file, "opto/intrinsicnode.hpp");
   AD.addInclude(AD._DFA_file, "opto/matcher.hpp");
+  AD.addInclude(AD._DFA_file, "opto/narrowptrnode.hpp");
   AD.addInclude(AD._DFA_file, "opto/opcodes.hpp");
   AD.addInclude(AD._DFA_file, "opto/convertnode.hpp");
   // Make sure each .cpp file starts with include lines:
--- a/src/share/vm/c1/c1_LIR.cpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/share/vm/c1/c1_LIR.cpp	Thu Sep 22 18:29:15 2016 +0200
@@ -209,6 +209,17 @@
   }
 
   if (TwoOperandLIRForm) {
+
+#ifdef ASSERT
+    bool threeOperandForm = false;
+#ifdef S390
+    // There are 3 operand shifts on S390 (see LIR_Assembler::shift_op()).
+    threeOperandForm =
+      code() == lir_shl ||
+      ((code() == lir_shr || code() == lir_ushr) && (result_opr()->is_double_cpu() || in_opr1()->type() == T_OBJECT));
+#endif
+#endif
+
     switch (code()) {
     case lir_add:
     case lir_sub:
@@ -222,13 +233,13 @@
     case lir_logic_xor:
     case lir_shl:
     case lir_shr:
-      assert(in_opr1() == result_opr(), "opr1 and result must match");
+      assert(in_opr1() == result_opr() || threeOperandForm, "opr1 and result must match");
       assert(in_opr1()->is_valid() && in_opr2()->is_valid(), "must be valid");
       break;
 
     // special handling for lir_ushr because of write barriers
     case lir_ushr:
-      assert(in_opr1() == result_opr() || in_opr2()->is_constant(), "opr1 and result must match or shift count is constant");
+      assert(in_opr1() == result_opr() || in_opr2()->is_constant() || threeOperandForm, "opr1 and result must match or shift count is constant");
       assert(in_opr1()->is_valid() && in_opr2()->is_valid(), "must be valid");
       break;
 
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Sep 22 18:29:15 2016 +0200
@@ -606,7 +606,10 @@
 
 
 void LIRGenerator::shift_op(Bytecodes::Code code, LIR_Opr result_op, LIR_Opr value, LIR_Opr count, LIR_Opr tmp) {
-  if (TwoOperandLIRForm && value != result_op) {
+
+  if (TwoOperandLIRForm && value != result_op
+      // Only 32bit right shifts require two operand form on S390.
+      S390_ONLY(&& (code == Bytecodes::_ishr || code == Bytecodes::_iushr))) {
     assert(count != result_op, "malformed");
     __ move(value, result_op);
     value = result_op;
--- a/src/share/vm/c1/c1_LIRGenerator.hpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/share/vm/c1/c1_LIRGenerator.hpp	Thu Sep 22 18:29:15 2016 +0200
@@ -28,6 +28,7 @@
 #include "c1/c1_Instruction.hpp"
 #include "c1/c1_LIR.hpp"
 #include "ci/ciMethodData.hpp"
+#include "utilities/macros.hpp"
 #include "utilities/sizes.hpp"
 
 // The classes responsible for code emission and register allocation
@@ -360,7 +361,7 @@
   void add_large_constant(LIR_Opr src, int c, LIR_Opr dest);
 
   // machine preferences and characteristics
-  bool can_inline_as_constant(Value i) const;
+  bool can_inline_as_constant(Value i S390_ONLY(COMMA int bits = 20)) const;
   bool can_inline_as_constant(LIR_Const* c) const;
   bool can_store_as_constant(Value i, BasicType type) const;
 
@@ -497,6 +498,12 @@
   static LIR_Opr divInOpr();
   static LIR_Opr divOutOpr();
   static LIR_Opr remOutOpr();
+#ifdef S390
+  // On S390 we can do ldiv, lrem without RT call.
+  static LIR_Opr ldivInOpr();
+  static LIR_Opr ldivOutOpr();
+  static LIR_Opr lremOutOpr();
+#endif
   static LIR_Opr shiftCountOpr();
   LIR_Opr syncLockOpr();
   LIR_Opr syncTempOpr();
@@ -622,7 +629,7 @@
 
   void load_item();
   void load_byte_item();
-  void load_nonconstant();
+  void load_nonconstant(S390_ONLY(int bits = 20));
   // load any values which can't be expressed as part of a single store instruction
   void load_for_store(BasicType store_type);
   void load_item_force(LIR_Opr reg);
--- a/src/share/vm/c1/c1_LinearScan.cpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/share/vm/c1/c1_LinearScan.cpp	Thu Sep 22 18:29:15 2016 +0200
@@ -1077,7 +1077,7 @@
   }
 
 
-#ifdef X86
+#if defined(X86) || defined(S390)
   if (op->code() == lir_cmove) {
     // conditional moves can handle stack operands
     assert(op->result_opr()->is_register(), "result must always be in a register");
@@ -1088,7 +1088,7 @@
   // this operand is allowed to be on the stack in some cases
   BasicType opr_type = opr->type_register();
   if (opr_type == T_FLOAT || opr_type == T_DOUBLE) {
-    if ((UseSSE == 1 && opr_type == T_FLOAT) || UseSSE >= 2) {
+    if ((UseSSE == 1 && opr_type == T_FLOAT) || UseSSE >= 2 S390_ONLY(|| true)) {
       // SSE float instruction (T_DOUBLE only supported with SSE2)
       switch (op->code()) {
         case lir_cmp:
@@ -1144,7 +1144,7 @@
       }
     }
   }
-#endif // X86
+#endif // X86 S390
 
   // all other operands require a register
   return mustHaveRegister;
@@ -2653,6 +2653,11 @@
     VMReg rname = frame_map()->fpu_regname(opr->fpu_regnr());
 #ifndef __SOFTFP__
 #ifndef VM_LITTLE_ENDIAN
+    // On S390 a (single precision) float value occupies only the high
+    // word of the full double register. So when the double register is
+    // stored to memory (e.g. by the RegisterSaver), then the float value
+    // is found at offset 0. I.e. the code below is not needed on S390.
+#ifndef S390
     if (! float_saved_as_double) {
       // On big endian system, we may have an issue if float registers use only
       // the low half of the (same) double registers.
@@ -2667,6 +2672,7 @@
         rname = next; // VMReg for the low bits, e.g. the real VMReg for the float
       }
     }
+#endif // !S390
 #endif
 #endif
     LocationValue* sv = new LocationValue(Location::new_reg_loc(loc_type, rname));
--- a/src/share/vm/opto/c2_globals.hpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/share/vm/opto/c2_globals.hpp	Thu Sep 22 18:29:15 2016 +0200
@@ -120,6 +120,9 @@
           "Check performance difference allowing FP "                       \
           "associativity and commutativity...")                             \
                                                                             \
+  diagnostic_pd(bool, IdealizeClearArrayNode,                               \
+          "Replace ClearArrayNode by subgraph of basic operations.")        \
+                                                                            \
   develop(bool, OptoBreakpoint, false,                                      \
           "insert breakpoint at method entry")                              \
                                                                             \
--- a/src/share/vm/opto/memnode.cpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/share/vm/opto/memnode.cpp	Thu Sep 22 18:29:15 2016 +0200
@@ -2717,9 +2717,9 @@
 
 //------------------------------Idealize---------------------------------------
 // Clearing a short array is faster with stores
-Node *ClearArrayNode::Ideal(PhaseGVN *phase, bool can_reshape){
+Node *ClearArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
   // Already know this is a large node, do not try to ideal it
-  if (_is_large) return NULL;
+  if (!IdealizeClearArrayNode || _is_large) return NULL;
 
   const int unit = BytesPerLong;
   const TypeX* t = phase->type(in(2))->isa_intptr_t();
--- a/src/share/vm/opto/output.cpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/share/vm/opto/output.cpp	Thu Sep 22 18:29:15 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1206,13 +1206,19 @@
           padding = nop_size;
         }
 
-        if(padding > 0) {
+        if (padding > 0) {
           assert((padding % nop_size) == 0, "padding is not a multiple of NOP size");
           int nops_cnt = padding / nop_size;
           MachNode *nop = new MachNopNode(nops_cnt);
           block->insert_node(nop, j++);
           last_inst++;
           _cfg->map_node_to_block(nop, block);
+          // Ensure enough space.
+          cb->insts()->maybe_expand_to_ensure_remaining(MAX_inst_size);
+          if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
+            C->record_failure("CodeCache is full");
+            return;
+          }
           nop->emit(*cb, _regalloc);
           cb->flush_bundle(true);
           current_offset = cb->insts_size();
--- a/src/share/vm/opto/type.cpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/share/vm/opto/type.cpp	Thu Sep 22 18:29:15 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -67,7 +67,7 @@
   { Bad,             T_ILLEGAL,    "vectorx:",      false, 0,                    relocInfo::none          },  // VectorX
   { Bad,             T_ILLEGAL,    "vectory:",      false, 0,                    relocInfo::none          },  // VectorY
   { Bad,             T_ILLEGAL,    "vectorz:",      false, 0,                    relocInfo::none          },  // VectorZ
-#elif defined(PPC64)
+#elif defined(PPC64) || defined(S390)
   { Bad,             T_ILLEGAL,    "vectors:",      false, 0,                    relocInfo::none          },  // VectorS
   { Bad,             T_ILLEGAL,    "vectord:",      false, Op_RegL,              relocInfo::none          },  // VectorD
   { Bad,             T_ILLEGAL,    "vectorx:",      false, 0,                    relocInfo::none          },  // VectorX
--- a/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp	Thu Sep 22 18:23:15 2016 +0200
+++ b/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp	Thu Sep 22 18:29:15 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -361,6 +361,8 @@
   int minimum_alignment = 16;
 #if defined(SPARC) || (defined(X86) && !defined(AMD64))
   minimum_alignment = 4;
+#elif defined(S390)
+  minimum_alignment = 2;
 #endif
 
   if (InteriorEntryAlignment < minimum_alignment) {