Skip to content
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

Add pass disallowing calls in entry blocks. #105

Merged
merged 2 commits into from
Nov 21, 2023

Conversation

ptersilie
Copy link

Adds a pass that splits the entry block before the first call instruction, thus ensuring that no calls can exist inside a function's entry block. This makes it easier on the JIT side to detect mappable callbacks from unmappable code (aka external functions) and fixes a soundness issue with our previous StackAdjust solution.

Unfortunately, this change revealed a stackmap bug that was lurking around, so we need to fix them along side this change.

yk companion PR coming up soon.

@ltratt
Copy link

ltratt commented Nov 20, 2023

Can we find a test for the stackmap fix? cvise might be our friend here?

@ptersilie
Copy link
Author

There's a test in yk that fails without this change.

@ltratt
Copy link

ltratt commented Nov 20, 2023

Understood, but we'll never be able to upstream this to LLVM without an LLVM-level test. Maybe we can just extract the ll from the failing yk test and plonk it in a test here?

@ptersilie
Copy link
Author

That should be possible.

@ltratt
Copy link

ltratt commented Nov 20, 2023

Thanks!

@ptersilie
Copy link
Author

Sorry, I accidentally rebased locally whilst working on the test. Permission to force push before I add the test?

if (MOI->isKill()) {
// There's no point in tracking a killed register. Instead, try and
// replace it with another register with the same value (possibly due
// to spilling), to increase the likelyhood off us tracking that value.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed this the other day, but I wouldn't say a temporary save/restore from one register to another is a "spill".

You said LLVM uses this term that way though? Is that so? Can you show us?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't find it anymore and don't really care enough to keep looking. Happy for you to suggest a different wording if you dislike the term spilling to describe storing one register in another to free the first one up.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can just say the value was moved to another register. There are many reasons why that could happen, the "spill" being just one of them.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -99,13 +113,14 @@ void processInstructions(
const MachineOperand Rhs = Instr.getOperand(1);
assert(Lhs.isReg() && "Is register.");
assert(Rhs.isReg() && "Is register.");
// Reassigning a new value to Lhs means any mappings to Lhs are now void
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

capital LHS?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vext01
Copy link

vext01 commented Nov 20, 2023

Just some superficial comments from me. Good work!

@ltratt
Copy link

ltratt commented Nov 20, 2023

Sorry, I accidentally rebased locally whilst working on the test.

If you rebase back to the last commit in this PR (357fc57ab34f2557a303ee90bbaa912da3472559) then no force pushing will be necessary.

@ptersilie
Copy link
Author

sigh ok, I just need to remember to move these changes 357fc57#diff-1d872ec9f8bee5a945bd90f3aa4e0190cbc47e55a0c0dec7d6f8cc92c3e9af66L82 from the second commit to the first, which I've already done, but which is gonna disappear when I reset to 357fc57

@ptersilie
Copy link
Author

That should address all comments. Needs squashing and rebasing as I need to move something from commit 2 into commit 1.

// YKFIXME: This is likely only a temporary fix. In the future we might
// want to allow stackmaps to track arbitrarily many locations per live
// variable. Currently, we can only track two.
// YKFIXME: This is likely only a temporary fix. In the future we might
Copy link

@vext01 vext01 Nov 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line 313: off -> of

I wonder if we can reword it a bit to be easier to read.

How about:

Instead, we look for copies of the killed register and use one of those registers instead.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 92fb504.

Review Bot: You have now depleted your free change requests. Please buy more review tokens if you like to request more changes.

@ltratt
Copy link

ltratt commented Nov 21, 2023

Please squash.

@ptersilie ptersilie force-pushed the nomoreentryblockcalls branch from 92fb504 to e4ee8de Compare November 21, 2023 13:49
@ptersilie
Copy link
Author

Squashed an rebased.

@ltratt ltratt added this pull request to the merge queue Nov 21, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Nov 21, 2023
@ptersilie
Copy link
Author

The renaming of the pass broke the formatting. Ok to squash?

@ltratt
Copy link

ltratt commented Nov 21, 2023

Please squash.

The pass splits entry block at the first call instruction, thus ensuring that
no entry block has a function call. This makes it easier during trace
construction to determine when external functions call back into mappable code.
This commit fixes yet another bug in stackmaps that leads to registers being
untracked. The bug went unnoticed until the recent entryblock change exposed it.
The fix consists of two changes, allowing spill mappings to be applied
transitively and replacing killed registers in the stackmap with non-killed
registers holding the same value. See comments for more detail.
@ptersilie ptersilie force-pushed the nomoreentryblockcalls branch from 4946fb6 to 10bf29b Compare November 21, 2023 15:16
@ptersilie
Copy link
Author

Squashed.

@ltratt ltratt added this pull request to the merge queue Nov 21, 2023
Merged via the queue into ykjit:main with commit 668b215 Nov 21, 2023
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants