Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "phasar/Utils/Logger.h"

#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constant.h"
Expand Down Expand Up @@ -629,26 +630,19 @@ class IDEInstInteractionAnalysisT
// variables using generalized initial seeds

// Generate zero value at the entry points
Seeds.addSeed(SP, this->getZeroValue(), bottomElement());
Seeds.addSeed(SP, this->getZeroValue(), Bottom{});
// Generate formal parameters of entry points, e.g. main(). Formal
// parameters will otherwise cause trouble by overriding alloca
// instructions without being valid data-flow facts themselves.
for (const auto &Arg : SP->getFunction()->args()) {
Seeds.addSeed(SP, &Arg, Bottom{});
Seeds.addSeed(SP, &Arg, BitVectorSet<e_t>());
}
// Generate all global variables using generalized initial seeds

for (const auto &G : this->IRDB->getModule()->globals()) {
if (const auto *GV = llvm::dyn_cast<llvm::GlobalVariable>(&G)) {
l_t InitialValues = BitVectorSet<e_t>();
std::set<e_t> EdgeFacts;
if (EdgeFactGen) {
EdgeFacts = EdgeFactGen(GV);
// fill BitVectorSet
InitialValues =
BitVectorSet<e_t>(EdgeFacts.begin(), EdgeFacts.end());
}
Seeds.addSeed(SP, GV, InitialValues);
l_t InitialValues = bvSetFrom(invoke_or_default(EdgeFactGen, GV));
Seeds.addSeed(SP, GV, std::move(InitialValues));
}
}
});
Expand Down Expand Up @@ -691,7 +685,12 @@ class IDEInstInteractionAnalysisT
if (SuccNode == Store->getPointerOperand() ||
PT.isInReachableAllocationSites(Store->getPointerOperand(), SuccNode,
true, Store)) {
return IIAAAddLabelsEFCache.createEdgeFunction(UserEdgeFacts);
if (isZeroValue(CurrNode)) {
return IIAAKillOrReplaceEFCache.createEdgeFunction(
std::move(UserEdgeFacts));
}
return IIAAAddLabelsEFCache.createEdgeFunction(
std::move(UserEdgeFacts));
}
}

Expand All @@ -709,7 +708,7 @@ class IDEInstInteractionAnalysisT
// v
// y
//
if ((CurrNode == SuccNode) && CurrNode == Store->getPointerOperand()) {
if (CurrNode == SuccNode && CurrNode == Store->getPointerOperand()) {
// y obtains its value(s) from its original allocation and the store
// instruction under analysis.
IF_LOG_ENABLED({
Expand All @@ -722,7 +721,8 @@ class IDEInstInteractionAnalysisT
PHASAR_LOG_LEVEL(DFADEBUG, '\n');
});
// obtain label from the original allocation
return IIAAKillOrReplaceEFCache.createEdgeFunction(UserEdgeFacts);
return IIAAKillOrReplaceEFCache.createEdgeFunction(
std::move(UserEdgeFacts));
}

} else {
Expand Down Expand Up @@ -800,7 +800,11 @@ class IDEInstInteractionAnalysisT

// We generate Curr in this instruction, so we have to annotate it with
// edge labels
return IIAAAddLabelsEFCache.createEdgeFunction(UserEdgeFacts);
if (isZeroValue(CurrNode)) {
return IIAAKillOrReplaceEFCache.createEdgeFunction(
std::move(UserEdgeFacts));
}
return IIAAAddLabelsEFCache.createEdgeFunction(std::move(UserEdgeFacts));
}

// Otherwise stick to identity.
Expand Down Expand Up @@ -835,7 +839,7 @@ class IDEInstInteractionAnalysisT
}
}
if (isZeroValue(SrcNode) && SRetParams.count(DestNode)) {
return IIAAAddLabelsEFCache.createEdgeFunction();
return IIAAKillOrReplaceEFCache.createEdgeFunction();
}
// Everything else can be passed as identity.
return EdgeIdentity<l_t>{};
Expand Down Expand Up @@ -863,14 +867,8 @@ class IDEInstInteractionAnalysisT
if (const auto *CD =
llvm::dyn_cast<llvm::ConstantData>(Ret->getReturnValue())) {
// Check if the user has registered a fact generator function
l_t UserEdgeFacts = BitVectorSet<e_t>();
std::set<e_t> EdgeFacts;
if (EdgeFactGen) {
EdgeFacts = EdgeFactGen(ExitInst);
// fill BitVectorSet
UserEdgeFacts = BitVectorSet<e_t>(EdgeFacts.begin(), EdgeFacts.end());
}
return IIAAAddLabelsEFCache.createEdgeFunction(
l_t UserEdgeFacts = bvSetFrom(invoke_or_default(EdgeFactGen, ExitInst));
return IIAAKillOrReplaceEFCache.createEdgeFunction(
std::move(UserEdgeFacts));
}
}
Expand All @@ -883,34 +881,29 @@ class IDEInstInteractionAnalysisT
d_t RetSiteNode,
llvm::ArrayRef<f_t> Callees) override {
// Check if the user has registered a fact generator function
l_t UserEdgeFacts = BitVectorSet<e_t>();
std::set<e_t> EdgeFacts;
if (EdgeFactGen) {
EdgeFacts = EdgeFactGen(CallSite);
// fill BitVectorSet
UserEdgeFacts = BitVectorSet<e_t>(EdgeFacts.begin(), EdgeFacts.end());
}
l_t UserEdgeFacts = bvSetFrom(invoke_or_default(EdgeFactGen, CallSite));

// Model call to heap allocating functions (new, new[], malloc, etc.) --
// only model direct calls, though.
if (Callees.size() == 1) {
for (const auto *Callee : Callees) {
if (this->ICF->isHeapAllocatingFunction(Callee)) {
// Let H be a heap allocating function.
//
// 0 --> x
//
// Edge function:
//
// 0
// \
const auto *Callee = Callees.front();

if (this->ICF->isHeapAllocatingFunction(Callee)) {
// Let H be a heap allocating function.
//
// 0 --> x
//
// Edge function:
//
// 0
// \
// %i = call H \ \x.x \cup { commit of('%i = call H') }
// v
// i
//
if (isZeroValue(CallNode) && RetSiteNode == CallSite) {
return IIAAAddLabelsEFCache.createEdgeFunction(
std::move(UserEdgeFacts));
}
// v
// i
//
if (isZeroValue(CallNode) && RetSiteNode == CallSite) {
return IIAAKillOrReplaceEFCache.createEdgeFunction(
std::move(UserEdgeFacts));
}
}
}
Expand Down Expand Up @@ -944,10 +937,6 @@ class IDEInstInteractionAnalysisT
return nullptr;
}

inline l_t topElement() override { return Top{}; }

inline l_t bottomElement() override { return Bottom{}; }

inline l_t join(l_t Lhs, l_t Rhs) override { return joinImpl(Lhs, Rhs); }

// Provide some handy helper edge functions to improve reuse.
Expand All @@ -956,7 +945,7 @@ class IDEInstInteractionAnalysisT
// others).
struct IIAAKillOrReplaceEF {
using l_t = typename AnalysisDomainTy::l_t;
l_t Replacement{};
l_t Replacement = BitVectorSet<e_t>();

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

Expand All @@ -972,27 +961,13 @@ class IDEInstInteractionAnalysisT
"IIAAKillOrReplaceEF is too large for SOO");

if (auto *AD = llvm::dyn_cast<IIAAAddLabelsEF>(SecondFunction)) {
auto ADCache =
SecondFunction.template getCacheOrNull<IIAAAddLabelsEF>();
assert(ADCache != nullptr);
if (This->isKillAll()) {
return ADCache->createEdgeFunction(*AD);
}
auto Union =
IDEInstInteractionAnalysisT::joinImpl(This->Replacement, AD->Data);
return ADCache->createEdgeFunction(std::move(Union));
return Cache->createEdgeFunction(std::move(Union));
}

if (auto *KR = llvm::dyn_cast<IIAAKillOrReplaceEF>(SecondFunction)) {
if (This->isKillAll()) {
return Cache->createEdgeFunction(*KR);
}
if (KR->isKillAll()) {
return SecondFunction;
}
auto Union = IDEInstInteractionAnalysisT::joinImpl(This->Replacement,
KR->Replacement);
return Cache->createEdgeFunction(std::move(Union));
return SecondFunction;
}
llvm::report_fatal_error(
"found unexpected edge function in 'IIAAKillOrReplaceEF'");
Expand Down Expand Up @@ -1033,6 +1008,8 @@ class IDEInstInteractionAnalysisT
return Replacement == Other.Replacement;
}

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

friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const IIAAKillOrReplaceEF &EF) {
OS << "EF: (IIAAKillOrReplaceEF)<->";
Expand Down Expand Up @@ -1061,7 +1038,7 @@ class IDEInstInteractionAnalysisT
// add all labels provided by Data.
struct IIAAAddLabelsEF {
using l_t = typename AnalysisDomainTy::l_t;
l_t Data{};
l_t Data = BitVectorSet<e_t>();

l_t computeTarget(ByConstRef<l_t> Src) const {
return IDEInstInteractionAnalysisT::joinImpl(Src, Data);
Expand All @@ -1083,7 +1060,7 @@ class IDEInstInteractionAnalysisT
return Cache->createEdgeFunction(std::move(Union));
}
if (auto *KR = llvm::dyn_cast<IIAAKillOrReplaceEF>(SecondFunction)) {
return Cache->createEdgeFunction(KR->Replacement);
return SecondFunction;
}
llvm::report_fatal_error(
"found unexpected edge function in 'IIAAAddLabelsEF'");
Expand Down Expand Up @@ -1214,9 +1191,8 @@ class IDEInstInteractionAnalysisT
}

protected:
static inline bool isZeroValueImpl(d_t d) {
return LLVMZeroValue::isLLVMZeroValue(d);
}
// NOLINTNEXTLINE(readability-identifier-naming)
static constexpr auto isZeroValueImpl = LLVMZeroValue::isLLVMZeroValue;

static void printEdgeFactImpl(llvm::raw_ostream &OS,
ByConstRef<l_t> EdgeFact) {
Expand Down Expand Up @@ -1244,10 +1220,10 @@ class IDEInstInteractionAnalysisT
}

static inline l_t joinImpl(ByConstRef<l_t> Lhs, ByConstRef<l_t> Rhs) {
if (Lhs.isTop() || Lhs.isBottom()) {
if (Lhs.isTop() || Rhs.isBottom()) {
return Rhs;
}
if (Rhs.isTop() || Rhs.isBottom()) {
if (Rhs.isTop() || Lhs.isBottom()) {
return Lhs;
}
const auto &LhsSet = std::get<BitVectorSet<e_t>>(Lhs);
Expand All @@ -1270,7 +1246,7 @@ class IDEInstInteractionAnalysisT
// at some point. Therefore, we only care for the variables and their
// associated values and ignore at which point a variable may holds as a
// data-flow fact.
const auto Variable = Result.getColumnKey();
const auto &Variable = Result.getColumnKey();
const auto &Value = Result.getValue();
// skip result entry if variable is not in the set of all variables
if (Variables.find(Variable) == Variables.end()) {
Expand Down