Selaa lähdekoodia

ARM: Tune rematerialization scheduler.

Mike Pall 14 vuotta sitten
vanhempi
commit
2d0b32500e
1 muutettua tiedostoa jossa 27 lisäystä ja 23 poistoa
  1. 27 23
      src/lj_asm.c

+ 27 - 23
src/lj_asm.c

@@ -121,6 +121,24 @@ static LJ_NORET LJ_NOINLINE void asm_mclimit(ASMState *as)
   lj_mcode_limiterr(as->J, (size_t)(as->mctop - as->mcp + 4*MCLIM_REDZONE));
 }
 
+#ifdef RID_NUM_KREF
+#define ra_iskref(ref)		((ref) < RID_NUM_KREF)
+#define ra_krefreg(ref)		((Reg)(RID_MIN_KREF + (Reg)(ref)))
+#define ra_krefk(as, ref)	(as->krefk[(ref)])
+
+static LJ_AINLINE void ra_setkref(ASMState *as, Reg r, int32_t k)
+{
+  IRRef ref = (IRRef)(r - RID_MIN_KREF);
+  as->krefk[ref] = k;
+  as->cost[r] = REGCOST(ref, ref);
+}
+
+#else
+#define ra_iskref(ref)		0
+#define ra_krefreg(ref)		RID_MIN_GPR
+#define ra_krefk(as, ref)	0
+#endif
+
 /* Arch-specific field offsets. */
 static const uint8_t field_ofs[IRFL__MAX+1] = {
 #define FLOFS(name, ofs)	(uint8_t)(ofs),
@@ -258,24 +276,6 @@ static void ra_dprintf(ASMState *as, const char *fmt, ...)
 
 #define ra_used(ir)		(ra_hasreg((ir)->r) || ra_hasspill((ir)->s))
 
-#ifdef RID_NUM_KREF
-#define ra_iskref(ref)		((ref) < RID_NUM_KREF)
-#define ra_krefreg(ref)		((Reg)(RID_MIN_KREF + (Reg)(ref)))
-#define ra_krefk(as, ref)	(as->krefk[(ref)])
-
-static LJ_AINLINE void ra_setkref(ASMState *as, Reg r, int32_t k)
-{
-  IRRef ref = (IRRef)(r - RID_MIN_KREF);
-  as->krefk[ref] = k;
-  as->cost[r] = REGCOST(ref, ref);
-}
-
-#else
-#define ra_iskref(ref)		0
-#define ra_krefreg(ref)		RID_MIN_GPR
-#define ra_krefk(as, ref)	0
-#endif
-
 /* Setup register allocator. */
 static void ra_setup(ASMState *as)
 {
@@ -475,7 +475,7 @@ static void ra_evictk(ASMState *as)
 static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
 {
   /* First try to find a register which already holds the same constant. */
-  RegSet work = ~as->freeset & RSET_GPR;
+  RegSet pick, work = ~as->freeset & RSET_GPR;
   Reg r;
   while (work) {
     IRRef ref;
@@ -486,11 +486,15 @@ static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
       return r;
     rset_clear(work, r);
   }
-  work = as->freeset & allow;
-  if (work)
-    r = rset_picktop(work);
-  else
+  pick = as->freeset & allow;
+  if (pick) {
+    /* Constants should preferably get unmodified registers. */
+    if ((pick & ~as->modset))
+      pick &= ~as->modset;
+    r = rset_pickbot(pick);  /* Reduce conflicts with inverse allocation. */
+  } else {
     r = ra_evict(as, allow);
+  }
   RA_DBGX((as, "allock    $x $r", k, r));
   ra_setkref(as, r, k);
   rset_clear(as->freeset, r);