From ef7803217a401e7be14ea26d70f12fb3ec7da66f Mon Sep 17 00:00:00 2001 From: Andrew Lenharth Date: Thu, 4 Sep 2008 14:34:22 +0000 Subject: cleanup as per Duncan's review git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55766 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/PartialSpecialization.cpp | 75 ++++++++++++++++------------ 1 file changed, 42 insertions(+), 33 deletions(-) (limited to 'lib/Transforms/IPO') diff --git a/lib/Transforms/IPO/PartialSpecialization.cpp b/lib/Transforms/IPO/PartialSpecialization.cpp index 1774c97f8c..d39ea58ab6 100644 --- a/lib/Transforms/IPO/PartialSpecialization.cpp +++ b/lib/Transforms/IPO/PartialSpecialization.cpp @@ -10,7 +10,11 @@ // This pass finds function arguments that are often a common constant and // specializes a version of the called function for that constant. // -// The initial heuristic favors constant arguments that used in control flow. +// This pass simply does the cloning for functions it specializes. It depends +// on IPSCCP and DAE to clean up the results. +// +// The initial heuristic favors constant arguments that are used in control +// flow. // //===----------------------------------------------------------------------===// @@ -24,19 +28,19 @@ #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Support/Compiler.h" #include -#include using namespace llvm; STATISTIC(numSpecialized, "Number of specialized functions created"); -//Call must be used at least occasionally +// Call must be used at least occasionally static const int CallsMin = 5; -//Must have 10% of calls having the same constant to specialize on + +// Must have 10% of calls having the same constant to specialize on static const double ConstValPercent = .1; namespace { class VISIBILITY_HIDDEN PartSpec : public ModulePass { - void scanForInterest(Function&, std::vector&); + void scanForInterest(Function&, SmallVector&); void replaceUsersFor(Function&, int, Constant*, Function*); int scanDistribution(Function&, int, std::map&); public : @@ -54,41 +58,43 @@ bool PartSpec::runOnModule(Module &M) { bool Changed = false; for (Module::iterator I = M.begin(); I != M.end(); ++I) { Function &F = *I; - if (!F.isDeclaration()) { - std::vector interestingArgs; - scanForInterest(F, interestingArgs); - //Find the first interesting Argument that we can specialize on - //If there are multiple intersting Arguments, then those will be found - //when processing the cloned function. - bool breakOuter = false; - for (unsigned int x = 0; !breakOuter && x < interestingArgs.size(); ++x) { - std::map distribution; - int total = scanDistribution(F, interestingArgs[x], distribution); - if (total > CallsMin) - for (std::map::iterator ii = distribution.begin(), - ee = distribution.end(); ii != ee; ++ii) - if ( total > ii->second && ii->first && - ii->second > total * ConstValPercent ) { - Function* NF = CloneFunction(&F); - NF->setLinkage(GlobalValue::InternalLinkage); - M.getFunctionList().push_back(NF); - replaceUsersFor(F, interestingArgs[x], ii->first, NF); - breakOuter = true; - Changed = true; - } - } + if (F.isDeclaration()) continue; + SmallVector interestingArgs; + scanForInterest(F, interestingArgs); + + // Find the first interesting Argument that we can specialize on + // If there are multiple interesting Arguments, then those will be found + // when processing the cloned function. + bool breakOuter = false; + for (unsigned int x = 0; !breakOuter && x < interestingArgs.size(); ++x) { + std::map distribution; + int total = scanDistribution(F, interestingArgs[x], distribution); + if (total > CallsMin) + for (std::map::iterator ii = distribution.begin(), + ee = distribution.end(); ii != ee; ++ii) + if (total > ii->second && ii->first && + ii->second > total * ConstValPercent) { + Function* NF = CloneFunction(&F); + NF->setLinkage(GlobalValue::InternalLinkage); + M.getFunctionList().push_back(NF); + replaceUsersFor(F, interestingArgs[x], ii->first, NF); + breakOuter = true; + Changed = true; + } } } return Changed; } /// scanForInterest - This function decides which arguments would be worth -/// specializing on. -void PartSpec::scanForInterest(Function& F, std::vector& args) { +/// specializing on. +void PartSpec::scanForInterest(Function& F, SmallVector& args) { for(Function::arg_iterator ii = F.arg_begin(), ee = F.arg_end(); ii != ee; ++ii) { for(Value::use_iterator ui = ii->use_begin(), ue = ii->use_end(); ui != ue; ++ui) { + // As an initial proxy for control flow, specialize on arguments + // that are used in comparisons. if (isa(ui)) { args.push_back(std::distance(F.arg_begin(), ii)); break; @@ -111,7 +117,7 @@ void PartSpec::replaceUsersFor(Function& F , int argnum, Constant* val, int PartSpec::scanDistribution(Function& F, int arg, std::map& dist) { - bool hasInd = false; + bool hasIndirect = false; int total = 0; for(Value::use_iterator ii = F.use_begin(), ee = F.use_end(); ii != ee; ++ii) @@ -119,8 +125,11 @@ int PartSpec::scanDistribution(Function& F, int arg, ++dist[dyn_cast(CI->getOperand(arg + 1))]; ++total; } else - hasInd = true; - if (hasInd) ++total; + hasIndirect = true; + + // Preserve the original address taken function even if all other uses + // will be specialized. + if (hasIndirect) ++total; return total; } -- cgit v1.2.3