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
84 changes: 41 additions & 43 deletions include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,49 +70,48 @@ template <typename L> struct ConstantEdgeFunction {

[[nodiscard]] constexpr bool isConstant() const noexcept { return true; }

// -- constant data member
[[nodiscard]] friend constexpr bool
operator==(ConstantEdgeFunction<L> LHS, ConstantEdgeFunction<L> RHS) noexcept
requires CanEfficientlyPassByValue<ConstantEdgeFunction>
{
return LHS.Value == RHS.Value;
}

value_type Value{};
};
[[nodiscard]] friend constexpr bool
operator==(const ConstantEdgeFunction<L> &LHS,
const ConstantEdgeFunction<L> &RHS) noexcept
requires(!CanEfficientlyPassByValue<ConstantEdgeFunction>)
{
return LHS.Value == RHS.Value;
}

template <typename L>
requires CanEfficientlyPassByValue<ConstantEdgeFunction<L>>
[[nodiscard]] constexpr bool operator==(ConstantEdgeFunction<L> LHS,
ConstantEdgeFunction<L> RHS) noexcept {
return LHS.Value == RHS.Value;
}
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const ConstantEdgeFunction &Id) {
OS << "ConstantEF";
if constexpr (is_llvm_printable_v<
typename ConstantEdgeFunction<L>::value_type>) {
OS << '[' << Id.Value << ']';
}
return OS;
}

template <typename L>
requires(!CanEfficientlyPassByValue<ConstantEdgeFunction<L>>)
[[nodiscard]] constexpr bool
operator==(const ConstantEdgeFunction<L> &LHS,
const ConstantEdgeFunction<L> &RHS) noexcept {
return LHS.Value == RHS.Value;
}
[[nodiscard]] friend auto hash_value(const ConstantEdgeFunction &CEF) noexcept
requires(is_std_hashable_v<typename NonTopBotValue<L>::type> ||
is_llvm_hashable_v<typename NonTopBotValue<L>::type>)
{
using value_type = typename ConstantEdgeFunction<L>::value_type;
if constexpr (is_std_hashable_v<value_type>) {
return std::hash<value_type>{}(CEF.Value);
} else {
using llvm::hash_value;
return hash_value(CEF.Value);
}
}

template <typename L>
[[nodiscard]] llvm::raw_ostream &
operator<<(llvm::raw_ostream &OS, ByConstRef<ConstantEdgeFunction<L>> Id) {
OS << "ConstantEF";
if constexpr (is_llvm_printable_v<
typename ConstantEdgeFunction<L>::value_type>) {
OS << '[' << Id.Value << ']';
}
return OS;
}
// -- constant data member

template <typename L>
requires(is_std_hashable_v<typename NonTopBotValue<L>::type> ||
is_llvm_hashable_v<typename NonTopBotValue<L>::type>)
[[nodiscard]] auto hash_value(const ConstantEdgeFunction<L> &CEF) noexcept {
using value_type = typename ConstantEdgeFunction<L>::value_type;
if constexpr (is_std_hashable_v<value_type>) {
return std::hash<value_type>{}(CEF.Value);
} else {
using llvm::hash_value;
return hash_value(CEF.Value);
}
}
value_type Value{};
};

