#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include #include #include "llvm/IR/Function.h" #include "revng/Support/Debug.h" namespace FunctionTags { class Tag; } class ListStatistics { private: unsigned ElementsCount = 0; unsigned Sum = 0; double OldM = 0.0; double NewM = 0.0; double OldS = 0.0; double NewS = 0.0; public: unsigned count() const { return ElementsCount; } unsigned sum() const { return Sum; } double mean() const { return (count() > 0) ? NewM : 0.0; } double variance() const { return ((ElementsCount > 1) ? NewS / (ElementsCount - 1) : 0.0); } double standardDeviation() const { return sqrt(variance()); } double confidenceInterval() const { return 1.96 * standardDeviation() / sqrt(ElementsCount); } public: std::string toString() const { std::string Result; Result += std::to_string(unsigned(mean())); Result += "±"; Result += std::to_string(unsigned(confidenceInterval())); return Result; } public: void push(unsigned NewElement) { ++ElementsCount; Sum += NewElement; // See Knuth TAOCP vol 2, 3rd edition, page 232 if (ElementsCount == 1) { OldM = NewM = NewElement; OldS = 0.0; } else { NewM = OldM + (NewElement - OldM) / ElementsCount; NewS = OldS + (NewElement - OldM) * (NewElement - NewM); // Set up for next iteration OldM = NewM; OldS = NewS; } } }; class FunctionClass { public: unsigned DeclarationsCount = 0; unsigned DefinitionsCount = 0; ListStatistics InstructionsStatistics; public: void process(const llvm::Function &F) { if (F.isDeclaration()) { ++DeclarationsCount; } else { ++DefinitionsCount; unsigned Size = 0; for (const llvm::BasicBlock &BB : F) Size += BB.size(); InstructionsStatistics.push(Size); } } void dump(llvm::raw_ostream &Output, unsigned Indent, const FunctionClass *Old = nullptr) const; }; class ModuleStatistics { private: unsigned NamedGlobalsCount = 0; unsigned AnonymousGlobalsCount = 0; unsigned AliasesCount = 0; unsigned NamedMetadataCount = 0; unsigned MaxNamedMetadataSize = 0; unsigned MaxArrayElements = 0; unsigned MaxStructElements = 0; FunctionClass AllFunctions; std::map TaggedFunctions; unsigned NamedStructsCount = 0; unsigned AnonymousStructsCount = 0; unsigned DebugCompileUnitsCount = 0; unsigned DebugScopesCount = 0; unsigned DebugSubprogramsCount = 0; unsigned DebugGloblaVariablesCount = 0; unsigned DebugTypesCount = 0; public: static ModuleStatistics analyze(const llvm::Module &M); void dump() const debug_function { std::string Result; { llvm::raw_string_ostream S(Result); dump(S, 0, nullptr); } dbg << Result; } void dump(llvm::raw_ostream &Output, unsigned Indent, const ModuleStatistics *Old = nullptr) const; };