[BOLT] Make FoldedIntoFunction always point to root parent (#180855)
After ICF folds functions, FoldedIntoFunction may point to a function that was also folded. Add a post-processing step at the end of ICF to flatten all chains so FoldedIntoFunction always points to the ultimate root parent (a function that is not itself folded).
This commit is contained in:
parent
2fd5479f2c
commit
5129b3c449
@ -400,7 +400,8 @@ private:
|
||||
FragmentsSetTy ParentFragments;
|
||||
|
||||
/// Indicate if the function body was folded into another function.
|
||||
/// Used by ICF optimization.
|
||||
/// Used by ICF optimization. Always points to the root parent function
|
||||
/// (i.e., a function that is not itself folded).
|
||||
BinaryFunction *FoldedIntoFunction{nullptr};
|
||||
|
||||
/// All fragments for a parent function.
|
||||
|
||||
@ -605,6 +605,19 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
|
||||
|
||||
} while (NumFoldedLastIteration > 0);
|
||||
|
||||
// Flatten folded function chains so FoldedIntoFunction always points
|
||||
// to the root parent.
|
||||
for (auto &BFI : BC.getBinaryFunctions()) {
|
||||
BinaryFunction &BF = BFI.second;
|
||||
if (!BF.isFolded())
|
||||
continue;
|
||||
BinaryFunction *Parent = BF.getFoldedIntoFunction();
|
||||
while (Parent->isFolded())
|
||||
Parent = Parent->getFoldedIntoFunction();
|
||||
if (Parent != BF.getFoldedIntoFunction())
|
||||
BF.setFolded(Parent);
|
||||
}
|
||||
|
||||
LLVM_DEBUG({
|
||||
// Print functions that are congruent but not identical.
|
||||
for (auto &CBI : CongruentBuckets) {
|
||||
|
||||
@ -5162,9 +5162,7 @@ void RewriteInstance::updateELFSymbolTable(
|
||||
auto addExtraSymbols = [&](const BinaryFunction &Function,
|
||||
const ELFSymTy &FunctionSymbol) {
|
||||
if (Function.isFolded()) {
|
||||
BinaryFunction *ICFParent = Function.getFoldedIntoFunction();
|
||||
while (ICFParent->isFolded())
|
||||
ICFParent = ICFParent->getFoldedIntoFunction();
|
||||
const BinaryFunction *ICFParent = Function.getFoldedIntoFunction();
|
||||
ELFSymTy ICFSymbol = FunctionSymbol;
|
||||
SmallVector<char, 256> Buf;
|
||||
ICFSymbol.st_name =
|
||||
@ -5280,8 +5278,7 @@ void RewriteInstance::updateELFSymbolTable(
|
||||
// instead so that the symbol gets updated to the parent's output address.
|
||||
// In non-relocation mode, folded functions are emitted at their original
|
||||
// location, so we keep the original function reference.
|
||||
// Follow the chain of folded functions to get the final parent.
|
||||
while (BC->HasRelocations && Function && Function->isFolded())
|
||||
if (BC->HasRelocations && Function && Function->isFolded())
|
||||
Function = Function->getFoldedIntoFunction();
|
||||
// Ignore false function references, e.g. when the section address matches
|
||||
// the address of the function.
|
||||
@ -6084,8 +6081,8 @@ uint64_t RewriteInstance::getNewFunctionAddress(uint64_t OldAddress) {
|
||||
return 0;
|
||||
|
||||
// If this function was folded, its output address is 0 since it wasn't
|
||||
// emitted. Follow the chain to get the parent function's address.
|
||||
while (Function->isFolded())
|
||||
// emitted. Get the parent function's address.
|
||||
if (Function->isFolded())
|
||||
Function = Function->getFoldedIntoFunction();
|
||||
|
||||
return Function->getOutputAddress();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user