template <typename L> struct AllBottom final {
using l_t = L;
Expand Down Expand Up @@ -299,6 +298,10 @@ template <typename L> struct EdgeFunctionComposer {
return First.depth() + Second.depth();
}

friend auto hash_value(const EdgeFunctionComposer &EFC) noexcept {
return llvm::hash_combine(EFC.First, EFC.Second);
}

// -- data members

EdgeFunction<l_t> First{};
Expand All @@ -307,11 +310,6 @@ template <typename L> struct EdgeFunctionComposer {

static_assert(HasDepth<EdgeFunctionComposer<int>>);

template <typename L>
auto hash_value(const EdgeFunctionComposer<L> &EFC) noexcept {
return llvm::hash_combine(EFC.First, EFC.Second);
}

template <typename L, uint8_t N> struct JoinEdgeFunction {
using l_t = L;
using JLattice = JoinLatticeTraits<L>;
Expand Down
14 changes: 6 additions & 8 deletions include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ class IDESolver
getSolverResults().dumpResults(*ICF, OS);
}

friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const IDESolver &Solver) {
Solver.dumpResults(OS);
return OS;
}

void dumpAllInterPathEdges() {
llvm::outs() << "COMPUTED INTER PATH EDGES" << '\n';
auto Interpe = this->computedInterPathEdges.cellSet();
Expand Down Expand Up @@ -1917,14 +1923,6 @@ class IDESolver
std::map<std::pair<n_t, d_t>, size_t> FSummaryReuse;
};

template <typename AnalysisDomainTy, typename Container>
llvm::raw_ostream &
operator<<(llvm::raw_ostream &OS,
const IDESolver<AnalysisDomainTy, Container> &Solver) {
Solver.dumpResults(OS);
return OS;
}

template <typename Problem, typename ICF>
IDESolver(Problem &, ICF *)
-> IDESolver<typename Problem::ProblemAnalysisDomain,
Expand Down
131 changes: 61 additions & 70 deletions include/phasar/Domain/LatticeDomain.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,94 +103,85 @@ struct LatticeDomain : public std::variant<Top, L, Bottom> {
}

template <typename TransformFn, typename... ArgsT>
void onValue(TransformFn Transform, ArgsT &&...Args) {
constexpr void onValue(TransformFn Transform, ArgsT &&...Args) {
if (auto *Val = getValueOrNull()) {
std::invoke(std::move(Transform), *Val, PSR_FWD(Args)...);
}
}
};

template <typename L>
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const LatticeDomain<L> &LD) {
if (LD.isBottom()) {
return OS << "Bottom";
}
if (LD.isTop()) {
return OS << "Top";
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const LatticeDomain &LD) {
if (LD.isBottom()) {
return OS << "Bottom";
}
if (LD.isTop()) {
return OS << "Top";
}

const auto *Val = LD.getValueOrNull();
assert(Val && "Only alternative remaining is L");
if constexpr (is_llvm_printable_v<L>) {
return OS << *Val;
} else {
return OS << PrettyPrinter{*Val};
}
}

const auto *Val = LD.getValueOrNull();
assert(Val && "Only alternative remaining is L");
if constexpr (is_llvm_printable_v<L>) {
return OS << *Val;
} else {
return OS << PrettyPrinter{*Val};
friend std::ostream &operator<<(std::ostream &OS, const LatticeDomain &LD) {
llvm::raw_os_ostream ROS(OS);
ROS << LD;
return OS;
}
}

template <typename L>
inline std::ostream &operator<<(std::ostream &OS, const LatticeDomain<L> &LD) {
llvm::raw_os_ostream ROS(OS);
ROS << LD;
return OS;
}
constexpr bool operator==(const LatticeDomain &Rhs) const {
if (this->index() != Rhs.index()) {
return false;
}
if (auto LhsPtr = this->getValueOrNull()) {
/// No need to check whether Rhs is an L; the indices are already the same
return *LhsPtr == *Rhs.getValueOrNull();
}
return true;
}

template <typename L>
constexpr bool operator==(const LatticeDomain<L> &Lhs,
const LatticeDomain<L> &Rhs) {
if (Lhs.index() != Rhs.index()) {
template <typename LL>
requires AreEqualityComparable<L, LL>
constexpr bool operator==(const LL &Rhs) const {
if (auto LVal = this->getValueOrNull()) {
return *LVal == Rhs;
}
return false;
}
if (auto LhsPtr = Lhs.getValueOrNull()) {
/// No need to check whether Lhs is an L; the indices are already the same
return *LhsPtr == *Rhs.getValueOrNull();
}
return true;
}

template <typename L, typename LL>
requires AreEqualityComparable<LL, L>
constexpr bool operator==(const LatticeDomain<L> &Lhs, const LL &Rhs) {
if (auto LVal = Lhs.getValueOrNull()) {
return *LVal == Rhs;
constexpr bool operator==(Bottom /*Rhs*/) const noexcept {
return this->isBottom();
}
return false;
}

template <typename L>
constexpr bool operator==(const LatticeDomain<L> &Lhs,
Bottom /*Rhs*/) noexcept {
return Lhs.isBottom();
}

template <typename L>
constexpr bool operator==(const LatticeDomain<L> &Lhs, Top /*Rhs*/) noexcept {
return Lhs.isTop();
}

template <typename L>
constexpr bool operator<(const LatticeDomain<L> &Lhs,
const LatticeDomain<L> &Rhs) {
/// Top < (Lhs::L < Rhs::L) < Bottom
if (Rhs.isTop()) {
return false;
}
if (Lhs.isTop()) {
return true;
constexpr bool operator==(Top /*Rhs*/) const noexcept {
return this->isTop();
}
if (auto LhsPtr = Lhs.getValueOrNull()) {
if (auto RhsPtr = Rhs.getValueOrNull()) {
return *LhsPtr < *RhsPtr;

constexpr bool operator<(const LatticeDomain &Rhs) const {
/// Top < (Lhs::L < Rhs::L) < Bottom
if (Rhs.isTop()) {
return false;
}
} else if (Lhs.isBottom()) {
return false;
}
if (Rhs.isBottom()) {
return true;
if (this->isTop()) {
return true;
}
if (auto LhsPtr = this->getValueOrNull()) {
if (auto RhsPtr = Rhs.getValueOrNull()) {
return *LhsPtr < *RhsPtr;
}
} else if (this->isBottom()) {
return false;
}
if (Rhs.isBottom()) {
return true;
}
llvm_unreachable("All comparison cases should be handled above.");
}
llvm_unreachable("All comparison cases should be handled above.");
}
};

template <typename L> struct JoinLatticeTraits<LatticeDomain<L>> {
using l_t = L;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,20 +154,20 @@ class IDEIIAFlowFact {
print(OS);
return Ret;
}
};

inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const IDEIIAFlowFact &FlowFact) {
FlowFact.print(OS);
return OS;
}
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const IDEIIAFlowFact &FlowFact) {
FlowFact.print(OS);
return OS;
}

inline std::ostream &operator<<(std::ostream &OS,
const IDEIIAFlowFact &FlowFact) {
llvm::raw_os_ostream Rso(OS);
FlowFact.print(Rso);
return OS;
}
friend std::ostream &operator<<(std::ostream &OS,
const IDEIIAFlowFact &FlowFact) {
llvm::raw_os_ostream Rso(OS);
FlowFact.print(Rso);
return OS;
}
};

} // namespace psr

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ struct GeneralStatistics {
std::string ModuleName{};

void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const;
};

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const GeneralStatistics &Statistics);
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const GeneralStatistics &Statistics);
};

/**
* This class uses the Module Pass Mechanism of LLVM to compute
Expand Down
13 changes: 6 additions & 7 deletions include/phasar/TypeHierarchy/TypeHierarchy.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,13 @@ template <typename T, typename F> class TypeHierarchy {
virtual void print(llvm::raw_ostream &OS = llvm::outs()) const = 0;

virtual void printAsJson(llvm::raw_ostream &OS) const = 0;
};

template <typename T, typename F>
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const TypeHierarchy<T, F> &TH) {
TH.print(OS);
return OS;
}
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const TypeHierarchy &TH) {
TH.print(OS);
return OS;
}
};

} // namespace psr

Expand Down
13 changes: 6 additions & 7 deletions include/phasar/TypeHierarchy/VFTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,13 @@ template <typename F> class VFTable {
virtual void print(llvm::raw_ostream &OS) const = 0;

virtual void printAsJson(llvm::raw_ostream &OS) const = 0;
};

template <typename T, typename F>
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const VFTable<F> &Table) {
Table.print(OS);
return OS;
}
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const VFTable &Table) {
Table.print(OS);
return OS;
}
};

} // namespace psr

Expand Down
Loading
Loading