Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 21 additions & 26 deletions include/phasar/ControlFlow/CallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,30 +59,6 @@ class CallGraph : public CallGraphBase<CallGraph<N, F>> {
FunctionGetter GetFunctionFromName,
InstructionGetter GetInstructionFromId);

/// A range of all functions that are vertices in the call-graph. The number
/// of vertex functions can be retrieved by getNumVertexFunctions().
[[nodiscard]] auto getAllVertexFunctions() const noexcept {
return llvm::make_first_range(CallersOf);
}

/// A range of all call-sites that are vertices in the call-graph. The number
/// of vertex-callsites can be retrived by getNumVertexCallSites().
[[nodiscard]] auto getAllVertexCallSites() const noexcept {
return llvm::make_first_range(CalleesAt);
}

[[nodiscard]] size_t getNumVertexFunctions() const noexcept {
return CallersOf.size();
}
[[nodiscard]] size_t getNumVertexCallSites() const noexcept {
return CalleesAt.size();
}

/// The number of functions within this call-graph
[[nodiscard]] size_t size() const noexcept { return getNumVertexFunctions(); }

[[nodiscard]] bool empty() const noexcept { return CallersOf.empty(); }

template <typename FunctionIdGetter, typename InstIdGetter>
void printAsJson(llvm::raw_ostream &OS, FunctionIdGetter GetFunctionId,
InstIdGetter GetInstructionId) const {
Expand Down Expand Up @@ -114,7 +90,7 @@ class CallGraph : public CallGraphBase<CallGraph<N, F>> {
Fun2Id.reserve(CallersOf.size());

size_t CurrId = 0;
for (const auto &Fun : getAllVertexFunctions()) {
for (const auto &Fun : this->getAllVertexFunctions()) {
OS << CurrId << "[label=\"";
OS.write_escaped(std::invoke(GetFunctionLabel, Fun)) << "\"];\n";
Fun2Id[Fun] = CurrId++;
Expand Down Expand Up @@ -147,6 +123,25 @@ class CallGraph : public CallGraphBase<CallGraph<N, F>> {
return {};
}

/// A range of all functions that are vertices in the call-graph. The number
/// of vertex functions can be retrieved by getNumVertexFunctions().
[[nodiscard]] auto getAllVertexFunctionsImpl() const noexcept {
return llvm::make_first_range(CallersOf);
}

/// A range of all call-sites that are vertices in the call-graph. The number
/// of vertex-callsites can be retrived by getNumVertexCallSites().
[[nodiscard]] auto getAllVertexCallSitesImpl() const noexcept {
return llvm::make_first_range(CalleesAt);
}

[[nodiscard]] size_t getNumVertexFunctionsImpl() const noexcept {
return CallersOf.size();
}
[[nodiscard]] size_t getNumVertexCallSitesImpl() const noexcept {
return CalleesAt.size();
}

// ---

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

CGBuilder.addCallEdge(CS, Fun);
CGBuilder.addCallEdge(CS, Fun, CEdges);
}
}
return CGBuilder.consumeCallGraph();
Expand Down
33 changes: 31 additions & 2 deletions include/phasar/ControlFlow/CallGraphBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ template <typename Derived> class CallGraphBase : public CRTPBase<Derived> {
///
/// NOTE: This function is typically called in a hot part of the analysis and
/// should therefore be very fast
[[nodiscard]] decltype(auto) getCalleesOfCallAt(ByConstRef<n_t> Inst) const
[[nodiscard]] constexpr decltype(auto)
getCalleesOfCallAt(ByConstRef<n_t> Inst) const
noexcept(noexcept(this->self().getCalleesOfCallAtImpl(Inst))) {
static_assert(
is_iterable_over_v<decltype(self().getCalleesOfCallAtImpl(Inst)), f_t>);
Expand All @@ -45,11 +46,39 @@ template <typename Derived> class CallGraphBase : public CRTPBase<Derived> {

/// Returns an iterable range of all possible call-site candidates that may
/// call the given function induced by the used call-graph.
[[nodiscard]] decltype(auto) getCallersOf(ByConstRef<f_t> Fun) const {
[[nodiscard]] constexpr decltype(auto)
getCallersOf(ByConstRef<f_t> Fun) const {
static_assert(
is_iterable_over_v<decltype(this->self().getCallersOfImpl(Fun)), n_t>);
return self().getCallersOfImpl(Fun);
}

/// A range of all functions that are vertices in the call-graph. The number
/// of vertex functions can be retrieved by getNumVertexFunctions().
[[nodiscard]] constexpr decltype(auto)
getAllVertexFunctions() const noexcept {
return self().getAllVertexFunctionsImpl();
}

/// A range of all call-sites that are vertices in the call-graph. The number
/// of vertex-callsites can be retrived by getNumVertexCallSites().
[[nodiscard]] constexpr auto getAllVertexCallSites() const noexcept {
return self().getAllVertexCallSitesImpl();
}

[[nodiscard]] constexpr size_t getNumVertexFunctions() const noexcept {
return self().getNumVertexFunctionsImpl();
}
[[nodiscard]] constexpr size_t getNumVertexCallSites() const noexcept {
return self().getNumVertexCallSitesImpl();
}

/// The number of functions within this call-graph
[[nodiscard]] constexpr size_t size() const noexcept {
return getNumVertexFunctions();
}

[[nodiscard]] constexpr bool empty() const noexcept { return size() == 0; }
};
} // namespace psr

Expand Down
27 changes: 19 additions & 8 deletions include/phasar/DB/ProjectIRDBBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifndef PHASAR_DB_PROJECTIRDBBASE_H
#define PHASAR_DB_PROJECTIRDBBASE_H

#include "phasar/Utils/Nullable.h"
#include "phasar/Utils/TypeTraits.h"

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

// Returns the function's definition if available, its declaration otherwise.
[[nodiscard]] f_t getFunction(llvm::StringRef FunctionName) const {
// Returns the function if available, nullptr/nullopt otherwise.
[[nodiscard]] Nullable<f_t> getFunction(llvm::StringRef FunctionName) const {
assert(isValid());
return self().getFunctionImpl(FunctionName);
}
/// Returns the function's definition if available, null otherwise.
[[nodiscard]] f_t getFunctionDefinition(llvm::StringRef FunctionName) const {
[[nodiscard]] Nullable<f_t>
getFunctionDefinition(llvm::StringRef FunctionName) const {
assert(isValid());
return self().getFunctionDefinitionImpl(FunctionName);
}
Expand All @@ -79,8 +81,17 @@ template <typename Derived> class ProjectIRDBBase {
return self().hasFunctionImpl(FunctionName);
}

/// Returns the global variable's definition if available, null otherwise.
[[nodiscard]] g_t
/// Returns the global variable's definition if available, nullptr/nullopt
/// otherwise.
[[nodiscard]] Nullable<g_t>
getGlobalVariable(llvm::StringRef GlobalVariableName) const {
assert(isValid());
return self().getGlobalVariableImpl(GlobalVariableName);
}

/// Returns the global variable's definition if available, nullptr/nullopt
/// otherwise.
[[nodiscard]] Nullable<g_t>
getGlobalVariableDefinition(llvm::StringRef GlobalVariableName) const {
assert(isValid());
return self().getGlobalVariableDefinitionImpl(GlobalVariableName);
Expand All @@ -102,9 +113,9 @@ template <typename Derived> class ProjectIRDBBase {
return self().getNumFunctionsImpl();
}

/// Returns the instruction to the corresponding Id. Returns nullptr, if there
/// is no instruction for this Id
[[nodiscard]] n_t getInstruction(size_t Id) const {
/// Returns the instruction to the corresponding Id. Returns nullptr/nullopt,
/// if there is no instruction for this Id
[[nodiscard]] Nullable<n_t> getInstruction(size_t Id) const {
assert(isValid());
return self().getInstructionImpl(Id);
}
Expand Down
2 changes: 2 additions & 0 deletions include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ class LLVMProjectIRDB : public ProjectIRDBBase<LLVMProjectIRDB> {
return Mod->getFunction(FunctionName) != nullptr;
}
[[nodiscard]] g_t
getGlobalVariableImpl(llvm::StringRef GlobalVariableName) const;
[[nodiscard]] g_t
getGlobalVariableDefinitionImpl(llvm::StringRef GlobalVariableName) const;
[[nodiscard]] size_t getNumInstructionsImpl() const noexcept {
return IdToInst.size() - IdOffset;
Expand Down
10 changes: 6 additions & 4 deletions include/phasar/Utils/SCCGeneric.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,10 @@ pearce4VisitIt(const G &Graph, typename GraphTraits<G>::vertex_t Start,

using OutEdgeRange =
decltype(GTraits::outEdges(Graph, std::declval<Vertex>()));
using OutEdgeIterator = decltype(std::begin(std::declval<OutEdgeRange>()));
using OutEdgeSentinel = decltype(std::end(std::declval<OutEdgeRange>()));
using OutEdgeIterator =
decltype(llvm::adl_begin(std::declval<OutEdgeRange &>()));
using OutEdgeSentinel =
decltype(llvm::adl_end(std::declval<OutEdgeRange &>()));

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

auto &&OutEdges = GTraits::outEdges(Graph, W);
Frame = &CallStack.emplace_back(
DfsFrame{W, std::begin(OutEdges), std::end(OutEdges)});
DfsFrame{W, llvm::adl_begin(OutEdges), llvm::adl_end(OutEdges)});
V = W;

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

// Simulate the recursion
Expand Down
2 changes: 1 addition & 1 deletion include/phasar/Utils/TypeTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ struct variant_idx<std::variant<Ts...>, T>

template <typename Container> struct ElementType {
using IteratorTy =
std::decay_t<decltype(llvm::adl_begin(std::declval<Container>()))>;
std::decay_t<decltype(llvm::adl_begin(std::declval<Container &>()))>;
using type = typename std::iterator_traits<IteratorTy>::value_type;
};

Expand Down
8 changes: 7 additions & 1 deletion lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,16 @@ LLVMProjectIRDB::getFunctionDefinitionImpl(llvm::StringRef FunctionName) const {
return internalGetFunctionDefinition(*Mod, FunctionName);
}

[[nodiscard]] const llvm::GlobalVariable *
LLVMProjectIRDB::getGlobalVariableImpl(
llvm::StringRef GlobalVariableName) const {
return Mod->getGlobalVariable(GlobalVariableName, true);
}

[[nodiscard]] const llvm::GlobalVariable *
LLVMProjectIRDB::getGlobalVariableDefinitionImpl(
llvm::StringRef GlobalVariableName) const {
auto *G = Mod->getGlobalVariable(GlobalVariableName);
const auto *G = getGlobalVariable(GlobalVariableName);
if (G && !G->isDeclaration()) {
return G;
}
Expand Down
Loading