Skip to content

Commit

Permalink
Merge branch 'development' into f-MoveAnalysisController
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianbs96 authored Aug 9, 2024
2 parents 930ab4d + 0c7b979 commit 1a1f3b7
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 114 deletions.
37 changes: 37 additions & 0 deletions include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,23 @@ defaultComposeOrNull(EdgeFunctionRef<ConcreteEF> This,
return nullptr;
}

template <typename L>
EdgeFunction<L>
defaultComposeOrNull(const EdgeFunction<L> &This,
const EdgeFunction<L> &SecondFunction) noexcept {
if (llvm::isa<EdgeIdentity<L>>(SecondFunction)) {
return This;
}
if (SecondFunction.isConstant() || llvm::isa<AllTop<L>>(This) ||
llvm::isa<EdgeIdentity<L>>(This)) {
return SecondFunction;
}
if (llvm::isa<AllBottom<L>>(This)) {
return This;
}
return nullptr;
}

template <typename L> struct ConstantEdgeFunction {
using l_t = L;
using JLattice = JoinLatticeTraits<L>;
Expand Down Expand Up @@ -409,6 +426,26 @@ EdgeFunction<L> defaultJoinOrNull(EdgeFunctionRef<ConcreteEF> This,
return nullptr;
}

template <typename L, uint8_t N = 0>
EdgeFunction<L> defaultJoinOrNull(const EdgeFunction<L> &This,
const EdgeFunction<L> &OtherFunction) {
if (llvm::isa<AllBottom<L>>(OtherFunction) || llvm::isa<AllTop<L>>(This)) {
return OtherFunction;
}
if (llvm::isa<AllTop<L>>(OtherFunction) || OtherFunction == This ||
llvm::isa<AllBottom<L>>(This)) {
return This;
}
if (llvm::isa<EdgeIdentity<L>>(OtherFunction)) {
if constexpr (N > 0) {
return JoinEdgeFunction<L, N>::create(This, OtherFunction);
} else if constexpr (HasJoinLatticeTraits<L>) {
return AllBottom<L>{};
}
}
return nullptr;
}

template <typename L>
EdgeFunction<L> EdgeIdentity<L>::join(EdgeFunctionRef<EdgeIdentity> This,
const EdgeFunction<L> &OtherFunction) {
Expand Down
2 changes: 2 additions & 0 deletions include/phasar/DataFlow/IfdsIde/IDETabulationProblem.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "phasar/Utils/JoinLattice.h"
#include "phasar/Utils/NullAnalysisPrinter.h"
#include "phasar/Utils/Printer.h"
#include "phasar/Utils/SemiRing.h"
#include "phasar/Utils/Soundness.h"

#include "llvm/ADT/StringRef.h"
Expand Down Expand Up @@ -62,6 +63,7 @@ template <typename AnalysisDomainTy,
class IDETabulationProblem : public FlowFunctions<AnalysisDomainTy, Container>,
public EdgeFunctions<AnalysisDomainTy>,
public JoinLattice<AnalysisDomainTy>,
public SemiRing<AnalysisDomainTy>,
public AllTopFnProvider<AnalysisDomainTy> {
public:
using ProblemAnalysisDomain = AnalysisDomainTy;
Expand Down
21 changes: 11 additions & 10 deletions include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ class IDESolver
PHASAR_LOG_LEVEL(DEBUG,
"Compose: " << SumEdgFnE << " * " << f << '\n');
WorkList.emplace_back(PathEdge(d1, ReturnSiteN, std::move(d3)),
f.composeWith(SumEdgFnE));
IDEProblem.extend(f, SumEdgFnE));
}
}
} else {
Expand Down Expand Up @@ -498,15 +498,15 @@ class IDESolver
<< f4);
PHASAR_LOG_LEVEL(DEBUG,
" (return * calleeSummary * call)");
EdgeFunction<l_t> fPrime =
f4.composeWith(fCalleeSummary).composeWith(f5);
EdgeFunction<l_t> fPrime = IDEProblem.extend(
IDEProblem.extend(f4, fCalleeSummary), f5);
PHASAR_LOG_LEVEL(DEBUG, " = " << fPrime);
d_t d5_restoredCtx = restoreContextOnReturnedFact(n, d2, d5);
// propagte the effects of the entire call
PHASAR_LOG_LEVEL(DEBUG, "Compose: " << fPrime << " * " << f);
WorkList.emplace_back(
PathEdge(d1, RetSiteN, std::move(d5_restoredCtx)),
f.composeWith(fPrime));
IDEProblem.extend(f, fPrime));
}
}
}
Expand Down Expand Up @@ -538,7 +538,7 @@ class IDESolver
.push_back(EdgeFnE);
}
INC_COUNTER("EF Queries", 1, Full);
auto fPrime = f.composeWith(EdgeFnE);
auto fPrime = IDEProblem.extend(f, EdgeFnE);
PHASAR_LOG_LEVEL(DEBUG, "Compose: " << EdgeFnE << " * " << f << " = "
<< fPrime);
WorkList.emplace_back(PathEdge(d1, ReturnSiteN, std::move(d3)),
Expand Down Expand Up @@ -570,7 +570,7 @@ class IDESolver
EdgeFunction<l_t> g =
CachedFlowEdgeFunctions.getNormalEdgeFunction(n, d2, nPrime, d3);
PHASAR_LOG_LEVEL(DEBUG, "Queried Normal Edge Function: " << g);
EdgeFunction<l_t> fPrime = f.composeWith(g);
EdgeFunction<l_t> fPrime = IDEProblem.extend(f, g);
if (SolverConfig.emitESG()) {
IntermediateEdgeFunctions[std::make_tuple(n, d2, nPrime, d3)]
.push_back(g);
Expand Down Expand Up @@ -950,7 +950,8 @@ class IDESolver
PHASAR_LOG_LEVEL(DEBUG,
"Compose: " << f5 << " * " << f << " * " << f4);
PHASAR_LOG_LEVEL(DEBUG, " (return * function * call)");
EdgeFunction<l_t> fPrime = f4.composeWith(f).composeWith(f5);
EdgeFunction<l_t> fPrime =
IDEProblem.extend(IDEProblem.extend(f4, f), f5);
PHASAR_LOG_LEVEL(DEBUG, " = " << fPrime);
// for each jump function coming into the call, propagate to
// return site using the composed function
Expand All @@ -965,7 +966,7 @@ class IDESolver
PHASAR_LOG_LEVEL(DEBUG, "Compose: " << fPrime << " * " << f3);
WorkList.emplace_back(PathEdge(std::move(d3), RetSiteC,
std::move(d5_restoredCtx)),
f3.composeWith(fPrime));
IDEProblem.extend(f3, fPrime));
}
}
}
Expand Down Expand Up @@ -1004,7 +1005,7 @@ class IDESolver
}
INC_COUNTER("EF Queries", 1, Full);
PHASAR_LOG_LEVEL(DEBUG, "Compose: " << f5 << " * " << f);
propagteUnbalancedReturnFlow(RetSiteC, d5, f.composeWith(f5),
propagteUnbalancedReturnFlow(RetSiteC, d5, IDEProblem.extend(f, f5),
Caller);
// register for value processing (2nd IDE phase)
UnbalancedRetSites.insert(RetSiteC);
Expand Down Expand Up @@ -1153,7 +1154,7 @@ class IDESolver
// was found
return AllTop;
}();
EdgeFunction<l_t> fPrime = JumpFnE.joinWith(f);
EdgeFunction<l_t> fPrime = IDEProblem.combine(JumpFnE, f);
bool NewFunction = fPrime != JumpFnE;

