Commit 7822145c authored by Stephan Herhut's avatar Stephan Herhut Committed by Commit Bot

[wasm] Improve register hinting for arguments

When assigning a register to a value that is used as a function
argument, we use a hint to suggest the corresponding register. However,
if the argument is also used after the call, the register will not be
free for the entire live range of the value. Hence we need to split the
live range.
To minimize the number of splits, we aim to choose a register with
maxium availability. This heuristic was implemented based on lifetime
positions with sub-instruction precision. In such a model, argument
registers typically have a shorter available time, as they need to
hold a value before a call, whereas all other registers are free until
right after the call, where they have been overwritten by the called
function. Hence, we typically chose a non-argument register, ignoring
the hint and creating an extra move.
This change moves the heuristic to instruction granularity, which
gives argument and other registers the same free time. We also now
prefer hinted registers if they have the same free time.

Change-Id: Ia8dd73b6c086d28859a836c42ea9ff8afce4c371
Reviewed-on: https://chromium-review.googlesource.com/1124852Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Commit-Queue: Stephan Herhut <herhut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54255}
parent 4b9b9b68
......@@ -3089,11 +3089,22 @@ bool LinearScanAllocator::TryAllocateFreeReg(
DCHECK_GE(free_until_pos.length(), num_codes);
// Find the register which stays free for the longest time.
int reg = codes[0];
for (int i = 1; i < num_codes; ++i) {
// Find the register which stays free for the longest time. Check for
// the hinted register first, as we might want to use that one. Only
// count full instructions for free ranges, as an instruction's internal
// positions do not help but might shadow a hinted register. This is
// typically the case for function calls, where all registered are
// cloberred after the call except for the argument registers, which are
// set before the call. Hence, the argument registers always get ignored,
// as their available time is shorter.
int reg;
if (current->FirstHintPosition(&reg) == nullptr) {
reg = codes[0];
}
for (int i = 0; i < num_codes; ++i) {
int code = codes[i];
if (free_until_pos[code] > free_until_pos[reg]) {
if (free_until_pos[code].ToInstructionIndex() >
free_until_pos[reg].ToInstructionIndex()) {
reg = code;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment