forked from OSchip/llvm-project
[ICF] Don't re-fold functions in non-relocation mode.
Summary: In-non relocation mode, when we run ICF the second time, we fold the same functions again since they were not removed from the function set. This diff marks them as folded and ignores them during ICF optimization. Note that we still want to optimize such functions since they are potentially called from the code not covered by BOLT in non-relocation mode. Folded functions are also excluded from dyno stats with this diff Also print the number of times folded functions were called. When 2 functions - f1() and f2() are folded, that number would be min(call_frequency(f1), call_frequency(f2)). (cherry picked from FBD4399993)
This commit is contained in:
parent
bc8a456309
commit
0894905373
|
@ -104,6 +104,7 @@ void BinaryContext::foldFunction(BinaryFunction &ChildBF,
|
|||
ChildBF.Names.clear();
|
||||
ChildBF.Names.push_back(NewName);
|
||||
ChildBF.OutputSymbol = Ctx->getOrCreateSymbol(NewName);
|
||||
ChildBF.setFolded();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3531,6 +3531,11 @@ DynoStats BinaryFunction::getDynoStats() const {
|
|||
if (!isSimple() || !hasValidProfile())
|
||||
return Stats;
|
||||
|
||||
// If the function was folded in non-relocation mode we keep its profile
|
||||
// for optimization. However, it should be excluded from the dyno stats.
|
||||
if (isFolded())
|
||||
return Stats;
|
||||
|
||||
// Update enumeration of basic blocks for correct detection of branch'
|
||||
// direction.
|
||||
updateLayoutIndices();
|
||||
|
|
|
@ -253,6 +253,10 @@ private:
|
|||
/// True if the function has more than one entry point.
|
||||
bool IsMultiEntry{false};
|
||||
|
||||
/// Indicate if the function body was folded into another function. Used
|
||||
/// for ICF optimization without relocations.
|
||||
bool IsFolded{false};
|
||||
|
||||
/// The address for the code for this function in codegen memory.
|
||||
uint64_t ImageAddress{0};
|
||||
|
||||
|
@ -1019,6 +1023,10 @@ public:
|
|||
return IsMultiEntry;
|
||||
}
|
||||
|
||||
bool isFolded() const {
|
||||
return IsFolded;
|
||||
}
|
||||
|
||||
/// Return true if the function uses jump tables.
|
||||
bool hasJumpTables() const {
|
||||
return JumpTables.size();
|
||||
|
@ -1291,6 +1299,11 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
BinaryFunction &setFolded(bool Folded = true) {
|
||||
IsFolded = Folded;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryFunction &setPersonalityFunction(uint64_t Addr) {
|
||||
PersonalityFunction = BC.getOrCreateGlobalSymbol(Addr, "FUNCat");
|
||||
return *this;
|
||||
|
|
|
@ -1330,6 +1330,7 @@ void IdenticalCodeFolding::runOnFunctions(BinaryContext &BC,
|
|||
uint64_t NumFunctionsFolded = 0;
|
||||
uint64_t NumJTFunctionsFolded = 0;
|
||||
uint64_t BytesSavedEstimate = 0;
|
||||
uint64_t CallsSavedEstimate = 0;
|
||||
static bool UseDFS = opts::UseDFSForICF;
|
||||
|
||||
// This hash table is used to identify identical functions. It maps
|
||||
|
@ -1356,7 +1357,7 @@ void IdenticalCodeFolding::runOnFunctions(BinaryContext &BC,
|
|||
KeyHash, KeyCongruent> CongruentBuckets;
|
||||
for (auto &BFI : BFs) {
|
||||
auto &BF = BFI.second;
|
||||
if (!shouldOptimize(BF))
|
||||
if (!shouldOptimize(BF) || BF.isFolded())
|
||||
continue;
|
||||
|
||||
// Make sure indices are in-order.
|
||||
|
@ -1414,9 +1415,11 @@ void IdenticalCodeFolding::runOnFunctions(BinaryContext &BC,
|
|||
Candidates.erase(FI);
|
||||
|
||||
// Fold the function and remove from the list of processed functions.
|
||||
BytesSavedEstimate += ChildBF->getSize();
|
||||
CallsSavedEstimate += std::min(ChildBF->getKnownExecutionCount(),
|
||||
ParentBF->getKnownExecutionCount());
|
||||
BC.foldFunction(*ChildBF, *ParentBF, BFs);
|
||||
|
||||
BytesSavedEstimate += ChildBF->getSize();
|
||||
++NumFoldedLastIteration;
|
||||
|
||||
if (ParentBF->hasJumpTables())
|
||||
|
@ -1456,7 +1459,8 @@ void IdenticalCodeFolding::runOnFunctions(BinaryContext &BC,
|
|||
<< NumJTFunctionsFolded << " functions had jump tables.\n"
|
||||
<< "BOLT-INFO: Removing all identical functions will save "
|
||||
<< format("%.2lf", (double) BytesSavedEstimate / 1024)
|
||||
<< " KB of code space.\n";
|
||||
<< " KB of code space. Folded functions were called "
|
||||
<< CallsSavedEstimate << " times based on profile.\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue