Skip to content

Commit 186a1f5

Browse files
committed
Add some comments + cleanup + using log categories (at least partially)
1 parent b595b6f commit 186a1f5

11 files changed

Lines changed: 182 additions & 59 deletions

File tree

include/phasar/PhasarLLVM/ControlFlow/CFGBase.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,37 +29,52 @@ template <typename Derived> class CFGBase {
2929
using n_t = typename CFGTraits<Derived>::n_t;
3030
using f_t = typename CFGTraits<Derived>::f_t;
3131

32+
/// Returns the function where the given instruction is defined
3233
[[nodiscard]] f_t getFunctionOf(ByConstRef<n_t> Inst) const noexcept {
3334
return self().getFunctionOfImpl(Inst);
3435
}
36+
/// Returns an iterable range of all predecessor instructions of Inst in the
37+
/// CFG
3538
[[nodiscard]] decltype(auto) getPredsOf(ByConstRef<n_t> Inst) const {
3639
static_assert(
3740
is_iterable_over_v<decltype(self().getPredsOfImpl(Inst)), n_t>);
3841
return self().getPredsOfImpl(Inst);
3942
}
43+
/// Returns an iterable range of all successor instructions of Inst in the
44+
/// CFG. NOTE: This function is typically being caled in a hot part of the
45+
/// analysis and should therefore be highly optimized for performance
4046
[[nodiscard]] decltype(auto) getSuccsOf(ByConstRef<n_t> Inst) const {
4147
static_assert(
4248
is_iterable_over_v<decltype(self().getSuccsOfImpl(Inst)), n_t>);
4349
return self().getSuccsOfImpl(Inst);
4450
}
51+
/// Returns an iterable range of all edges in the CFG of the given function
4552
[[nodiscard]] decltype(auto)
4653
getAllControlFlowEdges(ByConstRef<f_t> Fun) const {
4754
static_assert(
4855
is_iterable_over_v<decltype(self().getAllControlFlowEdgesImpl(Fun)),
4956
std::pair<n_t, n_t>>);
5057
return self().getAllControlFlowEdgesImpl(Fun);
5158
}
59+
/// Returns an iterable range of all instructions of the given function. NOTE:
60+
/// even if the CFG is initialized to ignore debugging instructions, they may
61+
/// be contained here.
5262
[[nodiscard]] decltype(auto) getAllInstructionsOf(ByConstRef<f_t> Fun) const {
5363
static_assert(
5464
is_iterable_over_v<decltype(self().getAllInstructionsOfImpl(Fun)),
5565
n_t>);
5666
return self().getAllInstructionsOfImpl(Fun);
5767
}
68+
/// Returns an iterable range of all starting instructions of the given
69+
/// function. For a forward-CFG, this is typically a singleton range
5870
[[nodiscard]] decltype(auto) getStartPointsOf(ByConstRef<f_t> Fun) const {
5971
static_assert(
6072
is_iterable_over_v<decltype(self().getStartPointsOfImpl(Fun)), n_t>);
6173
return self().getStartPointsOfImpl(Fun);
6274
}
75+
/// Returns an iterable range of all exit instructions (often return
76+
/// instructions) of the given function. For a backward-CFG, this is typically
77+
/// a singleton range
6378
[[nodiscard]] decltype(auto) getExitPointsOf(ByConstRef<f_t> Fun) const {
6479
static_assert(
6580
is_iterable_over_v<decltype(self().getExitPointsOfImpl(Fun)), n_t>);

include/phasar/PhasarLLVM/ControlFlow/ICFGBase.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,57 +31,84 @@ template <typename Derived> class ICFGBase {
3131
"An ICFG must also be a CFG");
3232
}
3333

34+
/// Returns an iterable range of all function definitions or declarations in
35+
/// the ICFG
3436
[[nodiscard]] decltype(auto) getAllFunctions() const {
3537
return self().getAllFunctionsImpl();
3638
}
3739

40+
/// returns the function definition or declaration with the given name. If
41+
/// ther eis no such function, returns a default constructed f_t (nullptr for
42+
/// pointers).
3843
[[nodiscard]] f_t getFunction(llvm::StringRef Fun) const {
3944
return self().getFunctionImpl(Fun);
4045
}
4146

47+
/// Returns true, iff the given instruction is a call-site where the callee is
48+
/// called via a function-pointer or another kind of virtual call.
49+
/// NOTE: Trivial cases where a bitcast of a function is called may still
50+
/// count as indirect call.
4251
[[nodiscard]] bool isIndirectFunctionCall(ByConstRef<n_t> Inst) const {
4352
return self().isIndirectFunctionCallImpl(Inst);
4453
}
54+
/// Returns true, iff the given instruction is a call-site where the callee is
55+
/// called via virtual dispatch. NOTE: Here, a class-hierarchy is required and
56+
/// a simple function-pointer is not sufficient.
4557
[[nodiscard]] bool isVirtualFunctionCall(ByConstRef<n_t> Inst) const {
4658
return self().isVirtualFunctionCallImpl(Inst);
4759
}
60+
/// Returns an iterable range of all instructions in all functions of the ICFG
61+
/// that are neither call-sites nor start-points of a function
4862
[[nodiscard]] decltype(auto) allNonCallStartNodes() const {
4963
static_assert(
5064
is_iterable_over_v<decltype(self().allNonCallStartNodesImpl()), n_t>);
5165
return self().allNonCallStartNodesImpl();
5266
}
67+
/// Returns an iterable range of all possible callee candidates at the given
68+
/// call-site induced by the used call-graph. NOTE: This function is typically
69+
/// called in a hot part of the analysis any should therefore be very fast
5370
[[nodiscard]] decltype(auto) getCalleesOfCallAt(ByConstRef<n_t> Inst) const {
5471
static_assert(
5572
is_iterable_over_v<decltype(self().getCalleesOfCallAtImpl(Inst)), f_t>);
5673
return self().getCalleesOfCallAtImpl(Inst);
5774
}
75+
/// Returns an iterable range of all possible call-site candidates that may
76+
/// call the given function induced by the used call-graph.
5877
[[nodiscard]] decltype(auto) getCallersOf(ByConstRef<f_t> Fun) const {
5978
static_assert(
6079
is_iterable_over_v<decltype(self().getCallersOfImpl(Fun)), n_t>);
6180
return self().getCallersOfImpl(Fun);
6281
}
82+
/// Returns an iterable range of all call-instruction in the given function
6383
[[nodiscard]] decltype(auto) getCallsFromWithin(ByConstRef<f_t> Fun) const {
6484
static_assert(
6585
is_iterable_over_v<decltype(self().getCallsFromWithinImpl(Fun)), n_t>);
6686
return self().getCallsFromWithinImpl(Fun);
6787
}
88+
/// Returns an iterable range of all return-sites of the given
89+
/// call-instruction. Often the same as getSuccsOf. NOTE: This function is
90+
/// typically called in a hot part of the analysis and should therefore be
91+
/// very fast
6892
[[nodiscard]] decltype(auto)
6993
getReturnSitesOfCallAt(ByConstRef<n_t> Inst) const {
7094
static_assert(
7195
is_iterable_over_v<decltype(self().getReturnSitesOfCallAtImpl(Inst)),
7296
n_t>);
7397
return self().getReturnSitesOfCallAtImpl(Inst);
7498
}
99+
/// Returns an iterable range of all global initializer functions
75100
[[nodiscard]] decltype(auto)
76101
getGlobalInitializers(ByConstRef<f_t> Fun) const {
77102
static_assert(
78103
is_iterable_over_v<decltype(self().getGlobalInitializersImpl(Fun)),
79104
f_t>);
80105
return self().getGlobalInitializersImpl(Fun);
81106
}
107+
/// Prints the underlying call-graph as DOT to the given output-stream
82108
void print(llvm::raw_ostream &OS = llvm::outs()) const {
83109
self().printImpl(OS);
84110
}
111+
/// Returns the underlying call-graph as JSON
85112
[[nodiscard]] nlohmann::json getAsJson() const {
86113
return self().getAsJsonImpl();
87114
}
@@ -93,7 +120,10 @@ template <typename Derived> class ICFGBase {
93120
}
94121
};
95122

