diff --git a/llvm/lib/Analysis/InlineSizeEstimatorAnalysis.cpp b/llvm/lib/Analysis/InlineSizeEstimatorAnalysis.cpp --- a/llvm/lib/Analysis/InlineSizeEstimatorAnalysis.cpp +++ b/llvm/lib/Analysis/InlineSizeEstimatorAnalysis.cpp @@ -67,8 +67,6 @@ static const size_t NumNamedFeatures = static_cast(NamedFeatureIndex::NumNamedFeatures); struct FunctionFeatures { - static std::vector> - ImportantInstructionSuccessions; static const size_t FeatureCount; std::array NamedFeatures = {0}; @@ -84,53 +82,38 @@ static FunctionFeatures getFunctionFeatures(Function &F, FunctionAnalysisManager &FAM); - -private: - /// Sort once the feature tuples. - struct SortFeatureTuples { - bool IsSorted = false; - SortFeatureTuples() { - std::sort(FunctionFeatures::ImportantInstructionSuccessions.begin(), - FunctionFeatures::ImportantInstructionSuccessions.end()); - IsSorted = true; - } - }; - - static llvm::ManagedStatic TupleSorter; - - static bool ensureSortedTuples() { return TupleSorter->IsSorted; } }; -llvm::ManagedStatic - IRToNativeSizeLearning::TupleSorter; // This is a point in time - we determined including these pairs of // consecutive instructions (in the IR layout available at inline time) as // features improves the model performance. We want to move away from manual // feature selection. -// The vector is given in opcode pairs rather than labels because 1) labels -// weren't readily available, and 2) the successions were hand - extracted -std::vector> - IRToNativeSizeLearning::FunctionFeatures::ImportantInstructionSuccessions = - {{1, 34}, {15, 27}, {53, 53}, {53, 34}, {1, 11}, {32, 2}, {2, 48}, - {28, 48}, {1, 45}, {49, 32}, {57, 56}, {55, 53}, {1, 28}, {57, 34}, - {1, 1}, {32, 28}, {32, 15}, {49, 28}, {53, 1}, {2, 53}, {48, 34}, - {28, 53}, {2, 32}, {1, 40}, {32, 48}, {29, 56}, {56, 32}, {55, 56}, - {48, 56}, {1, 31}, {33, 34}, {2, 28}, {1, 12}, {55, 1}, {31, 31}, - {65, 1}, {33, 56}, {32, 32}, {13, 13}, {1, 26}, {13, 26}, {2, 1}, - {1, 33}, {47, 49}, {64, 1}, {2, 38}, {34, 53}, {48, 2}, {55, 34}, - {34, 32}, {1, 5}, {56, 13}, {2, 2}, {2, 49}, {33, 2}, {49, 39}, - {56, 49}, {33, 49}, {32, 39}, {39, 57}, {29, 33}, {31, 34}, {32, 29}, - {47, 15}, {13, 34}, {2, 33}, {32, 49}, {49, 34}, {56, 33}, {1, 30}, - {33, 33}, {31, 33}, {2, 29}, {56, 7}, {32, 13}, {2, 55}, {56, 56}, - {2, 34}, {1, 42}, {34, 49}, {1, 20}, {32, 33}, {1, 25}, {53, 28}, - {1, 14}, {31, 49}, {28, 2}, {2, 13}, {2, 56}, {1, 32}, {56, 53}, - {65, 65}, {33, 53}, {64, 64}, {13, 2}, {34, 33}, {1, 4}, {49, 2}, - {1, 9}, {56, 1}, {33, 1}, {53, 57}, {32, 53}, {13, 56}, {32, 56}, - {55, 55}, {1, 18}, {49, 56}, {34, 34}, {1, 7}, {56, 64}, {32, 1}, - {13, 33}, {55, 28}, {49, 33}, {57, 57}, {56, 34}, {34, 56}, {33, 32}, - {32, 40}, {1, 29}, {53, 2}, {34, 1}, {32, 34}, {49, 49}, {1, 24}, - {40, 34}, {1, 13}, {38, 34}, {29, 2}, {34, 2}, {1, 39}, {1, 22}, - {1, 27}, {49, 1}, {1, 8}, {56, 2}}; +// The array is given in opcode pairs rather than labels because 1) labels +// weren't readily available, and 2) the successions were hand - extracted. +// +// This array must be sorted. +static const std::array, 137> + ImportantInstructionSuccessions{ + {{1, 1}, {1, 4}, {1, 5}, {1, 7}, {1, 8}, {1, 9}, {1, 11}, + {1, 12}, {1, 13}, {1, 14}, {1, 18}, {1, 20}, {1, 22}, {1, 24}, + {1, 25}, {1, 26}, {1, 27}, {1, 28}, {1, 29}, {1, 30}, {1, 31}, + {1, 32}, {1, 33}, {1, 34}, {1, 39}, {1, 40}, {1, 42}, {1, 45}, + {2, 1}, {2, 2}, {2, 13}, {2, 28}, {2, 29}, {2, 32}, {2, 33}, + {2, 34}, {2, 38}, {2, 48}, {2, 49}, {2, 53}, {2, 55}, {2, 56}, + {13, 2}, {13, 13}, {13, 26}, {13, 33}, {13, 34}, {13, 56}, {15, 27}, + {28, 2}, {28, 48}, {28, 53}, {29, 2}, {29, 33}, {29, 56}, {31, 31}, + {31, 33}, {31, 34}, {31, 49}, {32, 1}, {32, 2}, {32, 13}, {32, 15}, + {32, 28}, {32, 29}, {32, 32}, {32, 33}, {32, 34}, {32, 39}, {32, 40}, + {32, 48}, {32, 49}, {32, 53}, {32, 56}, {33, 1}, {33, 2}, {33, 32}, + {33, 33}, {33, 34}, {33, 49}, {33, 53}, {33, 56}, {34, 1}, {34, 2}, + {34, 32}, {34, 33}, {34, 34}, {34, 49}, {34, 53}, {34, 56}, {38, 34}, + {39, 57}, {40, 34}, {47, 15}, {47, 49}, {48, 2}, {48, 34}, {48, 56}, + {49, 1}, {49, 2}, {49, 28}, {49, 32}, {49, 33}, {49, 34}, {49, 39}, + {49, 49}, {49, 56}, {53, 1}, {53, 2}, {53, 28}, {53, 34}, {53, 53}, + {53, 57}, {55, 1}, {55, 28}, {55, 34}, {55, 53}, {55, 55}, {55, 56}, + {56, 1}, {56, 2}, {56, 7}, {56, 13}, {56, 32}, {56, 33}, {56, 34}, + {56, 49}, {56, 53}, {56, 56}, {56, 64}, {57, 34}, {57, 56}, {57, 57}, + {64, 1}, {64, 64}, {65, 1}, {65, 65}}}; // We have: 9 calculated features (the features here); 1 feature for each // instruction opcode; and 1 feature for each manually-identified sequence. @@ -140,14 +123,13 @@ // Note that instruction opcodes start from 1. For convenience, we also have an // always 0 feature for the '0' opcode, hence the extra 1. const size_t IRToNativeSizeLearning::FunctionFeatures::FeatureCount = - IRToNativeSizeLearning::FunctionFeatures::ImportantInstructionSuccessions - .size() + - getMaxInstructionID() + 1 + IRToNativeSizeLearning::NumNamedFeatures; + ImportantInstructionSuccessions.size() + getMaxInstructionID() + 1 + + IRToNativeSizeLearning::NumNamedFeatures; size_t getSize(Function &F, TargetTransformInfo &TTI) { size_t Ret = 0; - for (auto &BB : F) - for (auto &I : BB) + for (const auto &BB : F) + for (const auto &I : BB) Ret += TTI.getInstructionCost( &I, TargetTransformInfo::TargetCostKind::TCK_CodeSize); return Ret; @@ -161,8 +143,8 @@ unsigned getMaxDominatorTreeDepth(const Function &F, const DominatorTree &Tree) { unsigned Ret = 0; - for (auto &BB : F) - if (auto *TN = Tree.getNode(&BB)) + for (const auto &BB : F) + if (const auto *TN = Tree.getNode(&BB)) Ret = std::max(Ret, TN->getLevel()); return Ret; } @@ -171,42 +153,37 @@ IRToNativeSizeLearning::FunctionFeatures IRToNativeSizeLearning::getFunctionFeatures(Function &F, FunctionAnalysisManager &FAM) { - ensureSortedTuples(); + assert(llvm::is_sorted(ImportantInstructionSuccessions) && + "expected function features are sorted"); auto &DomTree = FAM.getResult(F); FunctionFeatures FF; size_t InstrCount = getMaxInstructionID() + 1; FF.InstructionHistogram.resize(InstrCount); - FF.InstructionPairHistogram.resize( - FunctionFeatures::ImportantInstructionSuccessions.size()); + FF.InstructionPairHistogram.resize(ImportantInstructionSuccessions.size()); - auto StartID = 0; - auto LastID = StartID; + int StartID = 0; + int LastID = StartID; auto getPairIndex = [](size_t a, size_t b) { - auto I = - std::find(FunctionFeatures::ImportantInstructionSuccessions.begin(), - FunctionFeatures::ImportantInstructionSuccessions.end(), - std::make_pair(a, b)); - if (I == FunctionFeatures::ImportantInstructionSuccessions.end()) + auto I = llvm::find(ImportantInstructionSuccessions, std::make_pair(a, b)); + if (I == ImportantInstructionSuccessions.end()) return -1; - return static_cast(std::distance( - FunctionFeatures::ImportantInstructionSuccessions.begin(), I)); + return static_cast( + std::distance(ImportantInstructionSuccessions.begin(), I)); }; // We don't want debug calls, because they'd just add noise. - for (auto &BB : F) { - for (auto I = BB.instructionsWithoutDebug().begin(), - E = BB.instructionsWithoutDebug().end(); - I != E; ++I) { - auto ID = I->getOpcode(); + for (const auto &BB : F) { + for (const auto &I : BB.instructionsWithoutDebug()) { + auto ID = I.getOpcode(); ++FF.InstructionHistogram[ID]; int PairIndex = getPairIndex(LastID, ID); if (PairIndex >= 0) ++FF.InstructionPairHistogram[PairIndex]; LastID = ID; - if (isa(*I)) + if (isa(I)) ++FF[NamedFeatureIndex::Calls]; } }