Skip to content

Commit ed815a2

Browse files
authored
Interface Improvements for ProjectIRDB + CallGraph (#807)
* Add Nullable annotation to symbol-table getters in ProjectIRDBBase + improve global-lookup * Additional API for CallGraphBase + minor optimization in CallGraph::deserialize() * Minor changes in TypeTraits begin/end in TypeTraits should take T& instead of T, because std::begin/end only work with lvalue references.
1 parent 70f1394 commit ed815a2

File tree

7 files changed

+87
-42
lines changed

7 files changed

+87
-42
lines changed

include/phasar/ControlFlow/CallGraph.h

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -59,30 +59,6 @@ class CallGraph : public CallGraphBase<CallGraph<N, F>> {
5959
FunctionGetter GetFunctionFromName,
6060
InstructionGetter GetInstructionFromId);
6161

62-
/// A range of all functions that are vertices in the call-graph. The number
63-
/// of vertex functions can be retrieved by getNumVertexFunctions().
64-
[[nodiscard]] auto getAllVertexFunctions() const noexcept {
65-
return llvm::make_first_range(CallersOf);
66-
}
67-
68-
/// A range of all call-sites that are vertices in the call-graph. The number
69-
/// of vertex-callsites can be retrived by getNumVertexCallSites().
70-
[[nodiscard]] auto getAllVertexCallSites() const noexcept {
71-
return llvm::make_first_range(CalleesAt);
72-
}
73-
74-
[[nodiscard]] size_t getNumVertexFunctions() const noexcept {
75-
return CallersOf.size();
76-
}
77-
[[nodiscard]] size_t getNumVertexCallSites() const noexcept {
78-
return CalleesAt.size();
79-
}
80-
81-
/// The number of functions within this call-graph
82-
[[nodiscard]] size_t size() const noexcept { return getNumVertexFunctions(); }
83-
84-
[[nodiscard]] bool empty() const noexcept { return CallersOf.empty(); }
85-
8662
template <typename FunctionIdGetter, typename InstIdGetter>
8763
void printAsJson(llvm::raw_ostream &OS, FunctionIdGetter GetFunctionId,
8864
InstIdGetter GetInstructionId) const {
@@ -114,7 +90,7 @@ class CallGraph : public CallGraphBase<CallGraph<N, F>> {
11490
Fun2Id.reserve(CallersOf.size());
11591

11692
size_t CurrId = 0;
117-
for (const auto &Fun : getAllVertexFunctions()) {
93+
for (const auto &Fun : this->getAllVertexFunctions()) {
11894
OS << CurrId << "[label=\"";
11995
OS.write_escaped(std::invoke(GetFunctionLabel, Fun)) << "\"];\n";
12096
Fun2Id[Fun] = CurrId++;
@@ -147,6 +123,25 @@ class CallGraph : public CallGraphBase<CallGraph<N, F>> {
147123
return {};
148124
}
149125

126+
/// A range of all functions that are vertices in the call-graph. The number
127+
/// of vertex functions can be retrieved by getNumVertexFunctions().
128+
[[nodiscard]] auto getAllVertexFunctionsImpl() const noexcept {
129+
return llvm::make_first_range(CallersOf);
130+
}
131+
132+
/// A range of all call-sites that are vertices in the call-graph. The number
133+
/// of vertex-callsites can be retrived by getNumVertexCallSites().
134+
[[nodiscard]] auto getAllVertexCallSitesImpl() const noexcept {
135+
return llvm::make_first_range(CalleesAt);
136+
}
137+
138+
[[nodiscard]] size_t getNumVertexFunctionsImpl() const noexcept {
139+
return CallersOf.size();
140+
}
141+
[[nodiscard]] size_t getNumVertexCallSitesImpl() const noexcept {
142+
return CalleesAt.size();
143+
}
144+
150145
// ---
151146

152147
StableVector<InstructionVertexTy> InstVertexOwner;
@@ -274,7 +269,7 @@ CallGraph<N, F>::deserialize(const CallGraphData &PrecomputedCG,
274269
"Invalid Call-Instruction Id: " << JId);
275270
}
276271

277-
CGBuilder.addCallEdge(CS, Fun);
272+
CGBuilder.addCallEdge(CS, Fun, CEdges);
278273
}
279274
}
280275
return CGBuilder.consumeCallGraph();

include/phasar/ControlFlow/CallGraphBase.h

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ template <typename Derived> class CallGraphBase : public CRTPBase<Derived> {
3636
///
3737
/// NOTE: This function is typically called in a hot part of the analysis and
3838
/// should therefore be very fast
39-
[[nodiscard]] decltype(auto) getCalleesOfCallAt(ByConstRef<n_t> Inst) const
39+
[[nodiscard]] constexpr decltype(auto)
40+
getCalleesOfCallAt(ByConstRef<n_t> Inst) const
4041
noexcept(noexcept(this->self().getCalleesOfCallAtImpl(Inst))) {
4142
static_assert(
4243
is_iterable_over_v<decltype(self().getCalleesOfCallAtImpl(Inst)), f_t>);
@@ -45,11 +46,39 @@ template <typename Derived> class CallGraphBase : public CRTPBase<Derived> {
4546

4647
/// Returns an iterable range of all possible call-site candidates that may
4748
/// call the given function induced by the used call-graph.
48-
[[nodiscard]] decltype(auto) getCallersOf(ByConstRef<f_t> Fun) const {
49+
[[nodiscard]] constexpr decltype(auto)
50+
getCallersOf(ByConstRef<f_t> Fun) const {
4951
static_assert(
5052
is_iterable_over_v<decltype(this->self().getCallersOfImpl(Fun)), n_t>);
5153
return self().getCallersOfImpl(Fun);
5254
}
55+
56+
/// A range of all functions that are vertices in the call-graph. The number
57+
/// of vertex functions can be retrieved by getNumVertexFunctions().
58+
[[nodiscard]] constexpr decltype(auto)
59+
getAllVertexFunctions() const noexcept {
60+
return self().getAllVertexFunctionsImpl();
61+
}
62+
63+
/// A range of all call-sites that are vertices in the call-graph. The number
64+
/// of vertex-callsites can be retrived by getNumVertexCallSites().
65+
[[nodiscard]] constexpr auto getAllVertexCallSites() const noexcept {
66+
return self().getAllVertexCallSitesImpl();
67+
}
68+
69+
[[nodiscard]] constexpr size_t getNumVertexFunctions() const noexcept {
70+
return self().getNumVertexFunctionsImpl();
71+
}
72+
[[nodiscard]] constexpr size_t getNumVertexCallSites() const noexcept {
73+
return self().getNumVertexCallSitesImpl();
74+
}
75+
76+
/// The number of functions within this call-graph
77+
[[nodiscard]] constexpr size_t size() const noexcept {
78+
return getNumVertexFunctions();
79+
}
80+
81+
[[nodiscard]] constexpr bool empty() const noexcept { return size() == 0; }
5382
};
5483
} // namespace psr
5584

include/phasar/DB/ProjectIRDBBase.h

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#ifndef PHASAR_DB_PROJECTIRDBBASE_H
1111
#define PHASAR_DB_PROJECTIRDBBASE_H
1212

13+
#include "phasar/Utils/Nullable.h"
1314
#include "phasar/Utils/TypeTraits.h"
1415

1516
#include "llvm/ADT/StringRef.h"
@@ -63,13 +64,14 @@ template <typename Derived> class ProjectIRDBBase {
6364
return self().getAllFunctionsImpl();
6465
}
6566

66-
// Returns the function's definition if available, its declaration otherwise.
67-
[[nodiscard]] f_t getFunction(llvm::StringRef FunctionName) const {
67+
// Returns the function if available, nullptr/nullopt otherwise.
68+
[[nodiscard]] Nullable<f_t> getFunction(llvm::StringRef FunctionName) const {
6869
assert(isValid());
6970
return self().getFunctionImpl(FunctionName);
7071
}
7172
/// Returns the function's definition if available, null otherwise.
72-
[[nodiscard]] f_t getFunctionDefinition(llvm::StringRef FunctionName) const {
73+
[[nodiscard]] Nullable<f_t>
74+
getFunctionDefinition(llvm::StringRef FunctionName) const {
7375
assert(isValid());
7476
return self().getFunctionDefinitionImpl(FunctionName);
7577
}
@@ -79,8 +81,17 @@ template <typename Derived> class ProjectIRDBBase {
7981
return self().hasFunctionImpl(FunctionName);
8082
}
8183

82-
/// Returns the global variable's definition if available, null otherwise.
83-
[[nodiscard]] g_t
84+
/// Returns the global variable's definition if available, nullptr/nullopt
85+
/// otherwise.
86+
[[nodiscard]] Nullable<g_t>
87+
getGlobalVariable(llvm::StringRef GlobalVariableName) const {
88+
assert(isValid());
89+
return self().getGlobalVariableImpl(GlobalVariableName);
90+
}
91+
92+
/// Returns the global variable's definition if available, nullptr/nullopt
93+
/// otherwise.
94+
[[nodiscard]] Nullable<g_t>
8495
getGlobalVariableDefinition(llvm::StringRef GlobalVariableName) const {
8596
assert(isValid());
8697
return self().getGlobalVariableDefinitionImpl(GlobalVariableName);
@@ -102,9 +113,9 @@ template <typename Derived> class ProjectIRDBBase {
102113
return self().getNumFunctionsImpl();
103114
}
104115

105-
/// Returns the instruction to the corresponding Id. Returns nullptr, if there
106-
/// is no instruction for this Id
107-
[[nodiscard]] n_t getInstruction(size_t Id) const {
116+
/// Returns the instruction to the corresponding Id. Returns nullptr/nullopt,
117+
/// if there is no instruction for this Id
118+
[[nodiscard]] Nullable<n_t> getInstruction(size_t Id) const {
108119
assert(isValid());
109120
return self().getInstructionImpl(Id);
110121
}

include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ class LLVMProjectIRDB : public ProjectIRDBBase<LLVMProjectIRDB> {
161161
return Mod->getFunction(FunctionName) != nullptr;
162162
}
163163
[[nodiscard]] g_t
164+
getGlobalVariableImpl(llvm::StringRef GlobalVariableName) const;
165+
[[nodiscard]] g_t
164166
getGlobalVariableDefinitionImpl(llvm::StringRef GlobalVariableName) const;
165167
[[nodiscard]] size_t getNumInstructionsImpl() const noexcept {
166168
return IdToInst.size() - IdOffset;

include/phasar/Utils/SCCGeneric.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,10 @@ pearce4VisitIt(const G &Graph, typename GraphTraits<G>::vertex_t Start,
372372

373373
using OutEdgeRange =
374374
decltype(GTraits::outEdges(Graph, std::declval<Vertex>()));
375-
using OutEdgeIterator = decltype(std::begin(std::declval<OutEdgeRange>()));
376-
using OutEdgeSentinel = decltype(std::end(std::declval<OutEdgeRange>()));
375+
using OutEdgeIterator =
376+
decltype(llvm::adl_begin(std::declval<OutEdgeRange &>()));
377+
using OutEdgeSentinel =
378+
decltype(llvm::adl_end(std::declval<OutEdgeRange &>()));
377379

378380
struct DfsFrame {
379381
Vertex CurrVtx;
@@ -401,7 +403,7 @@ pearce4VisitIt(const G &Graph, typename GraphTraits<G>::vertex_t Start,
401403

402404
auto &&OutEdges = GTraits::outEdges(Graph, W);
403405
Frame = &CallStack.emplace_back(
404-
DfsFrame{W, std::begin(OutEdges), std::end(OutEdges)});
406+
DfsFrame{W, llvm::adl_begin(OutEdges), llvm::adl_end(OutEdges)});
405407
V = W;
406408

407409
} while (Frame->It != Frame->End);
@@ -463,7 +465,7 @@ pearce4VisitIt(const G &Graph, typename GraphTraits<G>::vertex_t Start,
463465
"the out-edges, but never an owning container by value. Otherwise, "
464466
"the DFSFrame iterators may be dangling");
465467
CallStack.emplace_back(
466-
DfsFrame{Start, std::begin(OutEdges), std::end(OutEdges)});
468+
DfsFrame{Start, llvm::adl_begin(OutEdges), llvm::adl_end(OutEdges)});
467469
}
468470

469471
// Simulate the recursion

include/phasar/Utils/TypeTraits.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct variant_idx<std::variant<Ts...>, T>
6565

6666
template <typename Container> struct ElementType {
6767
using IteratorTy =
68-
std::decay_t<decltype(llvm::adl_begin(std::declval<Container>()))>;
68+
std::decay_t<decltype(llvm::adl_begin(std::declval<Container &>()))>;
6969
using type = typename std::iterator_traits<IteratorTy>::value_type;
7070
};
7171

lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,10 +317,16 @@ LLVMProjectIRDB::getFunctionDefinitionImpl(llvm::StringRef FunctionName) const {
317317
return internalGetFunctionDefinition(*Mod, FunctionName);
318318
}
319319

320+
[[nodiscard]] const llvm::GlobalVariable *
321+
LLVMProjectIRDB::getGlobalVariableImpl(
322+
llvm::StringRef GlobalVariableName) const {
323+
return Mod->getGlobalVariable(GlobalVariableName, true);
324+
}
325+
320326
[[nodiscard]] const llvm::GlobalVariable *
321327
LLVMProjectIRDB::getGlobalVariableDefinitionImpl(
322328
llvm::StringRef GlobalVariableName) const {
323-
auto *G = Mod->getGlobalVariable(GlobalVariableName);
329+
const auto *G = getGlobalVariable(GlobalVariableName);
324330
if (G && !G->isDeclaration()) {
325331
return G;
326332
}

0 commit comments

Comments
 (0)