diff options
author | Vitaly Buka <vitalybuka@google.com> | 2020-06-02 02:51:35 -0700 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2020-06-03 01:36:20 -0700 |
commit | 6e51a080f744013eaaff6be2f4864afd0882acfa (patch) | |
tree | 64d7b55201a32637ad33b137fa6c957cd7ce951e /llvm/lib/Analysis/StackSafetyAnalysis.cpp | |
parent | a019579fe56819688a36ba718afc8c7c4f3b04b1 (diff) | |
download | llvm-6e51a080f744013eaaff6be2f4864afd0882acfa.zip llvm-6e51a080f744013eaaff6be2f4864afd0882acfa.tar.gz llvm-6e51a080f744013eaaff6be2f4864afd0882acfa.tar.bz2 |
[StackSafety,NFC] Convert to template internal stuff
It's going to be usefull for ThinLTO.
Diffstat (limited to 'llvm/lib/Analysis/StackSafetyAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/StackSafetyAnalysis.cpp | 104 |
1 files changed, 54 insertions, 50 deletions
diff --git a/llvm/lib/Analysis/StackSafetyAnalysis.cpp b/llvm/lib/Analysis/StackSafetyAnalysis.cpp index d36b258..365adc7 100644 --- a/llvm/lib/Analysis/StackSafetyAnalysis.cpp +++ b/llvm/lib/Analysis/StackSafetyAnalysis.cpp @@ -58,9 +58,9 @@ public: }; /// Describes use of address in as a function call argument. -struct CallInfo { +template <typename CalleeTy> struct CallInfo { /// Function being called. - const GlobalValue *Callee = nullptr; + const CalleeTy *Callee = nullptr; /// Index of argument which pass address. size_t ParamNo = 0; // Offset range of address from base address (alloca or calling function @@ -68,25 +68,24 @@ struct CallInfo { // Range should never set to empty-set, that is an invalid access range // that can cause empty-set to be propagated with ConstantRange::add ConstantRange Offset; - CallInfo(const GlobalValue *Callee, size_t ParamNo, ConstantRange Offset) + CallInfo(const CalleeTy *Callee, size_t ParamNo, ConstantRange Offset) : Callee(Callee), ParamNo(ParamNo), Offset(Offset) {} - - StringRef getName() const { return Callee->getName(); } }; -raw_ostream &operator<<(raw_ostream &OS, const CallInfo &P) { - return OS << "@" << P.getName() << "(arg" << P.ParamNo << ", " << P.Offset - << ")"; +template <typename CalleeTy> +raw_ostream &operator<<(raw_ostream &OS, const CallInfo<CalleeTy> &P) { + return OS << "@" << P.Callee->getName() << "(arg" << P.ParamNo << ", " + << P.Offset << ")"; } /// Describe uses of address (alloca or parameter) inside of the function. -struct UseInfo { +template <typename CalleeTy> struct UseInfo { // Access range if the address (alloca or parameters). // It is allowed to be empty-set when there are no known accesses. ConstantRange Range; // List of calls which pass address as an argument. - SmallVector<CallInfo, 4> Calls; + SmallVector<CallInfo<CalleeTy>, 4> Calls; UseInfo(unsigned PointerSize) : Range{PointerSize, false} {} @@ -97,7 +96,8 @@ struct UseInfo { } }; -raw_ostream &operator<<(raw_ostream &OS, const UseInfo &U) { +template <typename CalleeTy> +raw_ostream &operator<<(raw_ostream &OS, const UseInfo<CalleeTy> &U) { OS << U.Range; for (auto &Call : U.Calls) OS << ", " << Call; @@ -140,9 +140,9 @@ ConstantRange getStaticAllocaSizeRange(const AllocaInst &AI) { return R; } -struct FunctionInfo { - std::map<const AllocaInst *, UseInfo> Allocas; - std::map<uint32_t, UseInfo> Params; +template <typename CalleeTy> struct FunctionInfo { + std::map<const AllocaInst *, UseInfo<CalleeTy>> Allocas; + std::map<uint32_t, UseInfo<CalleeTy>> Params; // TODO: describe return value as depending on one or more of its arguments. // StackSafetyDataFlowAnalysis counter stored here for faster access. @@ -179,12 +179,12 @@ struct FunctionInfo { } }; -using GVToSSI = std::map<const GlobalValue *, FunctionInfo>; +using GVToSSI = std::map<const GlobalValue *, FunctionInfo<GlobalValue>>; } // namespace struct StackSafetyInfo::InfoTy { - FunctionInfo Info; + FunctionInfo<GlobalValue> Info; }; struct StackSafetyGlobalInfo::InfoTy { @@ -209,7 +209,7 @@ class StackSafetyLocalAnalysis { ConstantRange getMemIntrinsicAccessRange(const MemIntrinsic *MI, const Use &U, Value *Base); - bool analyzeAllUses(Value *Ptr, UseInfo &AS); + bool analyzeAllUses(Value *Ptr, UseInfo<GlobalValue> &AS); public: StackSafetyLocalAnalysis(Function &F, ScalarEvolution &SE) @@ -218,7 +218,7 @@ public: UnknownRange(PointerSize, true) {} // Run the transformation on the associated function. - FunctionInfo run(); + FunctionInfo<GlobalValue> run(); }; ConstantRange StackSafetyLocalAnalysis::offsetFrom(Value *Addr, Value *Base) { @@ -292,7 +292,8 @@ ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange( /// The function analyzes all local uses of Ptr (alloca or argument) and /// calculates local access range and all function calls where it was used. -bool StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr, UseInfo &US) { +bool StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr, + UseInfo<GlobalValue> &US) { SmallPtrSet<const Value *, 16> Visited; SmallVector<const Value *, 8> WorkList; WorkList.push_back(Ptr); @@ -381,8 +382,8 @@ bool StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr, UseInfo &US) { return true; } -FunctionInfo StackSafetyLocalAnalysis::run() { - FunctionInfo Info; +FunctionInfo<GlobalValue> StackSafetyLocalAnalysis::run() { + FunctionInfo<GlobalValue> Info; assert(!F.isDeclaration() && "Can't run StackSafety on a function declaration"); @@ -407,19 +408,19 @@ FunctionInfo StackSafetyLocalAnalysis::run() { return Info; } -class StackSafetyDataFlowAnalysis { - using FunctionMap = std::map<const GlobalValue *, FunctionInfo>; +template <typename CalleeTy> class StackSafetyDataFlowAnalysis { + using FunctionMap = std::map<const CalleeTy *, FunctionInfo<CalleeTy>>; FunctionMap Functions; const ConstantRange UnknownRange; // Callee-to-Caller multimap. - DenseMap<const GlobalValue *, SmallVector<const GlobalValue *, 4>> Callers; - SetVector<const GlobalValue *> WorkList; + DenseMap<const CalleeTy *, SmallVector<const CalleeTy *, 4>> Callers; + SetVector<const CalleeTy *> WorkList; - bool updateOneUse(UseInfo &US, bool UpdateToFullSet); - void updateOneNode(const GlobalValue *Callee, FunctionInfo &FS); - void updateOneNode(const GlobalValue *Callee) { + bool updateOneUse(UseInfo<CalleeTy> &US, bool UpdateToFullSet); + void updateOneNode(const CalleeTy *Callee, FunctionInfo<CalleeTy> &FS); + void updateOneNode(const CalleeTy *Callee) { updateOneNode(Callee, Functions.find(Callee)->second); } void updateAllNodes() { @@ -438,13 +439,13 @@ public: const FunctionMap &run(); - ConstantRange getArgumentAccessRange(const GlobalValue *Callee, - unsigned ParamNo, + ConstantRange getArgumentAccessRange(const CalleeTy *Callee, unsigned ParamNo, const ConstantRange &Offsets) const; }; -ConstantRange StackSafetyDataFlowAnalysis::getArgumentAccessRange( - const GlobalValue *Callee, unsigned ParamNo, +template <typename CalleeTy> +ConstantRange StackSafetyDataFlowAnalysis<CalleeTy>::getArgumentAccessRange( + const CalleeTy *Callee, unsigned ParamNo, const ConstantRange &Offsets) const { auto FnIt = Functions.find(Callee); // Unknown callee (outside of LTO domain or an indirect call). @@ -465,8 +466,9 @@ ConstantRange StackSafetyDataFlowAnalysis::getArgumentAccessRange( return Access.add(Offsets); } -bool StackSafetyDataFlowAnalysis::updateOneUse(UseInfo &US, - bool UpdateToFullSet) { +template <typename CalleeTy> +bool StackSafetyDataFlowAnalysis<CalleeTy>::updateOneUse(UseInfo<CalleeTy> &US, + bool UpdateToFullSet) { bool Changed = false; for (auto &CS : US.Calls) { assert(!CS.Offset.isEmptySet() && @@ -485,8 +487,9 @@ bool StackSafetyDataFlowAnalysis::updateOneUse(UseInfo &US, return Changed; } -void StackSafetyDataFlowAnalysis::updateOneNode(const GlobalValue *Callee, - FunctionInfo &FS) { +template <typename CalleeTy> +void StackSafetyDataFlowAnalysis<CalleeTy>::updateOneNode( + const CalleeTy *Callee, FunctionInfo<CalleeTy> &FS) { bool UpdateToFullSet = FS.UpdateCount > StackSafetyMaxIterations; bool Changed = false; for (auto &KV : FS.Params) @@ -504,14 +507,13 @@ void StackSafetyDataFlowAnalysis::updateOneNode(const GlobalValue *Callee, } } -void StackSafetyDataFlowAnalysis::runDataFlow() { - Callers.clear(); - WorkList.clear(); - - SmallVector<const GlobalValue *, 16> Callees; +template <typename CalleeTy> +void StackSafetyDataFlowAnalysis<CalleeTy>::runDataFlow() { + SmallVector<const CalleeTy *, 16> Callees; for (auto &F : Functions) { Callees.clear(); - for (auto &KV : F.second.Params) + auto &FS = F.second; + for (auto &KV : FS.Params) for (auto &CS : KV.second.Calls) Callees.push_back(CS.Callee); @@ -525,22 +527,24 @@ void StackSafetyDataFlowAnalysis::runDataFlow() { updateAllNodes(); while (!WorkList.empty()) { - const GlobalValue *Callee = WorkList.back(); + const CalleeTy *Callee = WorkList.back(); WorkList.pop_back(); updateOneNode(Callee); } } #ifndef NDEBUG -void StackSafetyDataFlowAnalysis::verifyFixedPoint() { +template <typename ID> +void StackSafetyDataFlowAnalysis<ID>::verifyFixedPoint() { WorkList.clear(); updateAllNodes(); assert(WorkList.empty()); } #endif -const StackSafetyDataFlowAnalysis::FunctionMap & -StackSafetyDataFlowAnalysis::run() { +template <typename CalleeTy> +const typename StackSafetyDataFlowAnalysis<CalleeTy>::FunctionMap & +StackSafetyDataFlowAnalysis<CalleeTy>::run() { runDataFlow(); LLVM_DEBUG(verifyFixedPoint()); return Functions; @@ -562,7 +566,7 @@ const Function *findCalleeInModule(const GlobalValue *GV) { return nullptr; } -void resolveAllCalls(UseInfo &Use) { +template <typename CalleeTy> void resolveAllCalls(UseInfo<CalleeTy> &Use) { ConstantRange FullSet(Use.Range.getBitWidth(), true); for (auto &C : Use.Calls) { const Function *F = findCalleeInModule(C.Callee); @@ -576,7 +580,7 @@ void resolveAllCalls(UseInfo &Use) { } GVToSSI createGlobalStackSafetyInfo( - std::map<const GlobalValue *, FunctionInfo> Functions) { + std::map<const GlobalValue *, FunctionInfo<GlobalValue>> Functions) { GVToSSI SSI; if (Functions.empty()) return SSI; @@ -592,7 +596,7 @@ GVToSSI createGlobalStackSafetyInfo( ->first->getParent() ->getDataLayout() .getMaxPointerSizeInBits(); - StackSafetyDataFlowAnalysis SSDFA(PointerSize, std::move(Copy)); + StackSafetyDataFlowAnalysis<GlobalValue> SSDFA(PointerSize, std::move(Copy)); for (auto &F : SSDFA.run()) { auto FI = F.second; @@ -645,7 +649,7 @@ void StackSafetyInfo::print(raw_ostream &O) const { const StackSafetyGlobalInfo::InfoTy &StackSafetyGlobalInfo::getInfo() const { if (!Info) { - std::map<const GlobalValue *, FunctionInfo> Functions; + std::map<const GlobalValue *, FunctionInfo<GlobalValue>> Functions; for (auto &F : M->functions()) { if (!F.isDeclaration()) { auto FI = GetSSI(F).getInfo().Info; |