Skip to content

A MMIWP Constructor Initialized with the move constructor of MMI #98770

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

Closed
wants to merge 5 commits into from

Conversation

matinraayai
Copy link
Contributor

This PR exposes the move constructor of MachineModuleInfo as a way to initialize the MachineModuleInfoWrapperPasss.

This is useful for running passes over an externally initialized MMI, and then moving it back to its original storage for further processing/inspection, as shown in the following example:

    llvm::legacy::PassManager PM;
    auto MMI = std::make_unique<llvm::MachineModuleInfo>(TM);
    ... (Modify/inspect MMI)
    /// Initialize a MMIWP using the external MMI
    auto * MMIWP = new llvm::MachineModuleInfoWrapperPass(std::move(*MMI));
    PM.add(MMIWP);
    ... (Add more passes)
    PM.run(M);
    /// Move the MMI back to its original place prevent it from being destroyed after PM goes out of scope
    MMI = std::make_unique<llvm::MachineModuleInfo>(std::move(MMIWP->getMMI()));
    .. (Inspect the MMI)

Copy link

⚠️ We detected that you are using a GitHub private e-mail address to contribute to the repo.
Please turn off Keep my email addresses private setting in your account.
See LLVM Discourse for more information.

Copy link

github-actions bot commented Jul 13, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

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

What do you need to set in MMI?

@matinraayai
Copy link
Contributor Author

matinraayai commented Jul 15, 2024

What do you need to set in MMI?

In a nutshell, the mapping between llvm::Function and the llvm::machineFunctions.
In my code, I either:

  1. I have an MMI pre-populated with MFs and MIs, much like llvm-exegesis. I put the Module and the MMI through a minimal codegen pipeline to print the assembly.
  2. I have an LLVM IR Module which I put through IR and codegen pipelines right before assembly printing.

In either situations, I want to store the MMI and inspect it before/after code generation outside of a pass manager infrastructure; Hence I need control over the lifetime of the MMI so that it doesn't get destroyed by the pass manager's destructor.

Right now, I have a data structure that stores a Module as well as its MMIWP. The problem is, after running passes on the MMIWP I can't update it to store the modified MIR, because MMIWP doesn't have an assignment/move constructor.

Having this constructor removes the need to store the entire MMIWP, and allows me to store MMI before and after it is modified by the pass manager.

@arsenm I can show you the code offline in case you need more details.

@matinraayai
Copy link
Contributor Author

@arsenm On further inspection, I think the move constructor of MMI is not correct and should be removed all together:

MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI)
: TM(std::move(MMI.TM)),
Context(TM.getTargetTriple(), TM.getMCAsmInfo(), TM.getMCRegisterInfo(),
TM.getMCSubtargetInfo(), nullptr, &TM.Options.MCOptions, false),
MachineFunctions(std::move(MMI.MachineFunctions)) {
Context.setObjectFileInfo(TM.getObjFileLowering());
ObjFileMMI = MMI.ObjFileMMI;
CurCallSite = MMI.CurCallSite;
ExternalContext = MMI.ExternalContext;
TheModule = MMI.TheModule;
}

Yes, the machine function map gets moved; but each machine function holds an internal reference to the original MMI and its context, and moving them makes those references stale.

At this point I think the only way to prevent an MMI from going out of scope is hold on to an MMIWP and the PMs that control its lifetime.

I could in theory refactor MMIWP to either:

  1. Only support an external MMI (same as MachineModuleAnalysis), which requires a good amount of refactoring work.
  2. Support both internal and external MMI (see MMI's MCContext itself)

Given that the CodeGen pipeline is being ported to the new pass manager, and the MachineModuleAnalysis only supports an external MMI, I'm not sure if this contribution will be accepted upstream.

@matinraayai matinraayai marked this pull request as draft July 16, 2024 15:47
@arsenm arsenm requested review from aeubanks and paperchalice July 19, 2024 13:37
@arsenm
Copy link
Contributor

arsenm commented Jul 19, 2024

Yes, the machine function map gets moved; but each machine function holds an internal reference to the original MMI and its context, and moving them makes those references stale.

Can we remove this reference from MachineFunction? Intuitively it shouldn't be necessary. A quick grep shows limited uses, and in contexts where it should be directly queryable from the PM

@arsenm
Copy link
Contributor

arsenm commented Jul 19, 2024

Yes, the machine function map gets moved; but each machine function holds an internal reference to the original MMI and its context, and moving them makes those references stale.

Can we remove this reference from MachineFunction? Intuitively it shouldn't be necessary. A quick grep shows limited uses, and in contexts where it should be directly queryable from the PM

#99652 starts moving towards this

@matinraayai
Copy link
Contributor Author

@arsenm thanks for making a PR for removing the MMI reference; Let me know when it is merged so that I can test it with this PR.

However, I think there might be more issues with this than just a set of stale references. While trying the code example I put here in my tool code, I noticed that the MF states get corrupted once the PM operating on its original MMI goes out of scope. For this PR to merge I think I need to clarify whether an MMI should be moved at all. If we treat MMI as a "Module but for MIR" then probably not. If we treat it simply just as an MIR analysis data structure, then a move operator might be very useful.

If an MMI can be moved, then the constructor needs to be tested. We can do this by forcing the old MMI/PM out of scope and then checking its internal content. That's how I noticed the stale reference issues in the first place.

On the other hand, if an MMI cannot be moved, then it might be best if MMIWP doesn't own its MMI. I think MMIWP should also behave like the new PM MachineModuleAnalysis, where the MMI must be externally supplied to the pass.

I'm happy to move this PR in either direction, given I understand which direction is deemed appropriate by the backend maintainers.

@arsenm
Copy link
Contributor

arsenm commented Jul 19, 2024

@arsenm thanks for making a PR for removing the MMI reference; Let me know when it is merged so that I can test it with this PR.

That one is only the low hanging fruit, more work is needed to actually remove the reference

Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

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

Will need a new PM version at some point

@matinraayai
Copy link
Contributor Author

Closing this PR in favor of #105541.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants