8173465: Introduce NearLabel for branches known to be short.
authorgoetz
Fri, 27 Jan 2017 10:22:19 +0100
changeset 46272 3cee5c1f3459
parent 46271 979ebd346ecf
child 46273 898ec28d19d7
8173465: Introduce NearLabel for branches known to be short. Reviewed-by: kvn
hotspot/src/cpu/s390/vm/assembler_s390.hpp
hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp
hotspot/src/share/vm/asm/assembler.hpp
--- a/hotspot/src/cpu/s390/vm/assembler_s390.hpp	Wed Feb 15 22:59:57 2017 -0500
+++ b/hotspot/src/cpu/s390/vm/assembler_s390.hpp	Fri Jan 27 10:22:19 2017 +0100
@@ -28,8 +28,6 @@
 
 #undef  LUCY_DBG
 
-#define NearLabel Label
-
 // Immediate is an abstraction to represent the various immediate
 // operands which exist on z/Architecture. Neither this class nor
 // instances hereof have an own state. It consists of methods only.
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp	Wed Feb 15 22:59:57 2017 -0500
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp	Fri Jan 27 10:22:19 2017 +0100
@@ -1616,6 +1616,8 @@
   if (branch_target.is_bound()) {
     address branch_addr = target(branch_target);
     branch_optimized(cond, branch_addr);
+  } else if (branch_target.is_near()) {
+    z_brc(cond, branch_target);  // Caller assures that the target will be in range for z_brc.
   } else {
     z_brcl(cond, branch_target); // Let's hope target is in range. Otherwise, we will abort at patch time.
   }
@@ -1674,7 +1676,8 @@
                                                   bool     has_sign) {
   address      branch_origin = pc();
   bool         x2_imm8       = (has_sign && Immediate::is_simm8(x2)) || (!has_sign && Immediate::is_uimm8(x2));
-  bool         is_RelAddr16  = (branch_target.is_bound() &&
+  bool         is_RelAddr16  = branch_target.is_near() ||
+                               (branch_target.is_bound() &&
                                 RelAddr::is_in_range_of_RelAddr16(target(branch_target), branch_origin));
   unsigned int casenum       = (len64?2:0)+(has_sign?0:1);
 
@@ -1744,13 +1747,21 @@
                                                   Label&   branch_target,
                                                   bool     len64,
                                                   bool     has_sign) {
-  unsigned int casenum = (len64?2:0)+(has_sign?0:1);
+  unsigned int casenum = (len64 ? 2 : 0) + (has_sign ? 0 : 1);
 
   if (branch_target.is_bound()) {
     address branch_addr = target(branch_target);
     compare_and_branch_optimized(r1, r2, cond, branch_addr, len64, has_sign);
   } else {
-    {
+    if (VM_Version::has_CompareBranch() && branch_target.is_near()) {
+      switch (casenum) {
+        case 0: z_crj(  r1, r2, cond, branch_target); break;
+        case 1: z_clrj( r1, r2, cond, branch_target); break;
+        case 2: z_cgrj( r1, r2, cond, branch_target); break;
+        case 3: z_clgrj(r1, r2, cond, branch_target); break;
+        default: ShouldNotReachHere(); break;
+      }
+    } else {
       switch (casenum) {
         case 0: z_cr( r1, r2); break;
         case 1: z_clr(r1, r2); break;
--- a/hotspot/src/share/vm/asm/assembler.hpp	Wed Feb 15 22:59:57 2017 -0500
+++ b/hotspot/src/share/vm/asm/assembler.hpp	Fri Jan 27 10:22:19 2017 +0100
@@ -93,6 +93,10 @@
   GrowableArray<int>* _patch_overflow;
 
   Label(const Label&) { ShouldNotReachHere(); }
+ protected:
+
+  // The label will be bound to a location near its users.
+  bool _is_near;
 
  public:
 
@@ -126,6 +130,10 @@
   bool is_unbound() const  { return _loc == -1 && _patch_index > 0; }
   bool is_unused() const   { return _loc == -1 && _patch_index == 0; }
 
+  // The label will be bound to a location near its users. Users can
+  // optimize on this information, e.g. generate short branches.
+  bool is_near()           { return _is_near; }
+
   /**
    * Adds a reference to an unresolved displacement instruction to
    * this unbound label
@@ -145,6 +153,7 @@
     _loc = -1;
     _patch_index = 0;
     _patch_overflow = NULL;
+    _is_near = false;
   }
 
   Label() {
@@ -152,6 +161,13 @@
   }
 };
 
+// A NearLabel must be bound to a location near its users. Users can
+// optimize on this information, e.g. generate short branches.
+class NearLabel : public Label {
+ public:
+  NearLabel() : Label() { _is_near = true; }
+};
+
 // A union type for code which has to assemble both constant and
 // non-constant operands, when the distinction cannot be made
 // statically.