123+
/// True, iff ICF is a proper instantiation of ICFGBase with n_t and f_t taken
124+
/// from the given analysis-Domain
96125
template <typename ICF, typename Domain>
126+
// NOLINTNEXTLINE(readability-identifier-naming)
97127
constexpr bool is_icfg_v = is_crtp_base_of_v<ICFGBase, ICF>
98128
&&std::is_same_v<typename ICF::n_t, typename Domain::n_t>
99129
&&std::is_same_v<typename ICF::f_t, typename Domain::f_t>;

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,24 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
6969
static constexpr llvm::StringLiteral GlobalCRuntimeModelName =
7070
"__psrCRuntimeGlobalCtorsModel";
7171

72+
/// Constructs the ICFG based on the given IRDB and the entry-points using a
73+
/// fixpoint iteration. This may take a long time.
74+
///
75+
/// \param IRDB The IR code where the ICFG should be based on. Must not be
76+
/// nullptr.
77+
/// \param CGType The analysis kind to use for call-graph resolution
78+
/// \param EntryPoints The names of the functions to start with when
79+
/// incrementally building up the ICFG. For whole-program analysis of an
80+
/// executable use {"main"}.
81+
/// \param TH The type-hierarchy implementation to use. Will be constructed
82+
/// on-the-fly if nullptr, but required
83+
/// \param PT The points-to implementation to use. Will be constructed
84+
/// on-the-fly if nullptr, but required
85+
/// \param S The soundness level to expect from the analysis. Currently unused
86+
/// \param IncludeGlobals Properly include global constructors/destructors
87+
/// into the ICFG, if true. Requires to generate artificial functions into the
88+
/// IRDB. True by default
89+
7290
explicit LLVMBasedICFG(ProjectIRDB *IRDB, CallGraphAnalysisType CGType,
7391
llvm::ArrayRef<std::string> EntryPoints = {},
7492
LLVMTypeHierarchy *TH = nullptr,
@@ -84,14 +102,22 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
84102
LLVMBasedICFG(LLVMBasedICFG &&) noexcept = delete;
85103
LLVMBasedICFG &operator=(LLVMBasedICFG &&) noexcept = delete;
86104

105+
/// Exports the whole ICFG (not only the call-graph) as DOT.
106+
///
107+
/// \param WithSourceCodeInfo If true, not only contains the LLVM instructions
108+
/// as labels, but source-code information as well (e.g. function name, line
109+
/// no, col no, src-line).
87110
[[nodiscard]] std::string
88111
exportICFGAsDot(bool WithSourceCodeInfo = true) const;
112+
/// Similar to exportICFGAsDot, but exports the ICFG as JSON instead
89113
[[nodiscard]] nlohmann::json
90114
exportICFGAsJson(bool WithSourceCodeInfo = true) const;
91115

92-
[[nodiscard]] const llvm::SmallVectorImpl<f_t> &
93-
getAllVertexFunctions() const noexcept;
116+
/// Returns all functions from the underlying IRDB that are part of the ICFG,
117+
/// i.e. that are reachable from the entry-points
118+
[[nodiscard]] llvm::ArrayRef<f_t> getAllVertexFunctions() const noexcept;
94119

120+
/// Gets the underlying IRDB
95121
[[nodiscard]] ProjectIRDB *getIRDB() const noexcept { return IRDB; }
96122

97123
using CFGBase::print;
@@ -131,8 +157,6 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
131157
llvm::SmallVector<const llvm::Function *> *Callees,
132158
const llvm::Function *Callee);
133159

