Skip to content
Merged
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
6 changes: 6 additions & 0 deletions include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,12 @@ ConstantEdgeFunction<L>::join(EdgeFunctionRef<ConcreteEF> This,
if (auto Default = defaultJoinOrNull<l_t>(This, OtherFunction)) {
return Default;
}

if (llvm::isa<EdgeIdentity<L>>(OtherFunction)) {
// Prevent endless recursion
return AllBottom<L>{};
}

if (!OtherFunction.isConstant()) {
// do not know how to join; hence ask other function to decide on this
return OtherFunction.joinWith(This);
Expand Down
33 changes: 15 additions & 18 deletions include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,6 @@ class IDESolver {
}

void printIncomingTab() const {
#ifdef DYNAMIC_LOG
IF_LOG_ENABLED(
PHASAR_LOG_LEVEL(DEBUG, "Start of incomingtab entry");
for (const auto &Cell
Expand All @@ -1231,29 +1230,27 @@ class IDESolver {
}
PHASAR_LOG_LEVEL(DEBUG, "---------------");
} PHASAR_LOG_LEVEL(DEBUG, "End of incomingtab entry");)
#endif
}

void printEndSummaryTab() const {
#ifdef DYNAMIC_LOG
IF_LOG_ENABLED(
PHASAR_LOG_LEVEL(DEBUG, "Start of endsummarytab entry");
for (const auto &Cell
: EndsummaryTab.cellVec()) {
PHASAR_LOG_LEVEL(DEBUG,
"sP: " << IDEProblem.NtoString(Cell.getRowKey()));
PHASAR_LOG_LEVEL(DEBUG,
"d1: " << IDEProblem.DtoString(Cell.getColumnKey()));
for (const auto &InnerCell : Cell.getValue().cellVec()) {
PHASAR_LOG_LEVEL(
DEBUG, " eP: " << IDEProblem.NtoString(InnerCell.getRowKey()));
PHASAR_LOG_LEVEL(DEBUG, " d2: " << IDEProblem.DtoString(
InnerCell.getColumnKey()));
PHASAR_LOG_LEVEL(DEBUG, " EF: " << InnerCell.getValue());
}

EndsummaryTab.foreachCell([this](const auto &Row, const auto &Col,
const auto &Val) {
PHASAR_LOG_LEVEL(DEBUG, "sP: " << IDEProblem.NtoString(Row));
PHASAR_LOG_LEVEL(DEBUG, "d1: " << IDEProblem.DtoString(Col));

Val.foreachCell([this](const auto &InnerRow, const auto &InnerCol,
const auto &InnerVal) {
PHASAR_LOG_LEVEL(DEBUG, " eP: " << IDEProblem.NtoString(InnerRow));
PHASAR_LOG_LEVEL(DEBUG, " d2: " << IDEProblem.DtoString(InnerCol));
PHASAR_LOG_LEVEL(DEBUG, " EF: " << InnerVal);
});
PHASAR_LOG_LEVEL(DEBUG, "---------------");
} PHASAR_LOG_LEVEL(DEBUG, "End of endsummarytab entry");)
#endif
});

PHASAR_LOG_LEVEL(DEBUG, "End of endsummarytab entry");)
}

void printComputedPathEdges() {
Expand Down
28 changes: 14 additions & 14 deletions include/phasar/DataFlow/IfdsIde/SolverResults.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class SolverResultsBase {
llvm::Instruction>,
std::unordered_map<d_t, l_t>>
resultsAtInLLVMSSA(ByConstRef<n_t> Stmt, bool AllowOverapproximation = false,
bool StripZero = false);
bool StripZero = false) const;

/// Returns the L-type result at the given statement for the given data-flow
/// fact while respecting LLVM's SSA semantics.
Expand All @@ -118,7 +118,7 @@ class SolverResultsBase {
llvm::Instruction>,
l_t>
resultAtInLLVMSSA(ByConstRef<n_t> Stmt, d_t Value,
bool AllowOverapproximation = false);
bool AllowOverapproximation = false) const;

[[nodiscard]] std::vector<typename Table<n_t, d_t, l_t>::Cell>
getAllResultEntries() const {
Expand All @@ -129,7 +129,7 @@ class SolverResultsBase {
void dumpResults(const ICFGTy &ICF, const NodePrinterBase<n_t> &NP,
const DataFlowFactPrinterBase<d_t> &DP,
const EdgeFactPrinterBase<l_t> &LP,
llvm::raw_ostream &OS = llvm::outs()) {
llvm::raw_ostream &OS = llvm::outs()) const {
using f_t = typename ICFGTy::f_t;

PAMM_GET_INSTANCE;
Expand Down Expand Up @@ -179,15 +179,11 @@ class SolverResultsBase {

template <typename ICFGTy, typename ProblemTy>
void dumpResults(const ICFGTy &ICF, const ProblemTy &IDEProblem,
llvm::raw_ostream &OS = llvm::outs()) {
llvm::raw_ostream &OS = llvm::outs()) const {
dumpResults(ICF, IDEProblem, IDEProblem, IDEProblem, OS);
}

private:
[[nodiscard]] Derived &self() noexcept {
static_assert(std::is_base_of_v<SolverResultsBase, Derived>);
return static_cast<Derived &>(*this);
}
[[nodiscard]] const Derived &self() const noexcept {
static_assert(std::is_base_of_v<SolverResultsBase, Derived>);
return static_cast<const Derived &>(*this);
Expand All @@ -206,12 +202,12 @@ class SolverResults
using typename base_t::l_t;
using typename base_t::n_t;

SolverResults(Table<n_t, d_t, l_t> &ResTab, ByConstRef<d_t> ZV) noexcept
SolverResults(const Table<n_t, d_t, l_t> &ResTab, ByConstRef<d_t> ZV) noexcept
: Results(ResTab), ZV(ZV) {}
SolverResults(Table<n_t, d_t, l_t> &&ResTab, ByConstRef<d_t> ZV) = delete;

private:
Table<n_t, d_t, l_t> &Results;
const Table<n_t, d_t, l_t> &Results;
ByConstRef<D> ZV;
};

Expand All @@ -229,16 +225,20 @@ class OwningSolverResults

OwningSolverResults(Table<N, D, L> ResTab,
D ZV) noexcept(std::is_nothrow_move_constructible_v<D>)
: Results(std::move(ResTab)), ZV(ZV) {}
: Results(std::move(ResTab)), ZV(std::move(ZV)) {}

[[nodiscard]] operator SolverResults<N, D, L>() const &noexcept {
[[nodiscard]] SolverResults<N, D, L> get() const &noexcept {
return {Results, ZV};
}
SolverResults<N, D, L> get() && = delete;

[[nodiscard]] operator SolverResults<N, D, L>() const &noexcept {
return get();
}
operator SolverResults<N, D, L>() && = delete;

private:
// psr::Table is not const-enabled, so we have to give out mutable references
mutable Table<N, D, L> Results;
Table<N, D, L> Results;
D ZV;
};

Expand Down
5 changes: 4 additions & 1 deletion include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/MemoryBufferRef.h"
#include "llvm/Support/raw_ostream.h"

#include <memory>
Expand All @@ -48,10 +49,12 @@ class LLVMProjectIRDB : public ProjectIRDBBase<LLVMProjectIRDB> {
/// CAUTION: Do not manage the same LLVM Module with multiple LLVMProjectIRDB
/// instances at the same time! This will confuse the ModulesToSlotTracker
explicit LLVMProjectIRDB(llvm::Module *Mod);
/// Initializes the new ProjectIRDB with the given IR Moduleand takes
/// Initializes the new ProjectIRDB with the given IR Module and takes
/// ownership of it
explicit LLVMProjectIRDB(std::unique_ptr<llvm::Module> Mod,
bool DoPreprocessing = true);
/// Parses the given LLVM IR file and owns the resulting IR Module
explicit LLVMProjectIRDB(llvm::MemoryBufferRef Buf);

LLVMProjectIRDB(const LLVMProjectIRDB &) = delete;
LLVMProjectIRDB &operator=(LLVMProjectIRDB &) = delete;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace psr::detail {
template <typename Derived, typename N, typename D, typename L>
template <typename NTy>
auto SolverResultsBase<Derived, N, D, L>::resultsAtInLLVMSSA(
ByConstRef<n_t> Stmt, bool AllowOverapproximation, bool StripZero) ->
ByConstRef<n_t> Stmt, bool AllowOverapproximation, bool StripZero) const ->
typename std::enable_if_t<
std::is_same_v<std::decay_t<std::remove_pointer_t<NTy>>,
llvm::Instruction>,
Expand Down Expand Up @@ -96,7 +96,7 @@ auto SolverResultsBase<Derived, N, D, L>::resultsAtInLLVMSSA(
template <typename Derived, typename N, typename D, typename L>
template <typename NTy>
auto SolverResultsBase<Derived, N, D, L>::resultAtInLLVMSSA(
ByConstRef<n_t> Stmt, d_t Value, bool AllowOverapproximation) ->
ByConstRef<n_t> Stmt, d_t Value, bool AllowOverapproximation) const ->
typename std::enable_if_t<
std::is_same_v<std::decay_t<std::remove_pointer_t<NTy>>,
llvm::Instruction>,
Expand Down
55 changes: 55 additions & 0 deletions include/phasar/Utils/ChronoUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/******************************************************************************
* Copyright (c) 2023 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_UTILS_CHRONO_UTILS_H
#define PHASAR_PHASARLLVM_UTILS_CHRONO_UTILS_H

#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"

#include <chrono>

namespace psr {

/// Simple struct that allows formatting of time-durations as
/// hours:minutes:seconds.microseconds.
///
/// \remark This feature may come into C++23, so until then, use this one.
struct hms { // NOLINT
std::chrono::hours Hours{};
std::chrono::minutes Minutes{};
std::chrono::seconds Seconds{};
std::chrono::microseconds Micros{};

hms() noexcept = default;
hms(std::chrono::nanoseconds NS) noexcept {
using namespace std::chrono;

Hours = duration_cast<hours>(NS);
NS -= Hours;
Minutes = duration_cast<minutes>(NS);
NS -= Minutes;
Seconds = duration_cast<seconds>(NS);
NS -= Seconds;
Micros = duration_cast<microseconds>(NS);
}

friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const hms &HMS);

[[nodiscard]] std::string str() const {
std::string Ret;
llvm::raw_string_ostream OS(Ret);
OS << *this;
return Ret;
}
};

} // namespace psr

#endif // PHASAR_PHASARLLVM_UTILS_CHRONO_UTILS_H
45 changes: 45 additions & 0 deletions include/phasar/Utils/DefaultValue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/******************************************************************************
* Copyright (c) 2023 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_UTILS_DEFAULTVALUE_H
#define PHASAR_PHASARLLVM_UTILS_DEFAULTVALUE_H

#include "phasar/Utils/ByRef.h"

#include <type_traits>

namespace psr {

/// Gets a (cached) reference to the default-constructed value of type T. If T
/// is small and trivially default constructible, creates a temporary instead.
/// Useful for getters that return ByConstRef<T> but need to handle the
/// non-existing-T case
template <typename T,
typename = std::enable_if_t<std::is_default_constructible_v<T>>>
[[nodiscard]] ByConstRef<T>
getDefaultValue() noexcept(std::is_nothrow_default_constructible_v<T>) {
auto DefaultConstruct = [] {
if constexpr (std::is_aggregate_v<T>) {
return T{};
} else {
return T();
}
};

if constexpr (CanEfficientlyPassByValue<T>) {
return DefaultConstruct();
} else {
static T DefaultVal = DefaultConstruct();
return DefaultVal;
}
}

} // namespace psr

#endif // PHASAR_PHASARLLVM_UTILS_DEFAULTVALUE_H
9 changes: 5 additions & 4 deletions include/phasar/Utils/EquivalenceClassMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifndef PHASAR_UTILS_EQUIVALENCECLASSMAP_H
#define PHASAR_UTILS_EQUIVALENCECLASSMAP_H

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/iterator_range.h"

#include <initializer_list>
Expand Down Expand Up @@ -148,10 +149,10 @@ template <typename KeyT, typename ValueT> struct EquivalenceClassMap {
}

[[nodiscard]] const_iterator find(key_type Key) const {
return find_if(StoredData.begin(), StoredData.end(),
[&Key](const EquivalenceClassBucketT &Val) -> bool {
return Val.first.count(Key) >= 1;
});
return llvm::find_if(StoredData,
[&Key](const EquivalenceClassBucketT &Val) -> bool {
return Val.first.count(Key) >= 1;
});
}

[[nodiscard]] std::optional<ValueT> findValue(key_type Key) const {
Expand Down
Loading