IF_LOG_LEVEL_ENABLED(DEBUG, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define PHASAR_PHASARLLVM_DATAFLOW_IFDSIDE_PROBLEMS_IDEINSTINTERACTIONANALYSIS_H

#include "phasar/DataFlow/IfdsIde/DefaultEdgeFunctionSingletonCache.h"
#include "phasar/DataFlow/IfdsIde/EdgeFunction.h"
#include "phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h"
#include "phasar/DataFlow/IfdsIde/FlowFunctions.h"
#include "phasar/DataFlow/IfdsIde/IDETabulationProblem.h"
Expand Down Expand Up @@ -949,59 +950,15 @@ class IDEInstInteractionAnalysisT

l_t computeTarget(ByConstRef<l_t> /* Src */) const { return Replacement; }

static EdgeFunction<l_t> compose(EdgeFunctionRef<IIAAKillOrReplaceEF> This,
const EdgeFunction<l_t> SecondFunction) {

if (auto Default = defaultComposeOrNull(This, SecondFunction)) {
return Default;
}

auto Cache = This.getCacheOrNull();
assert(Cache != nullptr && "We expect a cache, because "
"IIAAKillOrReplaceEF is too large for SOO");

if (auto *AD = llvm::dyn_cast<IIAAAddLabelsEF>(SecondFunction)) {
auto Union =
IDEInstInteractionAnalysisT::joinImpl(This->Replacement, AD->Data);
return Cache->createEdgeFunction(std::move(Union));
}

if (auto *KR = llvm::dyn_cast<IIAAKillOrReplaceEF>(SecondFunction)) {
return SecondFunction;
}
llvm::report_fatal_error(
"found unexpected edge function in 'IIAAKillOrReplaceEF'");
static EdgeFunction<l_t>
compose(EdgeFunctionRef<IIAAKillOrReplaceEF> /*This*/,
const EdgeFunction<l_t> /*SecondFunction*/) {
llvm::report_fatal_error("Implemented in 'extend'");
}

static EdgeFunction<l_t> join(EdgeFunctionRef<IIAAKillOrReplaceEF> This,
const EdgeFunction<l_t> &OtherFunction) {
/// XXX: Here, we underapproximate joins with EdgeIdentity
if (llvm::isa<EdgeIdentity<l_t>>(OtherFunction)) {
return This;
}

if (auto Default = defaultJoinOrNull(This, OtherFunction)) {
return Default;
}

auto Cache = This.getCacheOrNull();
assert(Cache != nullptr && "We expect a cache, because "
"IIAAKillOrReplaceEF is too large for SOO");

if (auto *AD = llvm::dyn_cast<IIAAAddLabelsEF>(OtherFunction)) {
auto ADCache = OtherFunction.template getCacheOrNull<IIAAAddLabelsEF>();
assert(ADCache);
auto Union =
IDEInstInteractionAnalysisT::joinImpl(This->Replacement, AD->Data);
return ADCache->createEdgeFunction(std::move(Union));
}
if (auto *KR = llvm::dyn_cast<IIAAKillOrReplaceEF>(OtherFunction)) {
auto Union = IDEInstInteractionAnalysisT::joinImpl(This->Replacement,
KR->Replacement);
return Cache->createEdgeFunction(std::move(Union));
}
llvm::report_fatal_error(
"found unexpected edge function in 'IIAAKillOrReplaceEF'");
static EdgeFunction<l_t> join(EdgeFunctionRef<IIAAKillOrReplaceEF> /*This*/,
const EdgeFunction<l_t> & /*OtherFunction*/) {
llvm::report_fatal_error("Implemented in 'combine'");
}

bool operator==(const IIAAKillOrReplaceEF &Other) const noexcept {
Expand Down Expand Up @@ -1044,55 +1001,15 @@ class IDEInstInteractionAnalysisT
return IDEInstInteractionAnalysisT::joinImpl(Src, Data);
}

static EdgeFunction<l_t> compose(EdgeFunctionRef<IIAAAddLabelsEF> This,
const EdgeFunction<l_t> &SecondFunction) {
if (auto Default = defaultComposeOrNull(This, SecondFunction)) {
return Default;
}

auto Cache = This.getCacheOrNull();
assert(Cache != nullptr && "We expect a cache, because "
"IIAAAddLabelsEF is too large for SOO");

if (auto *AD = llvm::dyn_cast<IIAAAddLabelsEF>(SecondFunction)) {
auto Union =
IDEInstInteractionAnalysisT::joinImpl(This->Data, AD->Data);
return Cache->createEdgeFunction(std::move(Union));
}
if (auto *KR = llvm::dyn_cast<IIAAKillOrReplaceEF>(SecondFunction)) {
return SecondFunction;
}
llvm::report_fatal_error(
"found unexpected edge function in 'IIAAAddLabelsEF'");
static EdgeFunction<l_t>
compose(EdgeFunctionRef<IIAAAddLabelsEF> /*This*/,
const EdgeFunction<l_t> & /*SecondFunction*/) {
llvm::report_fatal_error("Implemented in 'extend'");
}

static EdgeFunction<l_t> join(EdgeFunctionRef<IIAAAddLabelsEF> This,
const EdgeFunction<l_t> &OtherFunction) {
/// XXX: Here, we underapproximate joins with EdgeIdentity
if (llvm::isa<EdgeIdentity<l_t>>(OtherFunction)) {
return This;
}

if (auto Default = defaultJoinOrNull(This, OtherFunction)) {
return Default;
}

auto Cache = This.getCacheOrNull();
assert(Cache != nullptr && "We expect a cache, because "
"IIAAAddLabelsEF is too large for SOO");

if (auto *AD = llvm::dyn_cast<IIAAAddLabelsEF>(OtherFunction)) {
auto Union =
IDEInstInteractionAnalysisT::joinImpl(This->Data, AD->Data);
return Cache->createEdgeFunction(std::move(Union));
}
if (auto *KR = llvm::dyn_cast<IIAAKillOrReplaceEF>(OtherFunction)) {
auto Union =
IDEInstInteractionAnalysisT::joinImpl(This->Data, KR->Replacement);
return Cache->createEdgeFunction(std::move(Union));
}
llvm::report_fatal_error(
"found unexpected edge function in 'IIAAAddLabelsEF'");
static EdgeFunction<l_t> join(EdgeFunctionRef<IIAAAddLabelsEF> /*This*/,
const EdgeFunction<l_t> & /*OtherFunction*/) {
llvm::report_fatal_error("Implemented in 'combine'");
}

bool operator==(const IIAAAddLabelsEF &Other) const noexcept {
Expand All @@ -1112,6 +1029,64 @@ class IDEInstInteractionAnalysisT
}
};

const auto &getData(const EdgeFunction<l_t> &EF) {
if (const auto *AddLabels = llvm::dyn_cast<IIAAAddLabelsEF>(EF)) {
return AddLabels->Data;
}
if (const auto *KillOrReplace = llvm::dyn_cast<IIAAKillOrReplaceEF>(EF)) {
return KillOrReplace->Replacement;
}
llvm::report_fatal_error(
"found unexpected first edge function in 'getData': " +
llvm::Twine(to_string(EF)));
}

EdgeFunction<l_t> extend(const EdgeFunction<l_t> &FirstFunction,
const EdgeFunction<l_t> &SecondFunction) override {
if (auto Default = defaultComposeOrNull(FirstFunction, SecondFunction)) {
return Default;
}

const auto &ThisData = getData(FirstFunction);

if (auto *AD = llvm::dyn_cast<IIAAAddLabelsEF>(SecondFunction)) {
auto Union = IDEInstInteractionAnalysisT::joinImpl(ThisData, AD->Data);
return llvm::isa<IIAAAddLabelsEF>(FirstFunction)
? IIAAAddLabelsEFCache.createEdgeFunction(std::move(Union))
: IIAAKillOrReplaceEFCache.createEdgeFunction(
std::move(Union));
}

llvm::report_fatal_error(
"found unexpected second edge function in 'extend'");
}

EdgeFunction<l_t> combine(const EdgeFunction<l_t> &FirstFunction,
const EdgeFunction<l_t> &OtherFunction) override {
/// XXX: Here, we underapproximate joins with EdgeIdentity
if (llvm::isa<EdgeIdentity<l_t>>(FirstFunction)) {
return OtherFunction;
}
if (llvm::isa<EdgeIdentity<l_t>>(OtherFunction) &&
!llvm::isa<AllTop<l_t>>(FirstFunction)) {
return FirstFunction;
}

if (auto Default = defaultJoinOrNull(FirstFunction, OtherFunction)) {
return Default;
}

const auto &ThisData = getData(FirstFunction);
const auto &OtherData = getData(OtherFunction);
auto Union = IDEInstInteractionAnalysisT::joinImpl(ThisData, OtherData);

if (llvm::isa<IIAAKillOrReplaceEF>(FirstFunction) &&
llvm::isa<IIAAKillOrReplaceEF>(OtherFunction)) {
return IIAAKillOrReplaceEFCache.createEdgeFunction(std::move(Union));
}
return IIAAAddLabelsEFCache.createEdgeFunction(std::move(Union));
}

// Provide functionalities for printing things and emitting text reports.

static void stripBottomResults(std::unordered_map<d_t, l_t> &Res) {
Expand Down Expand Up @@ -1173,7 +1148,7 @@ class IDEInstInteractionAnalysisT
}
if (const auto *H = llvm::dyn_cast<llvm::CallBase>(I)) {
if (!H->isIndirectCall() && H->getCalledFunction() &&
this->ICF->isHeapAllocatingFunction(H->getCalledFunction())) {
psr::isHeapAllocatingFunction(H->getCalledFunction())) {
Variables.insert(H);
}
}
Expand Down
10 changes: 5 additions & 5 deletions include/phasar/Utils/BitVectorSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,11 @@ template <typename T> class BitVectorSet {
}

[[nodiscard]] BitVectorSet<T> setUnion(const BitVectorSet<T> &Other) const {
size_t MaxSize = std::max(Bits.size(), Other.Bits.size());
BitVectorSet<T> Res;
Res.Bits.reserve(MaxSize);
Res.Bits = Bits;
Res.Bits |= Other.Bits;
const bool ThisSetIsSmaller = Bits.size() < Other.Bits.size();
BitVectorSet<T> Res = ThisSetIsSmaller ? Other : *this;
const BitVectorSet &Smaller = ThisSetIsSmaller ? *this : Other;

Res.Bits |= Smaller.Bits;
return Res;
}

Expand Down
Loading

0 comments on commit 1a1f3b7

Please sign in to comment.