Replace return variable with its destination.#67
Conversation
|
Last commit needs squashing. |
ykcompile/src/lib.rs
Outdated
|
|
||
| /// Returns the currently assigned register for a given `Local`. Similar to `local_to_reg` but | ||
| /// read-only, i.e. this function doesn't assign `Local`'s to registers. | ||
| fn get_reg(&self, local: &Local) -> Result<u8, CompileError> { |
There was a problem hiding this comment.
AFAICS this function is dead, so we should (later) squash d3394dd into this commit?
There was a problem hiding this comment.
I see you already mentioned this.
There was a problem hiding this comment.
Yes, I noticed shortly after pushing, but didn't know if force pushing is okay if I haven't assigned anyone yet.
ykcompile/src/lib.rs
Outdated
| /// In the long-run, when we have a proper register allocator, this won't be needed. | ||
| OutOfRegisters, | ||
| /// We tried to retrieve the register for a local which doesn't have a register assigned to it. | ||
| UnknownLocal, |
There was a problem hiding this comment.
Shall we put the Local inside and report it when we crash?
There was a problem hiding this comment.
I just realised this isn't even used anymore, so I removed it in
61e680e.
ykcompile/src/lib.rs
Outdated
| assigned_regs: HashMap<Local, u8>, | ||
| /// Stores the destination locals to which we copy RAX to after leaving an inlined call. | ||
| leaves: Vec<Option<Place>>, | ||
| /// Stores the destination local of the outer most function and moves its content into RAX at |
| fn free_register(&mut self, local: &Local) { | ||
| if let Some(reg) = self.assigned_regs.remove(local) { | ||
| if local == &self.rtn_var.as_ref().unwrap().local { | ||
| // We currently assume that we only trace a single function which leaves its return |
There was a problem hiding this comment.
Gross hack, but OK to get us going ;)
There was a problem hiding this comment.
Indeed. It'll be a while before we won't need this workaround anymore.
There was a problem hiding this comment.
Ah! In fact I need this for my non-inline call work, which -- like for inlined calls -- puts the return value in the destination register, which may not be rax.
yktrace/src/tir.rs
Outdated
| place.clone() | ||
| // Replace the default return variable $0 with the variable in the outer context where | ||
| // the return value will end up after leaving the function. This saves us an | ||
| // instruction when we compile the trace. More importantly however, this guards us |
There was a problem hiding this comment.
I'd kill the "More importantly however, this guards us against a future optimisation..." bit and just leave it for the commit message. The future will soon catch up with us and the comment will go stale.
|
|
||
| // Initialise VarRenamer's accumulator (and thus also set the first offset) to the | ||
| // traces most outer number of locals. | ||
| rnm.init_acc(body.num_locals); |
There was a problem hiding this comment.
would this be better as an argument to VarRename::new()? It's only done once?
There was a problem hiding this comment.
The problem is when we create VarRename we don't have access to body yet (at least not without jumping through some hoops).
yktrace/src/tir.rs
Outdated
| stack: Vec<u32>, | ||
| /// Current offset used to rename variables. | ||
| offset: u32, | ||
| /// Accumulator keeping track of total amount of variables used. Needed to use different |
There was a problem hiding this comment.
I think this would read better as "Accumulator keeping track of the total number of variables used"
I might be wrong, but "amount" feels like it implies an uncountable quantity?
yktrace/src/tir.rs
Outdated
| // restore it once we leave the inlined function call again. | ||
| self.offset += num_locals as u32; | ||
| // When entering an inlined function call set the offset to the current accumulator. Then | ||
| // increase the accumulator with the number of locals in the current function. Also add the |
There was a problem hiding this comment.
Minor wording tweak:
"increase the accumulator with the number of locals" -> "increment the accumulator by the number of locals"
|
Just a handful of small comments from me. |
|
Think I have addressed all comments. |
|
So |
|
It was used in |
|
OK. Please squash. |
This change replaces the default return variable `$0` with the variable in the outer context where the return value will end up after leaving the function. This saves us an instruction when we compile the trace. More importantly however, this guards us against a future optimisation in rustc that allows SIR to assign to $0 multiple times and at the beginning of a block, which could lead to another function overwriting its value (see rust-lang/rust#72205).
Currently, functions that are called consecutively (i.e. they are not nested) use the same offset to rename their variables (the offset of their outer context), which leads to them sharing the same variable names. By using an accumulator which is continuously increased to calculate the offset, we make sure consecutive functions have increasing variable names, even when after leaving a function the offset is temporarily reset to that of the outer context.
|
Squashed. |
|
bors r+ |
|
Build succeeded: |
This change replaces the default return variable
$0with the variablein the outer context where the return value will end up after leaving
the function. This saves us an instruction when we compile the trace.
More importantly however, this guards us against a future optimisation
in rustc that allows SIR to assign to $0 multiple times and at the
beginning of a block, which could lead to another function overwriting
its value (see rust-lang/rust#72205).
While we are here, also fix a bug in the variable renaming code.
Currently, functions that are called consecutively (i.e. they are not
nested) use the same offset to rename their variables (the offset of
their outer context), which leads to them sharing the same variable
names. By using an accumulator which is continuously increased to
calculate the offset, we make sure consecutive functions have increasing
variable names, even when after leaving a function the offset is
temporarily reset to that of the outer context.