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

Support VFE in thinLTO #69735

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

manman-ren
Copy link
Contributor

We add a run of GlobalDCEPass with ImportSummary. When ImportSummary is true, we remove virtual functions in vtables with VCallVisibility not Public. In this run, the regular GlobalDCEPass::AddVirtualFunctionDependencies will be bypassed, we will use ImportSummary to decide which virtual functions to remove.

Discussion points:
1> FuncsWithNonVtableRef: this is currently in ModuleSummaryIndex, does it
make sense to be part of FunctionSummary?
std::setGlobalValue::GUID FuncsWithNonVtableRef;
2> ComputeDependencies is copied from GlobalDCE to ModuleSummaryAnalysis, for the former,
ConstantDependenciesCache is a member variable
3> match from summary to Function in IR
Resolution is saved in std::setGlobalValue::GUID VFuncsToBeRemoved
Use F->getGUID() or GlobalValue::getGUID(F->getName()) when searching in VFuncsToBeRemoved

TODO:
1> support hybrid Regular/ThinLTO
2> support legacy thinLTO backend (ThinLTOCodeGenerator)

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' LTO Link time optimization (regular/full LTO or ThinLTO) llvm:ir llvm:analysis llvm:transforms labels Oct 20, 2023
We add a run of GlobalDCEPass with ImportSummary. When ImportSummary is true, we remove
virtual functions in vtables with VCallVisibility not Public. In this run, the regular
GlobalDCEPass::AddVirtualFunctionDependencies will be bypassed, we will use
ImportSummary to decide which virtual functions to remove.

Discussion points:
1> FuncsWithNonVtableRef: this is currently in ModuleSummaryIndex, does it
   make sense to be part of FunctionSummary?
   std::set<GlobalValue::GUID> FuncsWithNonVtableRef;
2> ComputeDependencies is copied from GlobalDCE to ModuleSummaryAnalysis, for the former,
   ConstantDependenciesCache is a member variable
3> match from summary to Function in IR
   Resolution is saved in std::set<GlobalValue::GUID> VFuncsToBeRemoved
   Use F->getGUID() or GlobalValue::getGUID(F->getName()) when searching in VFuncsToBeRemoved

TODO:
1> support hybrid Regular/ThinLTO
2> support legacy thinLTO backend (ThinLTOCodeGenerator)
Copy link
Contributor

@teresajohnson teresajohnson left a comment

Choose a reason for hiding this comment

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

Thanks for the patch! I didn't go through in too much detail yet, but have some mostly higher level comments and suggestions.

@@ -1362,6 +1362,8 @@ class ModuleSummaryIndex {
// Temporary map while building StackIds list. Clear when index is completely
// built via releaseTemporaryMemory.
std::map<uint64_t, unsigned> StackIdToIndex;
std::set<GlobalValue::GUID> FuncsWithNonVtableRef;
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of sets of GUIDs, it would probably be more efficient to represent, and to access, to just add new function flags (FFlags in the FunctionSummary).

@@ -1362,6 +1362,8 @@ class ModuleSummaryIndex {
// Temporary map while building StackIds list. Clear when index is completely
// built via releaseTemporaryMemory.
std::map<uint64_t, unsigned> StackIdToIndex;
std::set<GlobalValue::GUID> FuncsWithNonVtableRef;
std::set<GlobalValue::GUID> VFuncsToBeRemoved; // no need to serialize
Copy link
Contributor

Choose a reason for hiding this comment

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

It would need to be serialized for distributed thinlto. A better thing would be to describe which of these are produced by the per-module analysis and used by the thin link, vs produced by the thin link and consumed by the ThinLTO backends. However, I suggest making these flags as noted above (but those should be documented with this information too)

std::map<ValueInfo, std::vector<VirtFuncOffset>> &VFESafeVTablesAndFns,
std::map<ValueInfo, std::vector<ValueInfo>> &VFuncsAndCallers) {
// Go through Function summarys for intrinsics, also funcHasNonVTableRef to
// erase entries from VFESafeVTableAndFns.
Copy link
Contributor

Choose a reason for hiding this comment

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

why and when are entries being erased? More qualitative comments about what this algorithm is doing would be helpful.

continue;
}

// Go through VS->vTableFuncs
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you expand on the comment - what is this code doing and why?

}
llvm::errs() << "VFEThinLTO number of TIds: " << NameByGUID.size() << "\n";

// VFESafeVTablesAndFns: map from VI for vTable to VI for vfunc
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment seems to be in the wrong place, can you add a description of the below data structure (and describe VFESafeVTablesAndFns somewhere too, maybe where it is defined?)

}
}
}
llvm::errs() << "VFEThinLTO number of vTables: " << vFuncSet.size() << " "
Copy link
Contributor

Choose a reason for hiding this comment

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

Should these be optimization remarks or debug messages?

}
}

void runVFEOnIndex(ModuleSummaryIndex &Summary,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add an overview of the algorithm as a comment above this?

@@ -775,6 +783,58 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,
Index.addGlobalValueSummary(V, std::move(GVarSummary));
}

static void ComputeDependencies(
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: function should be lowerCamelCase

// again.
if (vfuncsRemoved.count(F->getGUID()))
return true;
if (vfuncsRemoved.count(GlobalValue::getGUID(F->getName())))
Copy link
Contributor

Choose a reason for hiding this comment

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

These lookups are a little dangerous as I think there are cases where we might rename and it wouldn't find the right function. For internalization we tag the function with an attribute before any thinlto renaming, linkage changes, or other optimization passes. See

V->addAttribute("thinlto-internalize");
.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category llvm:analysis llvm:ir llvm:transforms LTO Link time optimization (regular/full LTO or ThinLTO)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants