#include "lsra_stats.h"
#undef LSRA_STAT_DEF
#define REG_SEL_DEF(stat, value, shortname, orderSeqId) #stat,
+#define BUSY_REG_SEL_DEF(stat, value, shortname, orderSeqId) REG_SEL_DEF(stat, value, shortname, orderSeqId)
#include "lsra_score.h"
-#undef REG_SEL_DEF
};
assert(stat < ArrLen(lsraStatNames));
#define REG_SEL_DEF(stat, value, shortname, orderSeqId) \
case RegisterScore::stat: \
return LsraStat::STAT_##stat;
+#define BUSY_REG_SEL_DEF(stat, value, shortname, orderSeqId) REG_SEL_DEF(stat, value, shortname, orderSeqId)
#include "lsra_score.h"
-#undef REG_SEL_DEF
default:
return LsraStat::STAT_FREE;
}
#define REG_SEL_DEF(stat, value, shortname, orderSeqId) \
case stat: \
return shortname;
+#define BUSY_REG_SEL_DEF(stat, value, shortname, orderSeqId) REG_SEL_DEF(stat, value, shortname, orderSeqId)
#include "lsra_score.h"
-#undef REG_SEL_DEF
default:
return " - ";
}
#define REG_SEL_DEF(stat, value, shortname, orderSeqId) \
mappingTable->Set(stat, &LinearScan::RegisterSelection::try_##stat);
+#define BUSY_REG_SEL_DEF(stat, value, shortname, orderSeqId) REG_SEL_DEF(stat, value, shortname, orderSeqId)
#include "lsra_score.h"
-#undef REG_SEL_DEF
LPCWSTR ordering = JitConfig.JitLsraOrdering();
if (ordering == nullptr)
case orderSeqId: \
RegSelectionOrder[orderId] = enum_name; \
break;
+#define BUSY_REG_SEL_DEF(enum_name, value, shortname, orderSeqId) REG_SEL_DEF(enum_name, value, shortname, orderSeqId)
#include "lsra_score.h"
-#undef REG_SEL_DEF
default:
assert(!"Invalid lsraOrdering value.");
}
}
}
#else // RELEASE
-// In release, just invoke the default order
+ // In release, just invoke the default order
+ if (freeCandidates != RBM_NONE)
+ {
#define REG_SEL_DEF(stat, value, shortname, orderSeqId) \
try_##stat(); \
IF_FOUND_GOTO_DONE
+
+#define BUSY_REG_SEL_DEF(stat, value, shortname, orderSeqId)
+#include "lsra_score.h"
+ }
+
+#define REG_SEL_DEF(stat, value, shortname, orderSeqId)
+#define BUSY_REG_SEL_DEF(stat, value, shortname, orderSeqId) \
+ try_##stat(); \
+ IF_FOUND_GOTO_DONE
#include "lsra_score.h"
-#undef REG_SEL_DEF
+
#endif // DEBUG
#undef IF_FOUND_GOTO_DONE
#include "lsra_stats.h"
#undef LSRA_STAT_DEF
#define REG_SEL_DEF(enum_name, value, short_str, orderSeqId) STAT_##enum_name,
+#define BUSY_REG_SEL_DEF(enum_name, value, short_str, orderSeqId) REG_SEL_DEF(enum_name, value, short_str, orderSeqId)
#include "lsra_score.h"
-#undef REG_SEL_DEF
COUNT
};
#endif // TRACK_LSRA_STATS
enum RegisterScore
{
#define REG_SEL_DEF(enum_name, value, short_str, orderSeqId) enum_name = value,
+#define BUSY_REG_SEL_DEF(enum_name, value, short_str, orderSeqId) REG_SEL_DEF(enum_name, value, short_str, orderSeqId)
#include "lsra_score.h"
-#undef REG_SEL_DEF
NONE = 0
};
FORCEINLINE void reset(Interval* interval, RefPosition* refPosition);
#define REG_SEL_DEF(stat, value, shortname, orderSeqId) FORCEINLINE void try_##stat();
+#define BUSY_REG_SEL_DEF(stat, value, shortname, orderSeqId) REG_SEL_DEF(stat, value, shortname, orderSeqId)
#include "lsra_score.h"
-#undef REG_SEL_DEF
};
RegisterSelection* regSelector;
#ifndef REG_SEL_DEF
#error Must define REG_SEL_DEF macro before including this file
#endif
+#ifndef BUSY_REG_SEL_DEF
+#error Must define BUSY_REG_SEL_DEF macro before including this file
+#endif
// Register selection stats
// Each register will receive a score which takes into account the scoring criteria below.
REG_SEL_DEF(IS_PREV_REG, 0x00020, "PRVRG", 'L') // This register was previously assigned to the interval.
REG_SEL_DEF(REG_ORDER, 0x00010, "ORDER", 'M') // Tie-breaker
-// These are the original criteria for comparing registers that are in use.
-REG_SEL_DEF(SPILL_COST, 0x00008, "SPILL", 'N') // It has the lowest cost of all the candidates.
-REG_SEL_DEF(FAR_NEXT_REF, 0x00004, "FNREF", 'O') // It has a farther next reference than the best candidate thus far.
-REG_SEL_DEF(PREV_REG_OPT, 0x00002, "PRGOP", 'P') // The previous RefPosition of its current assigned interval is RegOptional.
+BUSY_REG_SEL_DEF(SPILL_COST, 0x00008, "SPILL", 'N') // It has the lowest cost of all the candidates.
+BUSY_REG_SEL_DEF(FAR_NEXT_REF, 0x00004, "FNREF", 'O') // It has a farther next reference than the best candidate thus far.
+BUSY_REG_SEL_DEF(PREV_REG_OPT, 0x00002, "PRGOP", 'P') // The previous RefPosition of its current assigned interval is RegOptional.
// TODO-CQ: Consider using REG_ORDER as a tie-breaker even for busy registers.
-REG_SEL_DEF(REG_NUM, 0x00001, "RGNUM", 'Q') // It has a lower register number.
+BUSY_REG_SEL_DEF(REG_NUM, 0x00001, "RGNUM", 'Q') // It has a lower register number.
// clang-format on
+#undef BUSY_REG_SEL_DEF
+#undef REG_SEL_DEF