-
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
Implement loop peeling. #1510
base: master
Are you sure you want to change the base?
Implement loop peeling. #1510
Conversation
On a fresh clone (and even if I merge in
|
@@ -1844,14 +1853,18 @@ impl<'a> Assemble<'a> { | |||
reg_alloc::Register::GP(r) => { | |||
let [_] = self.ra.assign_gp_regs( | |||
&mut self.asm, | |||
iidx, | |||
// This tells the register allocator to assign this register | |||
// to the instruction at `iidx` so we can look it up later. Since |
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 "since we are at the end" bit is dangerous: the register allocator does (must!) take into account iidx
when making decisions about what to spill etc. By passing in 0
here, I think weird things will happen. Is there any reason not to pass iidx
here (and below)?
@@ -423,8 +429,10 @@ impl Module { | |||
} | |||
|
|||
/// Push the location of a trace parameter. | |||
pub(crate) fn push_param(&mut self, loc: yksmp::Location) { | |||
pub(crate) fn push_param(&mut self, loc: yksmp::Location) -> usize { |
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.
This should return a ParamIdx
.
}), | ||
Inst::Call(dc) => { | ||
// Clone and map arguments. | ||
let args = (0..(dc.num_args())) |
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.
CallInst::iter_args_idx
does this horror for you.
Inst::IndirectCall(iidx) => { | ||
let ic = m.indirect_call(*iidx); | ||
// Clone and map arguments. | ||
let args = (0..(ic.num_args())) |
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.
Ditto IndirectCallInst::iter_args_idx
.
where | ||
F: Fn(InstIdx, &Module) -> Operand, | ||
{ | ||
let mapper = |x: &PackedOperand, m: &Module| match x.unpack(m) { |
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.
We always make m
the first argument (it's a useful convention IMHO).
Using `InstIdx(0)` can cause the register allocator to assume things aren't needed (etc.) in a way that could cause problems.
This masks a bug when writing live vars at the end of a trace, the fix for which requires its own PR.
This requires us to introduce a `None` constraint: we can then build up all GP and FP constraints in one go, gradually turning `None`s into other constraints as necessary.
While this isn't ready yet, I'm raising this as a draft, so @ltratt may have a peek. Running
simple.c
we get the following trace, which shows the direction we want this to go.I have taken this opportunity to rename the labels as their previous names consistently managed to confuse me. I'm not married to these names, so I'm open to discussion. But I do believe they need changing.
With the current PR, I'm getting the following error when running
simple.c
:This is possibly due to the way we copy the
VarLocation
s from theheader_end
to thebody_start
, which we do here: https://github.com/ykjit/yk/pull/1510/files#diff-b7513e8c31bfe56ee2b41fa041e8632d81f4bafc2e759b22b597f3867359269eR1938. I would also like to turn your attention the big comment there, which explains why we are doing things this way, and is related to what we discussed earlier.