-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[GlobalOpt] Update debug info when changing CC to Fast #144303
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
Conversation
|
@llvm/pr-subscribers-debuginfo @llvm/pr-subscribers-llvm-transforms Author: Maurice Heumann (momo5502) ChangesChanging the CC of local functions to This fixes #144301 Full diff: https://github.com/llvm/llvm-project/pull/144303.diff 1 Files Affected:
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index 7db0586386506..b0f1dee415efd 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -1920,6 +1920,14 @@ static void RemovePreallocated(Function *F) {
}
}
+static unsigned char GetDebugInfoFastCC(const Triple &Triple) {
+ if (Triple.isOSWindows() && Triple.isArch32Bit()) {
+ return llvm::dwarf::DW_CC_BORLAND_msfastcall;
+ }
+
+ return llvm::dwarf::DW_CC_normal;
+}
+
static bool
OptimizeFunctions(Module &M,
function_ref<TargetLibraryInfo &(Function &)> GetTLI,
@@ -1938,6 +1946,9 @@ OptimizeFunctions(Module &M,
if (hasOnlyColdCalls(F, GetBFI, ChangeableCCCache))
AllCallsCold.push_back(&F);
+ unsigned char DebugInfoFastCC =
+ GetDebugInfoFastCC(Triple(M.getTargetTriple()));
+
// Optimize functions.
for (Function &F : llvm::make_early_inc_range(M)) {
// Don't perform global opt pass on naked functions; we don't want fast
@@ -2021,6 +2032,13 @@ OptimizeFunctions(Module &M,
// Fast calling convention.
F.setCallingConv(CallingConv::Fast);
ChangeCalleesToFastCall(&F);
+
+ if (F.getSubprogram()) {
+ DISubprogram *SP = F.getSubprogram();
+ auto Temp = SP->getType()->cloneWithCC(DebugInfoFastCC);
+ SP->replaceType(MDNode::replaceWithPermanent(std::move(Temp)));
+ }
+
++NumFastCallFns;
Changed = true;
}
|
| static unsigned char GetDebugInfoFastCC(const Triple &Triple) { | ||
| if (Triple.isOSWindows() && Triple.isArch32Bit()) { | ||
| return llvm::dwarf::DW_CC_BORLAND_msfastcall; | ||
| } | ||
|
|
||
| return llvm::dwarf::DW_CC_normal; | ||
| } | ||
|
|
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 seems a bit brittle, if other targets had other calling convention choices - perhaps this logic should go wherever the CC is determined?
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 agree. However, I think the mapping for fastcc is determined by a table definition for each architecture. I feel like integrating this there is not easily feasible.
Do you have a recommendation on how this could be done better?
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.
Could you point to the table definition, we/someone could take a look to see how practical it is.
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 decision how FastCC is being lowered happens here:
| CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_X86_32_FastCC>>, |
Here is where the dwarf CC is translated to the CodeView format:
| case dwarf::DW_CC_BORLAND_msfastcall: return CallingConvention::NearFast; |
I feel like the reason this issue arises in the first place is the redundancy for calling convention specifications: the information is stored in the function, as well as the debug info.
What would also work would be a pseudo dwarf calling convention for fastCC that can then be mapped onto the real CC for each respective platform. However, I assume that for most platforms this is just the normal calling convention, which is why this approach seemed to cause the least overhead.
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.
Perhaps @zmodem has some thoughts on the PDB side of things, and @nikic has some thoughts on the broader LLVM architectural issue.
Yeah, I'd be open to the right direction being each architecture having a mapping from their real CCs to the DWARF CC they want to use for them, and removing the CC from the LLVM IR debug info metadata.
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.
No PDB specific thoughts really, but it does sound redundant to store the calling convention in the debug info metadata as well (and error prone as it needs to stay in sync).
When we lower the debug metadata (or translate it to codeview), do we have an easy way to get to the llvm::Function? If so it sounds like we should just get the calling convention from there?
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 do - the subprogram data is attached to the llvm::Function (so, technically, you could be looking at a subprogram without knowing what function it came from, but that's fixable)
I guess in the case where a DWARF function declaration is emitted with no associated LLVM IR, it might be a problem - in theory we could/may need to still carry a calling convention down through the debug info metadata to handle cases like that.
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.
If we don't go the route of dropping it from the metadata, maybe the verifier could check for Function/metadata calling convention consistency?
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.
Yeah - I'm not 100% sure we carry CC on declarations, so someone'd have to check that/see if we need it anyway. And if we do, yeah, checking for consistency would be good - and maybe the metadata would/could carry the same type of CC as the IR, rather than the debug info one - and then only convert from real CC to DWARF CC at the backend.
|
I'm going to close this. Turns out DW_CC_BORLAND_msfastcall is not at all the same as fastcc. Seems like there is no way to represent fastcc in the PDB, so it doesn't matter right now. |
Changing the CC of local functions to
fastccin GlobalOpt causes the PDB to misalign.Updating the debug info is requried to reflect the change in the PDB.
This fixes #144301