Skip to content

Commit d62d123

Browse files
committed
Resolve conflicts when merging to development
1 parent 3373eb2 commit d62d123

8 files changed

Lines changed: 174 additions & 47 deletions

File tree

Config.cmake.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ foreach(component ${phasar_FIND_COMPONENTS})
99
endforeach()
1010

1111
function(phasar_config executable)
12-
find_package(LLVM 10 REQUIRED CONFIG)
12+
find_package(LLVM 12 REQUIRED CONFIG)
1313
include_directories(${LLVM_INCLUDE_DIRS})
1414
link_directories(${LLVM_LIB_PATH} ${LLVM_LIBRARY_DIRS})
1515
find_library(LLVM_LIBRARY NAMES LLVM HINTS ${LLVM_LIBRARY_DIRS})

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <unordered_set>
1919
#include <vector>
2020

21+
#include "llvm/IR/LLVMContext.h"
22+
2123
#include "phasar/PhasarLLVM/ControlFlow/ICFG.h"
2224
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardCFG.h"
2325
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
@@ -42,17 +44,28 @@ class LLVMBasedBackwardsICFG
4244
: public ICFG<const llvm::Instruction *, const llvm::Function *>,
4345
public virtual LLVMBasedBackwardCFG {
4446
private:
45-
LLVMBasedICFG ForwardICFG;
47+
LLVMBasedICFG &ForwardICFG;
48+
static inline const std::unique_ptr<llvm::LLVMContext> LLVMBackwardRetCTX =
49+
std::make_unique<llvm::LLVMContext>();
50+
51+
class LLVMBackwardRet {
52+
private:
53+
const llvm::ReturnInst *Instance;
54+
55+
public:
56+
LLVMBackwardRet()
57+
: Instance(llvm::ReturnInst::Create(*LLVMBackwardRetCTX)){};
58+
[[nodiscard]] const llvm::ReturnInst *getInstance() const {
59+
return Instance;
60+
}
61+
};
62+
std::unordered_map<const llvm::Function *, LLVMBackwardRet> BackwardRets;
63+
llvm::DenseMap<const llvm::Instruction *, const llvm::Function *>
64+
BackwardRetToFunction;
4665

4766
public:
4867
LLVMBasedBackwardsICFG(LLVMBasedICFG &ICFG);
4968

50-
LLVMBasedBackwardsICFG(ProjectIRDB &IRDB, CallGraphAnalysisType CGType,
51-
const std::set<std::string> &EntryPoints = {},
52-
LLVMTypeHierarchy *TH = nullptr,
53-
LLVMPointsToInfo *PT = nullptr,
54-
Soundness S = Soundness::Soundy);
55-
5669
~LLVMBasedBackwardsICFG() override = default;
5770

5871
std::set<const llvm::Function *> getAllFunctions() const override;
@@ -77,6 +90,20 @@ class LLVMBasedBackwardsICFG
7790

7891
std::set<const llvm::Instruction *> allNonCallStartNodes() const override;
7992

93+
[[nodiscard]] const llvm::Function *
94+
getFunctionOf(const llvm::Instruction *Stmt) const override;
95+
96+
[[nodiscard]] std::vector<const llvm::Instruction *>
97+
getPredsOf(const llvm::Instruction *Stmt) const override;
98+
99+
[[nodiscard]] std::vector<const llvm::Instruction *>
100+
getSuccsOf(const llvm::Instruction *Stmt) const override;
101+
102+
[[nodiscard]] std::set<const llvm::Instruction *>
103+
getExitPointsOf(const llvm::Function *Fun) const override;
104+
105+
[[nodiscard]] bool isExitInst(const llvm::Instruction *Stmt) const override;
106+
80107
void mergeWith(const LLVMBasedBackwardsICFG &other);
81108

82109
using LLVMBasedBackwardCFG::print; // tell the compiler we wish to have both
@@ -95,6 +122,9 @@ class LLVMBasedBackwardsICFG
95122

96123
std::vector<const llvm::Function *> getDependencyOrderedFunctions();
97124

125+
private:
126+
void createBackwardRets();
127+
98128
protected:
99129
void collectGlobalCtors() override;
100130

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ class LLVMBasedICFG
182182
LLVMBasedICFG(ProjectIRDB &IRDB, CallGraphAnalysisType CGType,
183183
const std::set<std::string> &EntryPoints = {},
184184
LLVMTypeHierarchy *TH = nullptr, LLVMPointsToInfo *PT = nullptr,
185-
Soundness S = Soundness::Soundy, bool IncludeGlobals = false);
185+
Soundness S = Soundness::Soundy, bool IncludeGlobals = true);
186186