134-
/// The call graph.
135-
136160
#if HAS_MEMORY_RESOURCE
137161
std::pmr::monotonic_buffer_resource MRes;
138162
#else

include/phasar/PhasarLLVM/Utils/LLVMBasedContainerConfig.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#define PHASAR_PHASARLLVM_UTILS_LLVMBASEDCONTAINERCONFIG_H
1212

1313
#include "llvm/ADT/STLExtras.h"
14-
#include "llvm/ADT/iterator.h"
1514
#include "llvm/ADT/iterator_range.h"
1615
#include "llvm/IR/Module.h"
1716

include/phasar/Utils/Logger.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <variant>
1818

1919
#include "llvm/ADT/StringMap.h"
20+
#include "llvm/ADT/StringRef.h"
2021
#include "llvm/Support/Compiler.h" // LLVM_UNLIKELY
2122
#include "llvm/Support/ErrorHandling.h"
2223
#include "llvm/Support/raw_ostream.h"
@@ -29,6 +30,8 @@ enum SeverityLevel {
2930
INVALID
3031
};
3132

33+
SeverityLevel parseSeverityLevel(llvm::StringRef Str);
34+
3235
class Logger final {
3336
public:
3437
/**

lib/PhasarLLVM/ControlFlow/LLVMBasedCFG.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,8 @@ auto detail::LLVMBasedCFGImpl<Derived>::getAllControlFlowEdgesImpl(
108108
for (const auto &I : llvm::instructions(Fun)) {
109109
if (IgnoreDbgInstructions) {
110110
// Check for call to intrinsic debug function
111-
if (const auto *DbgCallInst = llvm::dyn_cast<llvm::CallInst>(&I)) {
112-
if (DbgCallInst->getCalledFunction() &&
113-
DbgCallInst->getCalledFunction()->isIntrinsic() &&
114-
(DbgCallInst->getCalledFunction()->getName() ==
115-
"llvm.dbg.declare")) {
116-
continue;
117-
}
111+
if (llvm::isa<llvm::DbgInfoIntrinsic>(&I)) {
112+
continue;
118113
}
119114
}
120115

0 commit comments

Comments
 (0)