-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace return variable with its destination. #67
Conversation
Last commit needs squashing. |
ykcompile/src/lib.rs
Outdated
@@ -125,8 +129,26 @@ impl TraceCompiler { | |||
} | |||
} | |||
|
|||
/// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAICS this function is dead, so we should (later) squash d3394dd into this commit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you already mentioned this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I noticed shortly after pushing, but didn't know if force pushing is okay if I haven't assigned anyone yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You did the right thing.
ykcompile/src/lib.rs
Outdated
@@ -27,6 +27,8 @@ pub enum CompileError { | |||
/// We ran out of registers. | |||
/// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we put the Local inside and report it when we crash?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realised this isn't even used anymore, so I removed it in
61e680e.
ykcompile/src/lib.rs
Outdated
@@ -96,8 +99,9 @@ pub struct TraceCompiler { | |||
available_regs: Vec<u8>, | |||
/// Maps locals to their assigned registers. | |||
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/outer most/outermost/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in bff4293.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gross hack, but OK to get us going ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. It'll be a while before we won't need this workaround anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 35abcb1
@@ -117,6 +117,10 @@ impl TirTrace { | |||
} | |||
}; | |||
|
|||
// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would this be better as an argument to VarRename::new()
? It's only done once?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is when we create VarRename
we don't have access to body
yet (at least not without jumping through some hoops).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Never mind then.
yktrace/src/tir.rs
Outdated
@@ -314,6 +318,11 @@ struct VarRenamer { | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 61cadb7
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor wording tweak:
"increase the accumulator with the number of locals" -> "increment the accumulator by the number of locals"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 61cadb7
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
$0
with 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.