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
3 changes: 3 additions & 0 deletions include/phasar/Controller/AnalysisController.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "phasar/DB/ProjectIRDB.h"
#include "phasar/PhasarLLVM/AnalysisStrategy/Strategies.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/IFDSIDESolverConfig.h"
#include "phasar/PhasarLLVM/Pointer/LLVMBasedPointsToAnalysis.h"
#include "phasar/PhasarLLVM/Pointer/LLVMPointsToSet.h"
#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h"
Expand Down Expand Up @@ -62,6 +63,7 @@ class AnalysisController {
std::string ProjectID;
std::string OutDirectory;
boost::filesystem::path ResultDirectory;
IFDSIDESolverConfig SolverConfig;
[[maybe_unused]] Soundness SoundnessLevel;
[[maybe_unused]] bool AutoGlobalSupport;

Expand Down Expand Up @@ -122,6 +124,7 @@ class AnalysisController {
const std::set<std::string> &EntryPoints,
AnalysisStrategy Strategy,
AnalysisControllerEmitterOptions EmitterOptions,
IFDSIDESolverConfig SolverConfig,
const std::string &ProjectID = "default-phasar-project",
const std::string &OutDirectory = "");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include "phasar/DB/ProjectIRDB.h"
#include "phasar/PhasarLLVM/AnalysisStrategy/AnalysisSetup.h"
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/IFDSIDESolverConfig.h"
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h"

namespace psr {

Expand Down Expand Up @@ -51,7 +53,7 @@ class WholeProgramAnalysis {
Solver DataFlowSolver;

public:
WholeProgramAnalysis(ProjectIRDB &IRDB,
WholeProgramAnalysis(IFDSIDESolverConfig SolverConfig, ProjectIRDB &IRDB,
std::set<std::string> EntryPoints = {},
PointerAnalysisTy *PointerInfo = nullptr,
CallGraphAnalysisTy *CallGraph = nullptr,
Expand All @@ -70,12 +72,17 @@ class WholeProgramAnalysis {
: std::unique_ptr<CallGraphAnalysisTy>(CallGraph)),
EntryPoints(EntryPoints),
ProblemDesc(&IRDB, TypeHierarchy, CallGraph, PointerInfo, EntryPoints),
DataFlowSolver(ProblemDesc) {}
DataFlowSolver(ProblemDesc) {
if constexpr (has_setIFDSIDESolverConfig_v<ProblemDescription>) {
ProblemDesc.setIFDSIDESolverConfig(SolverConfig);
}
}

template <typename T = ProblemDescription,
typename = typename std::enable_if_t<!std::is_same_v<
typename T::ConfigurationTy, HasNoConfigurationType>>>
WholeProgramAnalysis(ProjectIRDB &IRDB, ConfigurationTy *Config,
WholeProgramAnalysis(IFDSIDESolverConfig SolverConfig, ProjectIRDB &IRDB,
ConfigurationTy *Config,
std::set<std::string> EntryPoints = {},
PointerAnalysisTy *PointerInfo = nullptr,
CallGraphAnalysisTy *CallGraph = nullptr,
Expand All @@ -95,12 +102,17 @@ class WholeProgramAnalysis {
EntryPoints(EntryPoints), Config(Config),
ProblemDesc(&IRDB, TypeHierarchy, CallGraph, PointerInfo, *Config,
EntryPoints),
DataFlowSolver(ProblemDesc) {}
DataFlowSolver(ProblemDesc) {
if constexpr (has_setIFDSIDESolverConfig_v<ProblemDescription>) {
ProblemDesc.setIFDSIDESolverConfig(SolverConfig);
}
}

template <typename T = ProblemDescription,
typename = typename std::enable_if_t<!std::is_same_v<
typename T::ConfigurationTy, HasNoConfigurationType>>>
WholeProgramAnalysis(ProjectIRDB &IRDB, std::string ConfigPath,
WholeProgramAnalysis(IFDSIDESolverConfig SolverConfig, ProjectIRDB &IRDB,
std::string ConfigPath,
std::set<std::string> EntryPoints = {},
PointerAnalysisTy *PointerInfo = nullptr,
CallGraphAnalysisTy *CallGraph = nullptr,
Expand All @@ -121,7 +133,11 @@ class WholeProgramAnalysis {
OwnsConfig(true), ConfigPath(ConfigPath),
ProblemDesc(&IRDB, TypeHierarchy, CallGraph, PointerInfo, *Config,
EntryPoints),
DataFlowSolver(ProblemDesc) {}
DataFlowSolver(ProblemDesc) {
if constexpr (has_setIFDSIDESolverConfig_v<ProblemDescription>) {
ProblemDesc.setIFDSIDESolverConfig(SolverConfig);
}
Comment on lines +137 to +139
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is always defined on IFDS and IDE problems. We can remove this check.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The WholeProgramAnalysis is used for the Mono-analyses as well. They do not define that function

}

WholeProgramAnalysis(const WholeProgramAnalysis &) = delete;
WholeProgramAnalysis(WholeProgramAnalysis &&) = delete;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include "phasar/Config/Configuration.h"
#include "phasar/Utils/EnumFlags.h"
#include "phasar/Utils/Logger.h"
#include "phasar/Utils/Utilities.h"

namespace psr {

Expand All @@ -39,13 +38,14 @@ enum class SolverConfigOptions : uint32_t {
};

struct IFDSIDESolverConfig {
IFDSIDESolverConfig();
IFDSIDESolverConfig(SolverConfigOptions Options);
IFDSIDESolverConfig() noexcept = default;
IFDSIDESolverConfig(SolverConfigOptions Options) noexcept;
~IFDSIDESolverConfig() = default;
IFDSIDESolverConfig(const IFDSIDESolverConfig &) = default;
IFDSIDESolverConfig &operator=(const IFDSIDESolverConfig &) = default;
IFDSIDESolverConfig(IFDSIDESolverConfig &&) = default;
IFDSIDESolverConfig &operator=(IFDSIDESolverConfig &&) = default;
IFDSIDESolverConfig(const IFDSIDESolverConfig &) noexcept = default;
IFDSIDESolverConfig &
operator=(const IFDSIDESolverConfig &) noexcept = default;
IFDSIDESolverConfig(IFDSIDESolverConfig &&) noexcept = default;
IFDSIDESolverConfig &operator=(IFDSIDESolverConfig &&) noexcept = default;

[[nodiscard]] bool followReturnsPastSeeds() const;
[[nodiscard]] bool autoAddZero() const;
Expand All @@ -61,6 +61,8 @@ struct IFDSIDESolverConfig {
void setEmitESG(bool Set = true);
void setComputePersistedSummaries(bool Set = true);

void setConfig(SolverConfigOptions Opt);

friend std::ostream &operator<<(std::ostream &OS,
const IFDSIDESolverConfig &SC);

Expand Down
13 changes: 13 additions & 0 deletions include/phasar/Utils/TypeTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <type_traits>
#include <variant>

#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/IFDSIDESolverConfig.h"

#include "llvm/Support/raw_ostream.h"

namespace psr {
Expand Down Expand Up @@ -75,6 +77,13 @@ template <typename T>
struct is_llvm_hashable<T, decltype(hash_value(std::declval<T>()))> // NOLINT
: std::true_type {};

template <typename T, typename = void>
struct has_setIFDSIDESolverConfig : std::false_type {};
template <typename T>
struct has_setIFDSIDESolverConfig<
T, decltype(std::declval<T>().setIFDSIDESolverConfig(
std::declval<IFDSIDESolverConfig>()))> : std::true_type {};

Comment on lines +80 to +86
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need that (cf. comment in the above).

} // namespace detail

template <typename T>
Expand Down Expand Up @@ -111,6 +120,10 @@ template <typename T>
constexpr bool is_llvm_hashable_v = // NOLINT
detail::is_llvm_hashable<T>::value;

template <typename T>
constexpr bool has_setIFDSIDESolverConfig_v = // NOLINT
detail::has_setIFDSIDESolverConfig<T>::value;

template <typename T> struct is_variant : std::false_type {}; // NOLINT

template <typename... Args>
Expand Down
51 changes: 29 additions & 22 deletions include/phasar/Utils/Utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,41 +197,48 @@ It remove_by_index(It First, EndIt Last, IdxIt FirstIndex, IdxEndIt LastIndex) {
if (FirstIndex == LastIndex || First == Last) {
return Last;
}
First = std::next(First, *FirstIndex);
if (First == Last) {
return First;
}

auto CurrIdx = *FirstIndex;

if constexpr (std::is_same_v<It, EndIt> &&
std::is_same_v<
std::random_access_iterator_tag,
typename std::iterator_traits<It>::iterator_category>) {
size_t GapSize = 1;
auto Curr = First + 1;
/// Random-access version inspired from
/// "https://codereview.stackexchange.com/a/207056" and slightly changed

auto Bounds = size_t(std::distance(First, Last));
auto Out = std::next(First, *FirstIndex);
auto In = std::next(Out);
while (++FirstIndex != LastIndex) {
auto Offset = *FirstIndex - CurrIdx - 1;
if (Offset >= std::distance(Curr, Last)) {
auto CurrIdx = *FirstIndex;
if (*std::prev(FirstIndex) + 1 == CurrIdx) {
++In;
continue;
}
if (LLVM_UNLIKELY(CurrIdx >= Bounds)) {
break;
}
First = std::move(Curr, Curr + Offset, First); // NOLINT
CurrIdx = *FirstIndex;
Curr = First + ++GapSize;
}

return std::move(Curr, Last, First); // NOLINT
}
for (auto I = First; I != Last; ++CurrIdx, ++I) {
if (CurrIdx != *FirstIndex) {
*First++ = std::move(*I);
if (++FirstIndex == LastIndex) {
return std::move(std::next(I), Last, First);
auto Tar = std::next(First, CurrIdx);
Out = std::move(In, Tar, Out);
In = std::next(Tar);
}
return std::move(In, Last, Out);
} else {
auto CurrIdx = *FirstIndex;
First = std::next(First, CurrIdx);
if (First == Last) {
return First;
}
for (auto I = First; I != Last; ++CurrIdx, ++I) {
if (CurrIdx != *FirstIndex) {
*First++ = std::move(*I);
if (++FirstIndex == LastIndex) {
return std::move(std::next(I), Last, First);
}
}
}
return First;
}
return First;
}

template <typename Container, typename IdxIt,
Expand Down
Loading