187187
LLVMBasedICFG(const LLVMBasedICFG &);
188188

include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/LLVMFlowFunctions.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,14 @@ class MapFactsToCallee : public FlowFunction<const llvm::Value *, Container> {
180180
}
181181
return {};
182182
}
183+
container_type Res;
183184
// Pass global variables as is, if desired
185+
// Globals could also be actual arguments, then the formal argument needs to
186+
// be generated below.
184187
// Need llvm::Constant here to cover also ConstantExpr and ConstantAggregate
185188
if (PropagateGlobals && llvm::isa<llvm::Constant>(Source)) {
186-
return {Source};
189+
Res.insert(Source);
187190
}
188-
container_type Res;
189191
// Handle back propagation of return value in backwards analysis.
190192
// We add it to the result here. Later, normal flow in callee can identify
191193
// it
@@ -259,6 +261,7 @@ class MapFactsToCaller : public FlowFunction<const llvm::Value *, Container> {
259261
const llvm::Function *CalleeFun;
260262
const llvm::ReturnInst *ExitInst;
261263
bool PropagateGlobals;
264+
const bool PropagateZeroToCaller;
262265
std::vector<const llvm::Value *> Actuals;
263266
std::vector<const llvm::Value *> Formals;
264267
std::function<bool(const llvm::Value *)> ParamPredicate;
@@ -271,10 +274,12 @@ class MapFactsToCaller : public FlowFunction<const llvm::Value *, Container> {
271274
std::function<bool(const llvm::Value *)> ParamPredicate =
272275
[](const llvm::Value *) { return true; },
273276
std::function<bool(const llvm::Function *)> ReturnPredicate =
274-
[](const llvm::Function *) { return true; })
277+
[](const llvm::Function *) { return true; },
278+
bool PropagateZeroToCaller = true)
275279
: CallSite(CallSite), CalleeFun(CalleeFun),
276280
ExitInst(llvm::dyn_cast<llvm::ReturnInst>(ExitInst)),
277281
PropagateGlobals(PropagateGlobals),
282+
PropagateZeroToCaller(PropagateZeroToCaller),
278283
ParamPredicate(std::move(ParamPredicate)),
279284
ReturnPredicate(std::move(ReturnPredicate)) {
280285
assert(ExitInst && "Should not be null");
@@ -294,12 +299,16 @@ class MapFactsToCaller : public FlowFunction<const llvm::Value *, Container> {
294299
container_type computeTargets(const llvm::Value *Source) override {
295300
assert(!CalleeFun->isDeclaration() &&
296301
"Cannot perform mapping to caller for function declaration");
297-
// Pass ZeroValue as is
302+
// Pass ZeroValue as is, if desired
298303
if (LLVMZeroValue::getInstance()->isLLVMZeroValue(Source)) {
299-
return {Source};
304+
if (PropagateZeroToCaller) {
305+
return {Source};
306+
}
307+
return {};
300308
}
301309
// Pass global variables as is, if desired
302-
if (PropagateGlobals && llvm::isa<llvm::GlobalVariable>(Source)) {
310+
// Need llvm::Constant here to cover also ConstantExpr and ConstantAggregate
311+
if (PropagateGlobals && llvm::isa<llvm::Constant>(Source)) {
303312
return {Source};
304313
}
305314
// Do the parameter mapping
@@ -340,7 +349,8 @@ class MapFactsToCaller : public FlowFunction<const llvm::Value *, Container> {
340349
}
341350
}
342351
// Collect return value facts
343-
if (Source == ExitInst->getReturnValue() && ReturnPredicate(CalleeFun)) {
352+
if (ExitInst != nullptr && Source == ExitInst->getReturnValue() &&
353+
ReturnPredicate(CalleeFun)) {
344354
Res.insert(CallSite);
345355
}
346356
return Res;

lib/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.cpp

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,13 @@ LLVMBasedBackwardsICFG::LLVMBasedBackwardsICFG(LLVMBasedICFG &ICFG)
3838
: ForwardICFG(ICFG) {
3939
auto CgCopy = ForwardICFG.CallGraph;
4040
boost::copy_graph(boost::make_reverse_graph(CgCopy), ForwardICFG.CallGraph);
41+
createBackwardRets();
4142
}
4243

43-
LLVMBasedBackwardsICFG::LLVMBasedBackwardsICFG(
44-
ProjectIRDB &IRDB, CallGraphAnalysisType CGType,
45-
const std::set<std::string> &EntryPoints, LLVMTypeHierarchy *TH,
46-
LLVMPointsToInfo *PT, Soundness S)
47-
: ForwardICFG(IRDB, CGType, EntryPoints, TH, PT, S) {
48-
auto CgCopy = ForwardICFG.CallGraph;
49-
boost::copy_graph(boost::make_reverse_graph(CgCopy), ForwardICFG.CallGraph);
44+
void LLVMBasedBackwardsICFG::createBackwardRets() {
45+
for (const auto *Function : getAllFunctions()) {
46+
BackwardRetToFunction[BackwardRets[Function].getInstance()] = Function;
47+
}
5048
}
5149

5250
bool LLVMBasedBackwardsICFG::isIndirectFunctionCall(
@@ -88,15 +86,11 @@ std::set<const llvm::Instruction *>
8886
LLVMBasedBackwardsICFG::getReturnSitesOfCallAt(
8987
const llvm::Instruction *N) const {
9088
std::set<const llvm::Instruction *> ReturnSites;
91-
if (const auto *Call = llvm::dyn_cast<llvm::CallInst>(N)) {
89+
if (const auto *Call = llvm::dyn_cast<llvm::CallBase>(N)) {
9290
for (const auto *Succ : this->getSuccsOf(Call)) {
9391
ReturnSites.insert(Succ);
9492
}
9593
}
96-
if (const auto *Invoke = llvm::dyn_cast<llvm::InvokeInst>(N)) {
97-
ReturnSites.insert(&Invoke->getNormalDest()->back());
98-
ReturnSites.insert(&Invoke->getUnwindDest()->back());
99-
}
10094
return ReturnSites;
10195
}
10296

@@ -105,6 +99,51 @@ LLVMBasedBackwardsICFG::allNonCallStartNodes() const {
10599
return ForwardICFG.allNonCallStartNodes();
106100
}
107101

102+
const llvm::Function *
103+
LLVMBasedBackwardsICFG::getFunctionOf(const llvm::Instruction *Stmt) const {
104+
auto BackwardRetIt = BackwardRetToFunction.find(Stmt);
105+
if (BackwardRetIt != BackwardRetToFunction.end()) {
106+
return BackwardRetIt->second;
107+
}
108+
return Stmt->getFunction();
109+
}
110+
111+
std::vector<const llvm::Instruction *>
112+
LLVMBasedBackwardsICFG::getPredsOf(const llvm::Instruction *Stmt) const {
113+
auto BackwardRetIt = BackwardRetToFunction.find(Stmt);
114+
if (BackwardRetIt == BackwardRetToFunction.end()) {
115+
return LLVMBasedBackwardCFG::getPredsOf(Stmt);
116+
}
117+
auto ExitPoints =
118+
LLVMBasedBackwardCFG::getExitPointsOf(BackwardRetIt->second);
119+
return {ExitPoints.begin(), ExitPoints.end()};
120+
}
121+
122+
std::vector<const llvm::Instruction *>
123+
LLVMBasedBackwardsICFG::getSuccsOf(const llvm::Instruction *Stmt) const {
124+
if (isExitInst(Stmt)) {
125+
return {};
126+
}
127+
std::vector<const llvm::Instruction *> Succs =
128+
LLVMBasedBackwardCFG::getSuccsOf(Stmt);
129+
if (Succs.size() == 0) {
130+
assert(Stmt->getParent()->getParent() && "Could not find parent of stmt's parent ");
131+
Succs.push_back(
132+
BackwardRets.at(Stmt->getParent()->getParent()).getInstance());
133+
}
134+
return Succs;
135+
}
136+
137+
bool LLVMBasedBackwardsICFG::isExitInst(const llvm::Instruction *Stmt) const {
138+
return (Stmt->getParent() == nullptr &&
139+
BackwardRetToFunction.count(Stmt) > 0);
140+
}
141+
142+
std::set<const llvm::Instruction *>
143+
LLVMBasedBackwardsICFG::getExitPointsOf(const llvm::Function *Fun) const {
144+
return {BackwardRets.at(Fun).getInstance()};
145+
}
146+
108147
void LLVMBasedBackwardsICFG::mergeWith(const LLVMBasedBackwardsICFG &Other) {
109148
ForwardICFG.mergeWith(Other.ForwardICFG);
110149
}

lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,6 @@ LLVMBasedICFG::LLVMBasedICFG(ProjectIRDB &IRDB, CallGraphAnalysisType CGType,
151151
"CallGraphAnalysisType::OTF was not specified.");
152152
}
153153

154-
// instantiate the respective resolver type
155-
Res = makeResolver(IRDB, CGType, *this->TH, *this->PT);
156-
157-
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), INFO)
158-
<< "Starting CallGraphAnalysisType: " << CGType);
159-
VisitedFunctions.reserve(IRDB.getAllFunctions().size());
160-
161154
for (const auto &EntryPoint : EntryPoints) {
162155
auto *F = IRDB.getFunctionDefinition(EntryPoint);
163156
if (F == nullptr) {
@@ -179,9 +172,15 @@ LLVMBasedICFG::LLVMBasedICFG(ProjectIRDB &IRDB, CallGraphAnalysisType CGType,
179172
UserEntryPoints.end());
180173
}
181174

182-
while (true) {
183-
bool FixpointReached = true;
175+
// instantiate the respective resolver type
176+
Res = makeResolver(IRDB, CGType, *this->TH, *this->PT);
177+
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), INFO)
178+
<< "Starting CallGraphAnalysisType: " << CGType);
179+
VisitedFunctions.reserve(IRDB.getAllFunctions().size());
184180

181+
bool FixpointReached;
182+
do {
183+
FixpointReached = true;
185184
while (!FunctionWL.empty()) {
186185
const llvm::Function *F = FunctionWL.back();
187186
FunctionWL.pop_back();
@@ -192,10 +191,7 @@ LLVMBasedICFG::LLVMBasedICFG(ProjectIRDB &IRDB, CallGraphAnalysisType CGType,
192191
FixpointReached &= !constructDynamicCall(CS, *Res);
193192
}
194193

195-
if (FixpointReached) {
196-
break;
197-
}
198-
}
194+
} while (!FixpointReached);
199195

200196
for (const auto &[IndirectCall, Targets] : IndirectCalls) {
201197
if (Targets == 0) {
@@ -674,8 +670,22 @@ set<const llvm::Instruction *>
674670
LLVMBasedICFG::getReturnSitesOfCallAt(const llvm::Instruction *N) const {
675671
set<const llvm::Instruction *> ReturnSites;
676672
if (const auto *Invoke = llvm::dyn_cast<llvm::InvokeInst>(N)) {
677-
ReturnSites.insert(&Invoke->getNormalDest()->front());
678-
ReturnSites.insert(&Invoke->getUnwindDest()->front());
673+
const llvm::Instruction *NormalSucc = &Invoke->getNormalDest()->front();
674+
auto *UnwindSucc = &Invoke->getUnwindDest()->front();
675+
if (!IgnoreDbgInstructions &&
676+
llvm::isa<llvm::DbgInfoIntrinsic>(NormalSucc)) {
677+
NormalSucc = NormalSucc->getNextNonDebugInstruction();
678+
}
679+
if (!IgnoreDbgInstructions &&
680+
llvm::isa<llvm::DbgInfoIntrinsic>(UnwindSucc)) {
681+
UnwindSucc = UnwindSucc->getNextNonDebugInstruction();
682+
}
683+
if (NormalSucc != nullptr) {
684+
ReturnSites.insert(NormalSucc);
685+
}
686+
if (UnwindSucc != nullptr) {
687+
ReturnSites.insert(UnwindSucc);
688+
}
679689
} else {
680690
auto Succs = getSuccsOf(N);
681691
ReturnSites.insert(Succs.begin(), Succs.end());

unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGTest.cpp

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,33 @@ TEST(LLVMBasedICFGTest, StaticCallSite_1) {
4141
}
4242
}
4343

44-
TEST(LLVMBasedICFGTest, StaticCallSite_2) {
44+
TEST(LLVMBasedICFGTest, StaticCallSite_2a) {
45+
ProjectIRDB IRDB(
46+
{unittest::PathToLLTestFiles + "call_graphs/static_callsite_2_c.ll"},
47+
IRDBOptions::WPA);
48+
LLVMTypeHierarchy TH(IRDB);
49+
LLVMPointsToSet PT(IRDB);
50+
LLVMBasedICFG ICFG(IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT, Soundness::Soundy, false);
51+
const llvm::Function *F = IRDB.getFunctionDefinition("main");
52+
const llvm::Function *FOO = IRDB.getFunctionDefinition("foo");
53+
const llvm::Function *BAR = IRDB.getFunctionDefinition("bar");
54+
ASSERT_TRUE(F);
55+
ASSERT_TRUE(FOO);
56+
ASSERT_TRUE(BAR);
57+
58+
set<const llvm::Function *> FunctionSet;
59+
FunctionSet.insert(F);
60+
FunctionSet.insert(FOO);
61+
FunctionSet.insert(BAR);
62+
63+
set<const llvm::Function *> FunSet = ICFG.getAllFunctions();
64+
ASSERT_EQ(FunctionSet, FunSet);
65+
66+
set<const llvm::Instruction *> CallsFromWithin = ICFG.getCallsFromWithin(F);
67+
ASSERT_EQ(CallsFromWithin.size(), 2U);
68+
}
69+
70+
TEST(LLVMBasedICFGTest, StaticCallSite_2b) {
4571
ProjectIRDB IRDB(
4672
{unittest::PathToLLTestFiles + "call_graphs/static_callsite_2_c.ll"},
4773
IRDBOptions::WPA);
@@ -51,14 +77,20 @@ TEST(LLVMBasedICFGTest, StaticCallSite_2) {
5177
const llvm::Function *F = IRDB.getFunctionDefinition("main");
5278
const llvm::Function *FOO = IRDB.getFunctionDefinition("foo");
5379
const llvm::Function *BAR = IRDB.getFunctionDefinition("bar");
80+
const llvm::Function *CTOR = IRDB.getFunctionDefinition("__psrCRuntimeGlobalCtorsModel");
81+
const llvm::Function *DTOR = IRDB.getFunctionDefinition("__psrCRuntimeGlobalDtorsModel");
5482
ASSERT_TRUE(F);
5583
ASSERT_TRUE(FOO);
5684
ASSERT_TRUE(BAR);
85+
ASSERT_TRUE(CTOR);
86+
ASSERT_TRUE(DTOR);
5787

5888
set<const llvm::Function *> FunctionSet;
5989
FunctionSet.insert(F);
6090
FunctionSet.insert(FOO);
6191
FunctionSet.insert(BAR);
92+
FunctionSet.insert(CTOR);
93+
FunctionSet.insert(DTOR);
6294

6395
set<const llvm::Function *> FunSet = ICFG.getAllFunctions();
6496
ASSERT_EQ(FunctionSet, FunSet);
@@ -232,7 +264,7 @@ TEST(LLVMBasedICFGTest, StaticCallSite_7) {
232264
getLastInstructionOf(IRDB.getFunctionDefinition("_ZN3Foo1fEv"));
233265
set<const llvm::Function *> AllMethods = ICFG.getAllFunctions();
234266
ASSERT_EQ(LastInst, I);
235-
ASSERT_EQ(AllMethods.size(), 3U);
267+
ASSERT_EQ(AllMethods.size(), 5U);
236268
ASSERT_TRUE(AllMethods.count(Main));
237269
ASSERT_TRUE(AllMethods.count(FooF));
238270
ASSERT_TRUE(AllMethods.count(F));
@@ -257,7 +289,7 @@ TEST(LLVMBasedICFGTest, StaticCallSite_8) {
257289
ASSERT_EQ(Insts.size(), Insts1.size());
258290

259291
set<const llvm::Function *> FunSet = ICFG.getAllFunctions();
260-
ASSERT_EQ(FunSet.size(), 3U);
292+
ASSERT_EQ(FunSet.size(), 5U);
261293

262294
const llvm::Instruction *I = getNthInstruction(F, 1);
263295
ASSERT_TRUE(ICFG.isStartPoint(I));

0 commit comments

Comments
 (0)