Save/restore callee-saved registers used in regmove/regfill.

The regmove and regfill instructions temporarily divert a value's
location, and these temporary diversions are not reflected in
`func.locations`. For now, make an extra scan through the instructions
of the function to find any regmove or regfill instructions in order to
find all used callee-saved registers.

This fixes #296.
This commit is contained in:
Dan Gohman
2018-04-09 22:33:54 -07:00
parent eab57c0a40
commit 18b2f12150
2 changed files with 42 additions and 0 deletions

View File

@@ -184,6 +184,26 @@ fn callee_saved_gprs_used(flags: &shared_settings::Flags, func: &ir::Function) -
}
}
// regmove and regfill instructions may temporarily divert values into other registers,
// and these are not reflected in `func.locations`. Scan the function for such instructions
// and note which callee-saved registers they use.
//
// TODO: Consider re-evaluating how regmove/regfill/regspill work and whether it's possible
// to avoid this step.
for ebb in &func.layout {
for inst in func.layout.ebb_insts(ebb) {
match func.dfg[inst] {
ir::instructions::InstructionData::RegMove { dst, .. } |
ir::instructions::InstructionData::RegFill { dst, .. } => {
if !used.is_avail(GPR, dst) {
used.free(GPR, dst);
}
}
_ => (),
}
}
}
used.intersect(&all_callee_saved);
return used;
}