mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
134 lines
3.0 KiB
C++
134 lines
3.0 KiB
C++
#pragma once
|
|
|
|
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
#include <cmath>
|
|
#include <map>
|
|
#include <string>
|
|
|
|
#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<const FunctionTags::Tag *, FunctionClass> 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;
|
|
};
|