Skip to content

Commit af08f71

Browse files
Extended calculated statistics (#546)
* extended statistics * variable renaming for statistics calculation * added statistics entry for PHI nodes * varibale name typo in statistics fixed * removed separate counter for terminators * overload of << operator for GeneralStatistics * removed json stats from IRDB and instead expose the whole GeneralStatistics result * moved printAsJson to GeneralStatistics from IRDB * updated print statistics usage * returning a reference to the statistics object * minor Co-authored-by: Fabian Schiebel <fabian.schiebel@iem.fraunhofer.de>
1 parent 48925a7 commit af08f71

File tree

6 files changed

+57
-48
lines changed

6 files changed

+57
-48
lines changed

include/phasar/DB/ProjectIRDB.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/Passes/PassBuilder.h"
2323

2424
#include "nlohmann/json.hpp"
25+
#include "phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h"
2526
#include "phasar/Utils/EnumFlags.h"
2627

2728
namespace llvm {
@@ -63,7 +64,7 @@ class ProjectIRDB {
6364
std::map<std::size_t, llvm::Instruction *> IDInstructionMapping;
6465
size_t NumGlobals = 0;
6566
size_t NumberCallsites = 0;
66-
nlohmann::json StatsJson;
67+
GeneralStatistics GSPResult;
6768

6869
void buildIDModuleMapping(llvm::Module *M);
6970

@@ -160,6 +161,10 @@ class ProjectIRDB {
160161
return AllocatedTypes;
161162
};
162163

164+
[[nodiscard]] const psr::GeneralStatistics &getStatistics() const {
165+
return GSPResult;
166+
};
167+
163168
[[nodiscard]] std::set<const llvm::StructType *>
164169
getAllocatedStructTypes() const;
165170

@@ -188,8 +193,6 @@ class ProjectIRDB {
188193

189194
[[nodiscard]] static std::size_t getInstructionID(const llvm::Instruction *I);
190195

191-
void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const;
192-
193196
void print() const;
194197

195198
void emitPreprocessedIR(llvm::raw_ostream &OS = llvm::outs(),

include/phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class GeneralStatistics {
4545
size_t LoadInstructions = 0;
4646
size_t MemIntrinsics = 0;
4747
size_t GlobalPointers = 0;
48+
size_t Branches = 0;
49+
size_t GetElementPtrs = 0;
50+
size_t PhiNodes = 0;
4851
std::set<const llvm::Type *> AllocatedTypes;
4952
std::set<const llvm::Instruction *> AllocaInstructions;
5053
std::set<const llvm::Instruction *> RetResInstructions;
@@ -118,6 +121,10 @@ class GeneralStatistics {
118121
[[nodiscard]] std::set<const llvm::Instruction *>
119122
getRetResInstructions() const;
120123
[[nodiscard]] nlohmann::json getAsJson() const;
124+
void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const;
125+
126+
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
127+
const GeneralStatistics &Statistics);
121128
};
122129

123130
/**

lib/Controller/AnalysisController.cpp

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -230,15 +230,7 @@ void AnalysisController::emitRequestedHelperAnalysisResults() {
230230
PT.printAsJson();
231231
}
232232
}
233-
// if (EmitterOptions & AnalysisControllerEmitterOptions::EmitCGAsText) {
234-
// if (!ResultDirectory.empty()) {
235-
// if (auto OFS = openFileStream("/psr-cg.txt")) {
236-
// ICF.print(*OFS);
237-
// }
238-
// } else {
239-
// ICF.print();
240-
// }
241-
// }
233+
242234
if (EmitterOptions & AnalysisControllerEmitterOptions::EmitCGAsDot) {
243235
if (!ResultDirectory.empty()) {
244236
if (auto OFS = openFileStream("/psr-cg.dot")) {
@@ -249,23 +241,14 @@ void AnalysisController::emitRequestedHelperAnalysisResults() {
249241
}
250242
}
251243

252-
// if (EmitterOptions & AnalysisControllerEmitterOptions::EmitCGAsJson) {
253-
// if (!ResultDirectory.empty()) {
254-
// if (auto OFS = openFileStream("/psr-cg.json")) {
255-
// ICF.printAsJson(*OFS);
256-
// }
257-
// } else {
258-
// ICF.printAsJson();
259-
// }
260-
// }
261-
262244
if (EmitterOptions & AnalysisControllerEmitterOptions::EmitStatisticsAsJson) {
245+
const auto &Stats = IRDB.getStatistics();
263246
if (!ResultDirectory.empty()) {
264247
if (auto OFS = openFileStream("/psr-IrStatistics.json")) {
265-
IRDB.printAsJson(*OFS);
248+
Stats.printAsJson(*OFS);
266249
}
267250
} else {
268-
IRDB.printAsJson();
251+
Stats.printAsJson();
269252
}
270253
}
271254
}

lib/DB/ProjectIRDB.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ void ProjectIRDB::preprocessModule(llvm::Module *M) {
128128
PHASAR_LOG_LEVEL(INFO, "Preprocess module: " << M->getModuleIdentifier());
129129
MPM.run(*M, MAM);
130130
// retrieve data from the GeneralStatisticsAnalysis registered earlier
131-
auto GSPResult = MAM.getResult<GeneralStatisticsAnalysis>(*M);
132-
StatsJson = GSPResult.getAsJson();
131+
GSPResult = MAM.getResult<GeneralStatisticsAnalysis>(*M);
132+
133133
NumberCallsites = GSPResult.getFunctioncalls();
134134
auto Allocas = GSPResult.getAllocaInstructions();
135135
AllocaInstructions.insert(Allocas.begin(), Allocas.end());
@@ -279,10 +279,6 @@ void ProjectIRDB::print() const {
279279
}
280280
}
281281

282-
void ProjectIRDB::printAsJson(llvm::raw_ostream &OS) const {
283-
OS << StatsJson.dump(4) << '\n';
284-
}
285-
286282
void ProjectIRDB::emitPreprocessedIR(llvm::raw_ostream &OS,
287283
bool ShortenIR) const {
288284
for (const auto &[File, Module] : Modules) {

lib/PhasarLLVM/Passes/GeneralStatisticsAnalysis.cpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,15 @@ GeneralStatisticsAnalysis::run(llvm::Module &M,
5858
// do not add allocas from llvm internal functions
5959
Stats.AllocaInstructions.insert(&I);
6060
++Stats.AllocationSites;
61-
} // check bitcast instructions for possible types
62-
else {
63-
for (auto *User : I.users()) {
64-
if (const llvm::BitCastInst *Cast =
65-
llvm::dyn_cast<llvm::BitCastInst>(User)) {
66-
// types.insert(cast->getDestTy());
67-
}
68-
}
61+
}
62+
if (llvm::isa<llvm::PHINode>(I)) {
63+
++Stats.PhiNodes;
64+
}
65+
if (llvm::isa<llvm::BranchInst>(I)) {
66+
++Stats.Branches;
67+
}
68+
if (llvm::isa<llvm::GetElementPtrInst>(I)) {
69+
++Stats.GetElementPtrs;
6970
}
7071
// check for return or resume instructions
7172
if (llvm::isa<llvm::ReturnInst>(I) || llvm::isa<llvm::ResumeInst>(I)) {
@@ -125,7 +126,7 @@ GeneralStatisticsAnalysis::run(llvm::Module &M,
125126
}
126127
}
127128
// check for global pointers
128-
for (auto &Global : M.globals()) {
129+
for (auto const &Global : M.globals()) {
129130
if (Global.getType()->isPointerTy()) {
130131
++Stats.GlobalPointers;
131132
}
@@ -217,6 +218,10 @@ GeneralStatistics::getRetResInstructions() const {
217218
return RetResInstructions;
218219
}
219220

221+
void GeneralStatistics::printAsJson(llvm::raw_ostream &OS) const {
222+
OS << getAsJson().dump(4) << '\n';
223+
}
224+
220225
nlohmann::json GeneralStatistics::getAsJson() const {
221226
nlohmann::json J;
222227
J["ModuleName"] = GeneralStatistics::ModuleName;
@@ -225,7 +230,28 @@ nlohmann::json GeneralStatistics::getAsJson() const {
225230
J["AllocaInstructions"] = AllocaInstructions.size();
226231
J["CallSites"] = CallSites;
227232
J["GlobalVariables"] = Globals;
233+
J["Branches"] = Branches;
234+
J["GetElementPtrs"] = GetElementPtrs;
235+
J["BasicBlocks"] = BasicBlocks;
236+
J["PhiNodes"] = PhiNodes;
228237
return J;
229238
}
230239

240+
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
241+
const GeneralStatistics &Statistics) {
242+
return OS << "General LLVM IR Statistics"
243+
<< "\n"
244+
<< "Module " << Statistics.ModuleName << ":\n"
245+
<< "LLVM IR instructions:\t" << Statistics.Instructions << "\n"
246+
<< "Functions:\t" << Statistics.Functions << "\n"
247+
<< "Global Variables:\t" << Statistics.Globals << "\n"
248+
<< "Alloca Instructions:\t" << Statistics.AllocaInstructions.size()
249+
<< "\n"
250+
<< "Call Sites:\t" << Statistics.CallSites << "\n"
251+
<< "Branches:\t" << Statistics.Branches << "\n"
252+
<< "GetElementPtrs:\t" << Statistics.GetElementPtrs << "\n"
253+
<< "Phi Nodes:\t" << Statistics.PhiNodes << "\n"
254+
<< "Basic Blocks:\t" << Statistics.BasicBlocks << "\n";
255+
}
256+
231257
} // namespace psr

tools/phasar-llvm/phasar-llvm.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -336,17 +336,11 @@ int main(int Argc, const char **Argv) {
336336
// setup IRDB as source code manager
337337
ProjectIRDB IRDB(std::vector(ModuleOpt.begin(), ModuleOpt.end()));
338338
if (StatisticsOpt) {
339-
llvm::outs() << "Module " << IRDB.getWPAModule()->getName() << ":\n";
340-
llvm::outs() << "> LLVM IR instructions:\t" << IRDB.getNumInstructions()
341-
<< "\n";
342-
llvm::outs() << "> Functions:\t\t" << IRDB.getWPAModule()->size() << "\n";
343-
llvm::outs() << "> Global variables:\t"
344-
<< IRDB.getWPAModule()->global_size() << "\n";
345-
llvm::outs() << "> Alloca instructions:\t"
346-
<< IRDB.getAllocaInstructions().size() << "\n";
339+
llvm::outs() << IRDB.getStatistics();
340+
// the way we construct memory locations in IRDB is not included in
341+
// the GeneralStatistics class right now, thus we print it here separately.
347342
llvm::outs() << "> Memory Locations:\t"
348343
<< IRDB.getAllMemoryLocations().size() << "\n";
349-
llvm::outs() << "> Call Sites:\t\t" << IRDB.getNumCallsites() << "\n";
350344
}
351345

352346
// setup the emitter options to display the computed analysis results

0 commit comments

Comments
 (0)