mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-04 17:56:53 +00:00
[Transforms] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).
llvm-svn: 316187
This commit is contained in:
parent
3781c30a61
commit
d9ca107b8e
@ -12,6 +12,7 @@
|
||||
|
||||
#include "llvm/Analysis/CGSCCPassManager.h"
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -26,6 +27,6 @@ public:
|
||||
LazyCallGraph &CG, CGSCCUpdateResult &UR);
|
||||
};
|
||||
|
||||
}
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_TRANSFORMS_IPO_ARGUMENTPROMOTION_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- FunctionAttrs.h - Compute function attrs --------------------------===//
|
||||
//===- FunctionAttrs.h - Compute function attributes ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -6,9 +6,11 @@
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
/// \file
|
||||
/// Provides passes for computing function attributes based on interprocedural
|
||||
/// analyses.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
|
||||
@ -21,6 +23,9 @@
|
||||
namespace llvm {
|
||||
|
||||
class AAResults;
|
||||
class Function;
|
||||
class Module;
|
||||
class Pass;
|
||||
|
||||
/// The three kinds of memory access relevant to 'readonly' and
|
||||
/// 'readnone' attributes.
|
||||
@ -66,6 +71,7 @@ class ReversePostOrderFunctionAttrsPass
|
||||
public:
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
|
||||
|
@ -14,15 +14,15 @@
|
||||
#include "llvm/Analysis/CallGraphSCCPass.h"
|
||||
#include "llvm/Analysis/InlineCost.h"
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h"
|
||||
#include <utility>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AssumptionCacheTracker;
|
||||
class CallSite;
|
||||
class DataLayout;
|
||||
class InlineCost;
|
||||
class OptimizationRemarkEmitter;
|
||||
class CallGraph;
|
||||
class ProfileSummaryInfo;
|
||||
|
||||
/// This class contains all of the helper code which is used to perform the
|
||||
@ -44,6 +44,7 @@ struct LegacyInlinerBase : public CallGraphSCCPass {
|
||||
bool runOnSCC(CallGraphSCC &SCC) override;
|
||||
|
||||
using llvm::Pass::doFinalization;
|
||||
|
||||
/// Remove now-dead linkonce functions at the end of processing to avoid
|
||||
/// breaking the SCC traversal.
|
||||
bool doFinalization(CallGraph &CG) override;
|
||||
@ -69,7 +70,7 @@ struct LegacyInlinerBase : public CallGraphSCCPass {
|
||||
|
||||
private:
|
||||
// Insert @llvm.lifetime intrinsics.
|
||||
bool InsertLifetime;
|
||||
bool InsertLifetime = true;
|
||||
|
||||
protected:
|
||||
AssumptionCacheTracker *ACT;
|
||||
@ -103,6 +104,6 @@ private:
|
||||
InlineParams Params;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_TRANSFORMS_IPO_INLINER_H
|
||||
|
@ -16,7 +16,6 @@
|
||||
#define LLVM_TRANSFORMS_IPO_LOWERTYPETESTS_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
@ -26,6 +25,7 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Module;
|
||||
class raw_ostream;
|
||||
|
||||
namespace lowertypetests {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- ArgumentPromotion.cpp - Promote by-reference arguments ------------===//
|
||||
//===- ArgumentPromotion.cpp - Promote by-reference arguments -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -31,30 +31,59 @@
|
||||
|
||||
#include "llvm/Transforms/IPO/ArgumentPromotion.h"
|
||||
#include "llvm/ADT/DepthFirstIterator.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/CGSCCPassManager.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/CallGraphSCCPass.h"
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
#include "llvm/Analysis/Loads.h"
|
||||
#include "llvm/Analysis/MemoryLocation.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/IR/Argument.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Use.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/IPO.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "argpromotion"
|
||||
@ -65,7 +94,7 @@ STATISTIC(NumByValArgsPromoted, "Number of byval arguments promoted");
|
||||
STATISTIC(NumArgumentsDead, "Number of dead pointer args eliminated");
|
||||
|
||||
/// A vector used to hold the indices of a single GEP instruction
|
||||
typedef std::vector<uint64_t> IndicesVector;
|
||||
using IndicesVector = std::vector<uint64_t>;
|
||||
|
||||
/// DoPromotion - This method actually performs the promotion of the specified
|
||||
/// arguments, and returns the new function. At this point, we know that it's
|
||||
@ -75,13 +104,12 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
|
||||
SmallPtrSetImpl<Argument *> &ByValArgsToTransform,
|
||||
Optional<function_ref<void(CallSite OldCS, CallSite NewCS)>>
|
||||
ReplaceCallSite) {
|
||||
|
||||
// Start by computing a new prototype for the function, which is the same as
|
||||
// the old function, but has modified arguments.
|
||||
FunctionType *FTy = F->getFunctionType();
|
||||
std::vector<Type *> Params;
|
||||
|
||||
typedef std::set<std::pair<Type *, IndicesVector>> ScalarizeTable;
|
||||
using ScalarizeTable = std::set<std::pair<Type *, IndicesVector>>;
|
||||
|
||||
// ScalarizedElements - If we are promoting a pointer that has elements
|
||||
// accessed out of it, keep track of which elements are accessed so that we
|
||||
@ -89,7 +117,6 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
|
||||
//
|
||||
// Arguments that are directly loaded will have a zero element value here, to
|
||||
// handle cases where there are both a direct load and GEP accesses.
|
||||
//
|
||||
std::map<Argument *, ScalarizeTable> ScalarizedElements;
|
||||
|
||||
// OriginalLoads - Keep track of a representative load instruction from the
|
||||
@ -335,7 +362,6 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
|
||||
|
||||
// Loop over the argument list, transferring uses of the old arguments over to
|
||||
// the new arguments, also transferring over the names as well.
|
||||
//
|
||||
for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(),
|
||||
I2 = NF->arg_begin();
|
||||
I != E; ++I) {
|
||||
@ -537,7 +563,7 @@ static void markIndicesSafe(const IndicesVector &ToMark,
|
||||
/// arguments passed in.
|
||||
static bool isSafeToPromoteArgument(Argument *Arg, bool isByValOrInAlloca,
|
||||
AAResults &AAR, unsigned MaxElements) {
|
||||
typedef std::set<IndicesVector> GEPIndicesSet;
|
||||
using GEPIndicesSet = std::set<IndicesVector>;
|
||||
|
||||
// Quick exit for unused arguments
|
||||
if (Arg->use_empty())
|
||||
@ -714,7 +740,6 @@ static bool isSafeToPromoteArgument(Argument *Arg, bool isByValOrInAlloca,
|
||||
|
||||
/// \brief Checks if a type could have padding bytes.
|
||||
static bool isDenselyPacked(Type *type, const DataLayout &DL) {
|
||||
|
||||
// There is no size information, so be conservative.
|
||||
if (!type->isSized())
|
||||
return false;
|
||||
@ -749,7 +774,6 @@ static bool isDenselyPacked(Type *type, const DataLayout &DL) {
|
||||
|
||||
/// \brief Checks if the padding bytes of an argument could be accessed.
|
||||
static bool canPaddingBeAccessed(Argument *arg) {
|
||||
|
||||
assert(arg->hasByValAttr());
|
||||
|
||||
// Track all the pointers to the argument to make sure they are not captured.
|
||||
@ -788,7 +812,6 @@ static bool canPaddingBeAccessed(Argument *arg) {
|
||||
/// are any promotable arguments and if it is safe to promote the function (for
|
||||
/// example, all callers are direct). If safe to promote some arguments, it
|
||||
/// calls the DoPromotion method.
|
||||
///
|
||||
static Function *
|
||||
promoteArguments(Function *F, function_ref<AAResults &(Function &F)> AARGetter,
|
||||
unsigned MaxElements,
|
||||
@ -964,9 +987,17 @@ PreservedAnalyses ArgumentPromotionPass::run(LazyCallGraph::SCC &C,
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// ArgPromotion - The 'by reference' to 'by value' argument promotion pass.
|
||||
///
|
||||
struct ArgPromotion : public CallGraphSCCPass {
|
||||
// Pass identification, replacement for typeid
|
||||
static char ID;
|
||||
|
||||
explicit ArgPromotion(unsigned MaxElements = 3)
|
||||
: CallGraphSCCPass(ID), MaxElements(MaxElements) {
|
||||
initializeArgPromotionPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
@ -975,21 +1006,20 @@ struct ArgPromotion : public CallGraphSCCPass {
|
||||
}
|
||||
|
||||
bool runOnSCC(CallGraphSCC &SCC) override;
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
explicit ArgPromotion(unsigned MaxElements = 3)
|
||||
: CallGraphSCCPass(ID), MaxElements(MaxElements) {
|
||||
initializeArgPromotionPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
private:
|
||||
using llvm::Pass::doInitialization;
|
||||
|
||||
bool doInitialization(CallGraph &CG) override;
|
||||
|
||||
/// The maximum number of elements to expand, or 0 for unlimited.
|
||||
unsigned MaxElements;
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char ArgPromotion::ID = 0;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(ArgPromotion, "argpromotion",
|
||||
"Promote 'by reference' arguments to scalars", false,
|
||||
false)
|
||||
|
@ -6,34 +6,61 @@
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
//
|
||||
/// \file
|
||||
/// This file implements interprocedural passes which walk the
|
||||
/// call-graph deducing and/or propagating function attributes.
|
||||
///
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/IPO/FunctionAttrs.h"
|
||||
#include "llvm/ADT/SCCIterator.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/CGSCCPassManager.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/CallGraphSCCPass.h"
|
||||
#include "llvm/Analysis/CaptureTracking.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
#include "llvm/Analysis/MemoryLocation.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/Argument.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/InstIterator.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Use.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/IPO.h"
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "functionattrs"
|
||||
@ -57,8 +84,10 @@ static cl::opt<bool> EnableNonnullArgPropagation(
|
||||
"caller functions."));
|
||||
|
||||
namespace {
|
||||
typedef SmallSetVector<Function *, 8> SCCNodeSet;
|
||||
}
|
||||
|
||||
using SCCNodeSet = SmallSetVector<Function *, 8>;
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// Returns the memory access attribute for function F using AAR for AA results,
|
||||
/// where SCCNodes is the current SCC.
|
||||
@ -237,6 +266,7 @@ static bool addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter) {
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// For a given pointer Argument, this retains a list of Arguments of functions
|
||||
/// in the same SCC that the pointer data flows into. We use this to build an
|
||||
/// SCC of the arguments.
|
||||
@ -248,7 +278,7 @@ struct ArgumentGraphNode {
|
||||
class ArgumentGraph {
|
||||
// We store pointers to ArgumentGraphNode objects, so it's important that
|
||||
// that they not move around upon insert.
|
||||
typedef std::map<Argument *, ArgumentGraphNode> ArgumentMapTy;
|
||||
using ArgumentMapTy = std::map<Argument *, ArgumentGraphNode>;
|
||||
|
||||
ArgumentMapTy ArgumentMap;
|
||||
|
||||
@ -263,7 +293,7 @@ class ArgumentGraph {
|
||||
public:
|
||||
ArgumentGraph() { SyntheticRoot.Definition = nullptr; }
|
||||
|
||||
typedef SmallVectorImpl<ArgumentGraphNode *>::iterator iterator;
|
||||
using iterator = SmallVectorImpl<ArgumentGraphNode *>::iterator;
|
||||
|
||||
iterator begin() { return SyntheticRoot.Uses.begin(); }
|
||||
iterator end() { return SyntheticRoot.Uses.end(); }
|
||||
@ -281,8 +311,7 @@ public:
|
||||
/// consider that a capture, instead adding it to the "Uses" list and
|
||||
/// continuing with the analysis.
|
||||
struct ArgumentUsesTracker : public CaptureTracker {
|
||||
ArgumentUsesTracker(const SCCNodeSet &SCCNodes)
|
||||
: Captured(false), SCCNodes(SCCNodes) {}
|
||||
ArgumentUsesTracker(const SCCNodeSet &SCCNodes) : SCCNodes(SCCNodes) {}
|
||||
|
||||
void tooManyUses() override { Captured = true; }
|
||||
|
||||
@ -331,37 +360,45 @@ struct ArgumentUsesTracker : public CaptureTracker {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Captured; // True only if certainly captured (used outside our SCC).
|
||||
SmallVector<Argument *, 4> Uses; // Uses within our SCC.
|
||||
// True only if certainly captured (used outside our SCC).
|
||||
bool Captured = false;
|
||||
|
||||
// Uses within our SCC.
|
||||
SmallVector<Argument *, 4> Uses;
|
||||
|
||||
const SCCNodeSet &SCCNodes;
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template <> struct GraphTraits<ArgumentGraphNode *> {
|
||||
typedef ArgumentGraphNode *NodeRef;
|
||||
typedef SmallVectorImpl<ArgumentGraphNode *>::iterator ChildIteratorType;
|
||||
using NodeRef = ArgumentGraphNode *;
|
||||
using ChildIteratorType = SmallVectorImpl<ArgumentGraphNode *>::iterator;
|
||||
|
||||
static NodeRef getEntryNode(NodeRef A) { return A; }
|
||||
static ChildIteratorType child_begin(NodeRef N) { return N->Uses.begin(); }
|
||||
static ChildIteratorType child_end(NodeRef N) { return N->Uses.end(); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct GraphTraits<ArgumentGraph *> : public GraphTraits<ArgumentGraphNode *> {
|
||||
static NodeRef getEntryNode(ArgumentGraph *AG) { return AG->getEntryNode(); }
|
||||
|
||||
static ChildIteratorType nodes_begin(ArgumentGraph *AG) {
|
||||
return AG->begin();
|
||||
}
|
||||
|
||||
static ChildIteratorType nodes_end(ArgumentGraph *AG) { return AG->end(); }
|
||||
};
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
/// Returns Attribute::None, Attribute::ReadOnly or Attribute::ReadNone.
|
||||
static Attribute::AttrKind
|
||||
determinePointerReadAttrs(Argument *A,
|
||||
const SmallPtrSet<Argument *, 8> &SCCNodes) {
|
||||
|
||||
SmallVector<Use *, 32> Worklist;
|
||||
SmallSet<Use *, 32> Visited;
|
||||
|
||||
@ -502,8 +539,8 @@ static bool addArgumentReturnedAttrs(const SCCNodeSet &SCCNodes) {
|
||||
continue;
|
||||
|
||||
// There is nothing to do if an argument is already marked as 'returned'.
|
||||
if (any_of(F->args(),
|
||||
[](const Argument &Arg) { return Arg.hasReturnedAttr(); }))
|
||||
if (llvm::any_of(F->args(),
|
||||
[](const Argument &Arg) { return Arg.hasReturnedAttr(); }))
|
||||
continue;
|
||||
|
||||
auto FindRetArg = [&]() -> Value * {
|
||||
@ -1137,8 +1174,11 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct PostOrderFunctionAttrsLegacyPass : public CallGraphSCCPass {
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
// Pass identification, replacement for typeid
|
||||
static char ID;
|
||||
|
||||
PostOrderFunctionAttrsLegacyPass() : CallGraphSCCPass(ID) {
|
||||
initializePostOrderFunctionAttrsLegacyPassPass(
|
||||
*PassRegistry::getPassRegistry());
|
||||
@ -1153,7 +1193,8 @@ struct PostOrderFunctionAttrsLegacyPass : public CallGraphSCCPass {
|
||||
CallGraphSCCPass::getAnalysisUsage(AU);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char PostOrderFunctionAttrsLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(PostOrderFunctionAttrsLegacyPass, "functionattrs",
|
||||
@ -1216,8 +1257,11 @@ bool PostOrderFunctionAttrsLegacyPass::runOnSCC(CallGraphSCC &SCC) {
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct ReversePostOrderFunctionAttrsLegacyPass : public ModulePass {
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
// Pass identification, replacement for typeid
|
||||
static char ID;
|
||||
|
||||
ReversePostOrderFunctionAttrsLegacyPass() : ModulePass(ID) {
|
||||
initializeReversePostOrderFunctionAttrsLegacyPassPass(
|
||||
*PassRegistry::getPassRegistry());
|
||||
@ -1231,9 +1275,11 @@ struct ReversePostOrderFunctionAttrsLegacyPass : public ModulePass {
|
||||
AU.addPreserved<CallGraphWrapperPass>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char ReversePostOrderFunctionAttrsLegacyPass::ID = 0;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(ReversePostOrderFunctionAttrsLegacyPass, "rpo-functionattrs",
|
||||
"Deduce function attributes in RPO", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
|
||||
@ -1293,7 +1339,7 @@ static bool deduceFunctionAttributeInRPO(Module &M, CallGraph &CG) {
|
||||
}
|
||||
|
||||
bool Changed = false;
|
||||
for (auto *F : reverse(Worklist))
|
||||
for (auto *F : llvm::reverse(Worklist))
|
||||
Changed |= addNoRecurseAttrsTopDown(*F);
|
||||
|
||||
return Changed;
|
||||
|
@ -14,29 +14,60 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/IPO/Inliner.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/BlockFrequencyInfo.h"
|
||||
#include "llvm/Analysis/CGSCCPassManager.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/InlineCost.h"
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/InstIterator.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Utils/Cloning.h"
|
||||
#include "llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include "llvm/Transforms/Utils/ModuleUtils.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "inline"
|
||||
@ -63,13 +94,16 @@ static cl::opt<bool>
|
||||
cl::init(false), cl::Hidden);
|
||||
|
||||
namespace {
|
||||
|
||||
enum class InlinerFunctionImportStatsOpts {
|
||||
No = 0,
|
||||
Basic = 1,
|
||||
Verbose = 2,
|
||||
};
|
||||
|
||||
cl::opt<InlinerFunctionImportStatsOpts> InlinerFunctionImportStats(
|
||||
} // end anonymous namespace
|
||||
|
||||
static cl::opt<InlinerFunctionImportStatsOpts> InlinerFunctionImportStats(
|
||||
"inliner-function-import-stats",
|
||||
cl::init(InlinerFunctionImportStatsOpts::No),
|
||||
cl::values(clEnumValN(InlinerFunctionImportStatsOpts::Basic, "basic",
|
||||
@ -77,10 +111,8 @@ cl::opt<InlinerFunctionImportStatsOpts> InlinerFunctionImportStats(
|
||||
clEnumValN(InlinerFunctionImportStatsOpts::Verbose, "verbose",
|
||||
"printing of statistics for each inlined function")),
|
||||
cl::Hidden, cl::desc("Enable inliner stats for imported functions"));
|
||||
} // namespace
|
||||
|
||||
LegacyInlinerBase::LegacyInlinerBase(char &ID)
|
||||
: CallGraphSCCPass(ID), InsertLifetime(true) {}
|
||||
LegacyInlinerBase::LegacyInlinerBase(char &ID) : CallGraphSCCPass(ID) {}
|
||||
|
||||
LegacyInlinerBase::LegacyInlinerBase(char &ID, bool InsertLifetime)
|
||||
: CallGraphSCCPass(ID), InsertLifetime(InsertLifetime) {}
|
||||
@ -96,7 +128,7 @@ void LegacyInlinerBase::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
CallGraphSCCPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
typedef DenseMap<ArrayType *, std::vector<AllocaInst *>> InlinedArrayAllocasTy;
|
||||
using InlinedArrayAllocasTy = DenseMap<ArrayType *, std::vector<AllocaInst *>>;
|
||||
|
||||
/// Look at all of the allocas that we inlined through this call site. If we
|
||||
/// have already inlined other allocas through other calls into this function,
|
||||
@ -161,7 +193,6 @@ static void mergeInlinedArrayAllocas(
|
||||
// function. Also, AllocasForType can be empty of course!
|
||||
bool MergedAwayAlloca = false;
|
||||
for (AllocaInst *AvailableAlloca : AllocasForType) {
|
||||
|
||||
unsigned Align1 = AI->getAlignment(),
|
||||
Align2 = AvailableAlloca->getAlignment();
|
||||
|
||||
@ -267,7 +298,6 @@ static bool
|
||||
shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
|
||||
int &TotalSecondaryCost,
|
||||
function_ref<InlineCost(CallSite CS)> GetInlineCost) {
|
||||
|
||||
// For now we only handle local or inline functions.
|
||||
if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
|
||||
return false;
|
||||
@ -342,6 +372,7 @@ static Optional<InlineCost>
|
||||
shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
|
||||
OptimizationRemarkEmitter &ORE) {
|
||||
using namespace ore;
|
||||
|
||||
InlineCost IC = GetInlineCost(CS);
|
||||
Instruction *Call = CS.getInstruction();
|
||||
Function *Callee = CS.getCalledFunction();
|
||||
@ -478,6 +509,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
|
||||
if (Function *Callee = CS.getCalledFunction())
|
||||
if (Callee->isDeclaration()) {
|
||||
using namespace ore;
|
||||
|
||||
ORE.emit([&]() {
|
||||
return OptimizationRemarkMissed(DEBUG_TYPE, "NoDefinition", &I)
|
||||
<< NV("Callee", Callee) << " will not be inlined into "
|
||||
@ -573,6 +605,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
|
||||
|
||||
// Attempt to inline the function.
|
||||
using namespace ore;
|
||||
|
||||
if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas,
|
||||
InlineHistoryID, InsertLifetime, AARGetter,
|
||||
ImportedFunctionsStats)) {
|
||||
@ -620,7 +653,6 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
|
||||
if (Callee && Callee->use_empty() && Callee->hasLocalLinkage() &&
|
||||
// TODO: Can remove if in SCC now.
|
||||
!SCCFunctions.count(Callee) &&
|
||||
|
||||
// The function may be apparently dead, but if there are indirect
|
||||
// callgraph references to the node, we cannot delete it yet, this
|
||||
// could invalidate the CGSCC iterator.
|
||||
@ -922,6 +954,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
|
||||
BasicBlock *Block = CS.getParent();
|
||||
|
||||
using namespace ore;
|
||||
|
||||
if (!InlineFunction(CS, IFI)) {
|
||||
ORE.emit([&]() {
|
||||
return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- LowerTypeTests.cpp - type metadata lowering pass ------------------===//
|
||||
//===- LowerTypeTests.cpp - type metadata lowering pass -------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -13,32 +13,70 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/IPO/LowerTypeTests.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/EquivalenceClasses.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/TinyPtrVector.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Analysis/TypeMetadataUtils.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/GlobalAlias.h"
|
||||
#include "llvm/IR/GlobalObject.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/InlineAsm.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/IR/ModuleSummaryIndexYAML.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Use.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/TrailingObjects.h"
|
||||
#include "llvm/Support/YAMLTraits.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/IPO.h"
|
||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||
#include "llvm/Transforms/Utils/ModuleUtils.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace lowertypetests;
|
||||
@ -206,16 +244,19 @@ struct ByteArrayInfo {
|
||||
/// operation involving a map lookup; this data structure helps to reduce the
|
||||
/// number of times we need to do this lookup.
|
||||
class GlobalTypeMember final : TrailingObjects<GlobalTypeMember, MDNode *> {
|
||||
friend TrailingObjects;
|
||||
|
||||
GlobalObject *GO;
|
||||
size_t NTypes;
|
||||
|
||||
// For functions: true if this is a definition (either in the merged module or
|
||||
// in one of the thinlto modules).
|
||||
bool IsDefinition;
|
||||
|
||||
// For functions: true if this function is either defined or used in a thinlto
|
||||
// module and its jumptable entry needs to be exported to thinlto backends.
|
||||
bool IsExported;
|
||||
|
||||
friend TrailingObjects;
|
||||
size_t numTrailingObjects(OverloadToken<MDNode *>) const { return NTypes; }
|
||||
|
||||
public:
|
||||
@ -232,15 +273,19 @@ public:
|
||||
GTM->getTrailingObjects<MDNode *>());
|
||||
return GTM;
|
||||
}
|
||||
|
||||
GlobalObject *getGlobal() const {
|
||||
return GO;
|
||||
}
|
||||
|
||||
bool isDefinition() const {
|
||||
return IsDefinition;
|
||||
}
|
||||
|
||||
bool isExported() const {
|
||||
return IsExported;
|
||||
}
|
||||
|
||||
ArrayRef<MDNode *> types() const {
|
||||
return makeArrayRef(getTrailingObjects<MDNode *>(), NTypes);
|
||||
}
|
||||
@ -354,6 +399,7 @@ class LowerTypeTestsModule {
|
||||
public:
|
||||
LowerTypeTestsModule(Module &M, ModuleSummaryIndex *ExportSummary,
|
||||
const ModuleSummaryIndex *ImportSummary);
|
||||
|
||||
bool lower();
|
||||
|
||||
// Lower the module using the action and summary passed as command line
|
||||
@ -389,11 +435,12 @@ struct LowerTypeTests : public ModulePass {
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
} // end anonymous namespace
|
||||
|
||||
char LowerTypeTests::ID = 0;
|
||||
|
||||
INITIALIZE_PASS(LowerTypeTests, "lowertypetests", "Lower type metadata", false,
|
||||
false)
|
||||
char LowerTypeTests::ID = 0;
|
||||
|
||||
ModulePass *
|
||||
llvm::createLowerTypeTestsPass(ModuleSummaryIndex *ExportSummary,
|
||||
@ -1192,7 +1239,7 @@ void LowerTypeTestsModule::createJumpTable(
|
||||
// Luckily, this function does not get any prologue even without the
|
||||
// attribute.
|
||||
if (OS != Triple::Win32)
|
||||
F->addFnAttr(llvm::Attribute::Naked);
|
||||
F->addFnAttr(Attribute::Naked);
|
||||
if (JumpTableArch == Triple::arm)
|
||||
F->addFnAttr("target-features", "-thumb-mode");
|
||||
if (JumpTableArch == Triple::thumb) {
|
||||
@ -1401,7 +1448,7 @@ void LowerTypeTestsModule::buildBitSetsFromFunctionsWASM(
|
||||
|
||||
void LowerTypeTestsModule::buildBitSetsFromDisjointSet(
|
||||
ArrayRef<Metadata *> TypeIds, ArrayRef<GlobalTypeMember *> Globals) {
|
||||
llvm::DenseMap<Metadata *, uint64_t> TypeIdIndices;
|
||||
DenseMap<Metadata *, uint64_t> TypeIdIndices;
|
||||
for (unsigned I = 0; I != TypeIds.size(); ++I)
|
||||
TypeIdIndices[TypeIds[I]] = I;
|
||||
|
||||
@ -1555,8 +1602,8 @@ bool LowerTypeTestsModule::lower() {
|
||||
// Equivalence class set containing type identifiers and the globals that
|
||||
// reference them. This is used to partition the set of type identifiers in
|
||||
// the module into disjoint sets.
|
||||
typedef EquivalenceClasses<PointerUnion<GlobalTypeMember *, Metadata *>>
|
||||
GlobalClassesTy;
|
||||
using GlobalClassesTy =
|
||||
EquivalenceClasses<PointerUnion<GlobalTypeMember *, Metadata *>>;
|
||||
GlobalClassesTy GlobalClasses;
|
||||
|
||||
// Verify the type metadata and build a few data structures to let us
|
||||
@ -1571,7 +1618,7 @@ bool LowerTypeTestsModule::lower() {
|
||||
unsigned Index;
|
||||
std::vector<GlobalTypeMember *> RefGlobals;
|
||||
};
|
||||
llvm::DenseMap<Metadata *, TIInfo> TypeIdInfo;
|
||||
DenseMap<Metadata *, TIInfo> TypeIdInfo;
|
||||
unsigned I = 0;
|
||||
SmallVector<MDNode *, 2> Types;
|
||||
|
||||
|
@ -89,28 +89,45 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/IR/Argument.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Use.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/IR/ValueMap.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/IPO.h"
|
||||
#include "llvm/Transforms/Utils/FunctionComparator.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
@ -153,10 +170,12 @@ namespace {
|
||||
class FunctionNode {
|
||||
mutable AssertingVH<Function> F;
|
||||
FunctionComparator::FunctionHash Hash;
|
||||
|
||||
public:
|
||||
// Note the hash is recalculated potentially multiple times, but it is cheap.
|
||||
FunctionNode(Function *F)
|
||||
: F(F), Hash(FunctionComparator::functionHash(*F)) {}
|
||||
|
||||
Function *getFunc() const { return F; }
|
||||
FunctionComparator::FunctionHash getHash() const { return Hash; }
|
||||
|
||||
@ -173,12 +192,12 @@ public:
|
||||
/// by considering all pointer types to be equivalent. Once identified,
|
||||
/// MergeFunctions will fold them by replacing a call to one to a call to a
|
||||
/// bitcast of the other.
|
||||
///
|
||||
class MergeFunctions : public ModulePass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
MergeFunctions()
|
||||
: ModulePass(ID), FnTree(FunctionNodeCmp(&GlobalNumbers)), FNodesInTree() {
|
||||
: ModulePass(ID), FnTree(FunctionNodeCmp(&GlobalNumbers)) {
|
||||
initializeMergeFunctionsPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
@ -189,8 +208,10 @@ private:
|
||||
// not need to become larger with another pointer.
|
||||
class FunctionNodeCmp {
|
||||
GlobalNumberState* GlobalNumbers;
|
||||
|
||||
public:
|
||||
FunctionNodeCmp(GlobalNumberState* GN) : GlobalNumbers(GN) {}
|
||||
|
||||
bool operator()(const FunctionNode &LHS, const FunctionNode &RHS) const {
|
||||
// Order first by hashes, then full function comparison.
|
||||
if (LHS.getHash() != RHS.getHash())
|
||||
@ -199,7 +220,7 @@ private:
|
||||
return FCmp.compare() == -1;
|
||||
}
|
||||
};
|
||||
typedef std::set<FunctionNode, FunctionNodeCmp> FnTreeType;
|
||||
using FnTreeType = std::set<FunctionNode, FunctionNodeCmp>;
|
||||
|
||||
GlobalNumberState GlobalNumbers;
|
||||
|
||||
@ -207,9 +228,9 @@ private:
|
||||
/// analyzed again.
|
||||
std::vector<WeakTrackingVH> Deferred;
|
||||
|
||||
#ifndef NDEBUG
|
||||
/// Checks the rules of order relation introduced among functions set.
|
||||
/// Returns true, if sanity check has been passed, and false if failed.
|
||||
#ifndef NDEBUG
|
||||
bool doSanityCheck(std::vector<WeakTrackingVH> &Worklist);
|
||||
#endif
|
||||
|
||||
@ -257,6 +278,7 @@ private:
|
||||
/// The set of all distinct functions. Use the insert() and remove() methods
|
||||
/// to modify it. The map allows efficient lookup and deferring of Functions.
|
||||
FnTreeType FnTree;
|
||||
|
||||
// Map functions to the iterators of the FunctionNode which contains them
|
||||
// in the FnTree. This must be updated carefully whenever the FnTree is
|
||||
// modified, i.e. in insert(), remove(), and replaceFunctionInTree(), to avoid
|
||||
@ -268,6 +290,7 @@ private:
|
||||
} // end anonymous namespace
|
||||
|
||||
char MergeFunctions::ID = 0;
|
||||
|
||||
INITIALIZE_PASS(MergeFunctions, "mergefunc", "Merge Functions", false, false)
|
||||
|
||||
ModulePass *llvm::createMergeFunctionsPass() {
|
||||
@ -475,7 +498,6 @@ static Value *createCast(IRBuilder<> &Builder, Value *V, Type *DestTy) {
|
||||
// parameter debug info, from the entry block.
|
||||
void MergeFunctions::eraseInstsUnrelatedToPDI(
|
||||
std::vector<Instruction *> &PDIUnrelatedWL) {
|
||||
|
||||
DEBUG(dbgs() << " Erasing instructions (in reverse order of appearance in "
|
||||
"entry block) unrelated to parameter debug info from entry "
|
||||
"block: {\n");
|
||||
@ -493,7 +515,6 @@ void MergeFunctions::eraseInstsUnrelatedToPDI(
|
||||
|
||||
// Reduce G to its entry block.
|
||||
void MergeFunctions::eraseTail(Function *G) {
|
||||
|
||||
std::vector<BasicBlock *> WorklistBB;
|
||||
for (Function::iterator BBI = std::next(G->begin()), BBE = G->end();
|
||||
BBI != BBE; ++BBI) {
|
||||
@ -518,7 +539,6 @@ void MergeFunctions::eraseTail(Function *G) {
|
||||
// PDIUnrelatedWL with such instructions.
|
||||
void MergeFunctions::filterInstsUnrelatedToPDI(
|
||||
BasicBlock *GEntryBlock, std::vector<Instruction *> &PDIUnrelatedWL) {
|
||||
|
||||
std::set<Instruction *> PDIRelated;
|
||||
for (BasicBlock::iterator BI = GEntryBlock->begin(), BIE = GEntryBlock->end();
|
||||
BI != BIE; ++BI) {
|
||||
@ -686,7 +706,7 @@ void MergeFunctions::writeThunk(Function *F, Function *G) {
|
||||
SmallVector<Value *, 16> Args;
|
||||
unsigned i = 0;
|
||||
FunctionType *FFTy = F->getFunctionType();
|
||||
for (Argument & AI : H->args()) {
|
||||
for (Argument &AI : H->args()) {
|
||||
Args.push_back(createCast(Builder, &AI, FFTy->getParamType(i)));
|
||||
++i;
|
||||
}
|
||||
|
@ -23,42 +23,64 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/SampleProfile.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/InlineCost.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||
#include "llvm/Analysis/PostDominators.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/InstIterator.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/MDBuilder.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/ValueSymbolTable.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/ProfileData/InstrProf.h"
|
||||
#include "llvm/ProfileData/SampleProf.h"
|
||||
#include "llvm/ProfileData/SampleProfReader.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/GenericDomTree.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/IPO.h"
|
||||
#include "llvm/Transforms/Instrumentation.h"
|
||||
#include "llvm/Transforms/Utils/Cloning.h"
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace sampleprof;
|
||||
@ -70,34 +92,39 @@ using namespace sampleprof;
|
||||
static cl::opt<std::string> SampleProfileFile(
|
||||
"sample-profile-file", cl::init(""), cl::value_desc("filename"),
|
||||
cl::desc("Profile file loaded by -sample-profile"), cl::Hidden);
|
||||
|
||||
static cl::opt<unsigned> SampleProfileMaxPropagateIterations(
|
||||
"sample-profile-max-propagate-iterations", cl::init(100),
|
||||
cl::desc("Maximum number of iterations to go through when propagating "
|
||||
"sample block/edge weights through the CFG."));
|
||||
|
||||
static cl::opt<unsigned> SampleProfileRecordCoverage(
|
||||
"sample-profile-check-record-coverage", cl::init(0), cl::value_desc("N"),
|
||||
cl::desc("Emit a warning if less than N% of records in the input profile "
|
||||
"are matched to the IR."));
|
||||
|
||||
static cl::opt<unsigned> SampleProfileSampleCoverage(
|
||||
"sample-profile-check-sample-coverage", cl::init(0), cl::value_desc("N"),
|
||||
cl::desc("Emit a warning if less than N% of samples in the input profile "
|
||||
"are matched to the IR."));
|
||||
|
||||
static cl::opt<double> SampleProfileHotThreshold(
|
||||
"sample-profile-inline-hot-threshold", cl::init(0.1), cl::value_desc("N"),
|
||||
cl::desc("Inlined functions that account for more than N% of all samples "
|
||||
"collected in the parent function, will be inlined again."));
|
||||
|
||||
namespace {
|
||||
typedef DenseMap<const BasicBlock *, uint64_t> BlockWeightMap;
|
||||
typedef DenseMap<const BasicBlock *, const BasicBlock *> EquivalenceClassMap;
|
||||
typedef std::pair<const BasicBlock *, const BasicBlock *> Edge;
|
||||
typedef DenseMap<Edge, uint64_t> EdgeWeightMap;
|
||||
typedef DenseMap<const BasicBlock *, SmallVector<const BasicBlock *, 8>>
|
||||
BlockEdgeMap;
|
||||
|
||||
using BlockWeightMap = DenseMap<const BasicBlock *, uint64_t>;
|
||||
using EquivalenceClassMap = DenseMap<const BasicBlock *, const BasicBlock *>;
|
||||
using Edge = std::pair<const BasicBlock *, const BasicBlock *>;
|
||||
using EdgeWeightMap = DenseMap<Edge, uint64_t>;
|
||||
using BlockEdgeMap =
|
||||
DenseMap<const BasicBlock *, SmallVector<const BasicBlock *, 8>>;
|
||||
|
||||
class SampleCoverageTracker {
|
||||
public:
|
||||
SampleCoverageTracker() : SampleCoverage(), TotalUsedSamples(0) {}
|
||||
SampleCoverageTracker() = default;
|
||||
|
||||
bool markSamplesUsed(const FunctionSamples *FS, uint32_t LineOffset,
|
||||
uint32_t Discriminator, uint64_t Samples);
|
||||
@ -106,15 +133,16 @@ public:
|
||||
unsigned countBodyRecords(const FunctionSamples *FS) const;
|
||||
uint64_t getTotalUsedSamples() const { return TotalUsedSamples; }
|
||||
uint64_t countBodySamples(const FunctionSamples *FS) const;
|
||||
|
||||
void clear() {
|
||||
SampleCoverage.clear();
|
||||
TotalUsedSamples = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::map<LineLocation, unsigned> BodySampleCoverageMap;
|
||||
typedef DenseMap<const FunctionSamples *, BodySampleCoverageMap>
|
||||
FunctionSamplesCoverageMap;
|
||||
using BodySampleCoverageMap = std::map<LineLocation, unsigned>;
|
||||
using FunctionSamplesCoverageMap =
|
||||
DenseMap<const FunctionSamples *, BodySampleCoverageMap>;
|
||||
|
||||
/// Coverage map for sampling records.
|
||||
///
|
||||
@ -138,7 +166,7 @@ private:
|
||||
/// and all the inlined callsites. Strictly, we should have a map of counters
|
||||
/// keyed by FunctionSamples pointers, but these stats are cleared after
|
||||
/// every function, so we just need to keep a single counter.
|
||||
uint64_t TotalUsedSamples;
|
||||
uint64_t TotalUsedSamples = 0;
|
||||
};
|
||||
|
||||
/// \brief Sample profile pass.
|
||||
@ -152,11 +180,8 @@ public:
|
||||
StringRef Name, bool IsThinLTOPreLink,
|
||||
std::function<AssumptionCache &(Function &)> GetAssumptionCache,
|
||||
std::function<TargetTransformInfo &(Function &)> GetTargetTransformInfo)
|
||||
: DT(nullptr), PDT(nullptr), LI(nullptr), GetAC(GetAssumptionCache),
|
||||
GetTTI(GetTargetTransformInfo), Reader(), Samples(nullptr),
|
||||
Filename(Name), ProfileIsValid(false),
|
||||
IsThinLTOPreLink(IsThinLTOPreLink),
|
||||
TotalCollectedSamples(0), ORE(nullptr) {}
|
||||
: GetAC(GetAssumptionCache), GetTTI(GetTargetTransformInfo),
|
||||
Filename(Name), IsThinLTOPreLink(IsThinLTOPreLink) {}
|
||||
|
||||
bool doInitialization(Module &M);
|
||||
bool runOnModule(Module &M, ModuleAnalysisManager *AM);
|
||||
@ -245,13 +270,13 @@ protected:
|
||||
std::unique_ptr<SampleProfileReader> Reader;
|
||||
|
||||
/// \brief Samples collected for the body of this function.
|
||||
FunctionSamples *Samples;
|
||||
FunctionSamples *Samples = nullptr;
|
||||
|
||||
/// \brief Name of the profile file to load.
|
||||
std::string Filename;
|
||||
|
||||
/// \brief Flag indicating whether the profile input loaded successfully.
|
||||
bool ProfileIsValid;
|
||||
bool ProfileIsValid = false;
|
||||
|
||||
/// \brief Flag indicating if the pass is invoked in ThinLTO compile phase.
|
||||
///
|
||||
@ -263,10 +288,10 @@ protected:
|
||||
///
|
||||
/// This is the sum of all the samples collected in all the functions executed
|
||||
/// at runtime.
|
||||
uint64_t TotalCollectedSamples;
|
||||
uint64_t TotalCollectedSamples = 0;
|
||||
|
||||
/// \brief Optimization Remark Emitter used to emit diagnostic remarks.
|
||||
OptimizationRemarkEmitter *ORE;
|
||||
OptimizationRemarkEmitter *ORE = nullptr;
|
||||
};
|
||||
|
||||
class SampleProfileLoaderLegacyPass : public ModulePass {
|
||||
@ -282,8 +307,7 @@ public:
|
||||
},
|
||||
[&](Function &F) -> TargetTransformInfo & {
|
||||
return TTIWP->getTTI(F);
|
||||
}),
|
||||
ACT(nullptr), TTIWP(nullptr) {
|
||||
}) {
|
||||
initializeSampleProfileLoaderLegacyPassPass(
|
||||
*PassRegistry::getPassRegistry());
|
||||
}
|
||||
@ -293,6 +317,7 @@ public:
|
||||
bool doInitialization(Module &M) override {
|
||||
return SampleLoader.doInitialization(M);
|
||||
}
|
||||
|
||||
StringRef getPassName() const override { return "Sample profile pass"; }
|
||||
bool runOnModule(Module &M) override;
|
||||
|
||||
@ -303,10 +328,12 @@ public:
|
||||
|
||||
private:
|
||||
SampleProfileLoader SampleLoader;
|
||||
AssumptionCacheTracker *ACT;
|
||||
TargetTransformInfoWrapperPass *TTIWP;
|
||||
AssumptionCacheTracker *ACT = nullptr;
|
||||
TargetTransformInfoWrapperPass *TTIWP = nullptr;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// Return true if the given callsite is hot wrt to its caller.
|
||||
///
|
||||
/// Functions that were inlined in the original binary will be represented
|
||||
@ -321,8 +348,8 @@ private:
|
||||
///
|
||||
/// If that fraction is larger than the default given by
|
||||
/// SampleProfileHotThreshold, the callsite will be inlined again.
|
||||
bool callsiteIsHot(const FunctionSamples *CallerFS,
|
||||
const FunctionSamples *CallsiteFS) {
|
||||
static bool callsiteIsHot(const FunctionSamples *CallerFS,
|
||||
const FunctionSamples *CallsiteFS) {
|
||||
if (!CallsiteFS)
|
||||
return false; // The callsite was not inlined in the original binary.
|
||||
|
||||
@ -338,7 +365,6 @@ bool callsiteIsHot(const FunctionSamples *CallerFS,
|
||||
(double)CallsiteTotalSamples / (double)ParentTotalSamples * 100.0;
|
||||
return PercentSamples >= SampleProfileHotThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
/// Mark as used the sample record for the given function samples at
|
||||
/// (LineOffset, Discriminator).
|
||||
@ -652,7 +678,7 @@ SampleProfileLoader::findIndirectCallFunctionSamples(
|
||||
Sum += T_C.second;
|
||||
if (const FunctionSamplesMap *M = FS->findFunctionSamplesMapAt(
|
||||
LineLocation(getOffset(DIL), DIL->getBaseDiscriminator()))) {
|
||||
if (M->size() == 0)
|
||||
if (M->empty())
|
||||
return R;
|
||||
for (const auto &NameFS : *M) {
|
||||
Sum += NameFS.second.getEntrySamples();
|
||||
@ -1264,7 +1290,7 @@ void SampleProfileLoader::propagateWeights(Function &F) {
|
||||
if (!FS)
|
||||
continue;
|
||||
auto T = FS->findCallTargetMapAt(LineOffset, Discriminator);
|
||||
if (!T || T.get().size() == 0)
|
||||
if (!T || T.get().empty())
|
||||
continue;
|
||||
SmallVector<InstrProfValueData, 2> SortedCallTargets;
|
||||
uint64_t Sum = SortCallTargets(SortedCallTargets, T.get());
|
||||
@ -1323,7 +1349,7 @@ void SampleProfileLoader::propagateWeights(Function &F) {
|
||||
// weights, the second pass does not need to set it.
|
||||
if (MaxWeight > 0 && !TI->extractProfTotalWeight(TempWeight)) {
|
||||
DEBUG(dbgs() << "SUCCESS. Found non-zero weights.\n");
|
||||
TI->setMetadata(llvm::LLVMContext::MD_prof,
|
||||
TI->setMetadata(LLVMContext::MD_prof,
|
||||
MDB.createBranchWeights(Weights));
|
||||
ORE->emit([&]() {
|
||||
return OptimizationRemark(DEBUG_TYPE, "PopularDest", MaxDestInst)
|
||||
@ -1482,6 +1508,7 @@ bool SampleProfileLoader::emitAnnotations(Function &F) {
|
||||
}
|
||||
|
||||
char SampleProfileLoaderLegacyPass::ID = 0;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(SampleProfileLoaderLegacyPass, "sample-profile",
|
||||
"Sample Profile loader", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
|
Loading…
Reference in New Issue
Block a user