Skip to content

Commit bb86c25

Browse files
authored
Split LLVMBasedICFG (#726)
* Out-source globals model * Mode call-graph construction * small refactor * Cleanup resolver headers * buildCallGraph speedup for non-OTF resolvers * Move isVirtualCall into Resolver + some refactoring * Move EntryFunctionUtils into phasar_llvm_controlflow to avoid circular library dependencies between phasar_llvm_db and phasar_llvm_utils * Add more constness
1 parent f17594d commit bb86c25

22 files changed

Lines changed: 692 additions & 429 deletions

include/phasar/PhasarLLVM/ControlFlow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_H
1111
#define PHASAR_PHASARLLVM_CONTROLFLOW_H
1212

13+
#include "phasar/PhasarLLVM/ControlFlow/EntryFunctionUtils.h"
1314
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardCFG.h"
1415
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h"
1516
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/******************************************************************************
2+
* Copyright (c) 2024 Fabian Schiebel.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Fabian Schiebel and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_PHASARLLVM_UTILS_ENTRYFUNCTIONUTILS_H
11+
#define PHASAR_PHASARLLVM_UTILS_ENTRYFUNCTIONUTILS_H
12+
13+
#include "llvm/ADT/ArrayRef.h"
14+
#include "llvm/IR/Function.h"
15+
16+
#include <string>
17+
#include <vector>
18+
19+
namespace psr {
20+
class LLVMProjectIRDB;
21+
22+
[[nodiscard]] std::vector<const llvm::Function *>
23+
getEntryFunctions(const LLVMProjectIRDB &IRDB,
24+
llvm::ArrayRef<std::string> EntryPoints);
25+
26+
[[nodiscard]] std::vector<llvm::Function *>
27+
getEntryFunctionsMut(LLVMProjectIRDB &IRDB,
28+
llvm::ArrayRef<std::string> EntryPoints);
29+
} // namespace psr
30+
31+
#endif // PHASAR_PHASARLLVM_UTILS_ENTRYFUNCTIONUTILS_H
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/******************************************************************************
2+
* Copyright (c) 2024 Fabian Schiebel.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Fabian Schiebel and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_GLOBALCTORSDTORSMODEL_H
11+
#define PHASAR_PHASARLLVM_CONTROLFLOW_GLOBALCTORSDTORSMODEL_H
12+
13+
#include "llvm/ADT/ArrayRef.h"
14+
#include "llvm/IR/Function.h"
15+
16+
namespace psr {
17+
class LLVMProjectIRDB;
18+
19+
class GlobalCtorsDtorsModel {
20+
public:
21+
static constexpr llvm::StringLiteral ModelName =
22+
"__psrCRuntimeGlobalCtorsModel";
23+
24+
static constexpr llvm::StringLiteral DtorModelName =
25+
"__psrCRuntimeGlobalDtorsModel";
26+
27+
static constexpr llvm::StringLiteral DtorsCallerName =
28+
"__psrGlobalDtorsCaller";
29+
30+
static constexpr llvm::StringLiteral UserEntrySelectorName =
31+
"__psrCRuntimeUserEntrySelector";
32+
33+
static llvm::Function *
34+
buildModel(LLVMProjectIRDB &IRDB,
35+
llvm::ArrayRef<llvm::Function *> UserEntryPoints);
36+
static llvm::Function *
37+
buildModel(LLVMProjectIRDB &IRDB,
38+
llvm::ArrayRef<std::string> UserEntryPoints);
39+
40+
/// Returns true, if a function was generated by phasar.
41+
[[nodiscard]] static bool isPhasarGenerated(const llvm::Function &F) noexcept;
42+
};
43+
} // namespace psr
44+
45+
#endif // PHASAR_PHASARLLVM_CONTROLFLOW_GLOBALCTORSDTORSMODEL_H
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/******************************************************************************
2+
* Copyright (c) 2024 Fabian Schiebel.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Fabian Schiebel and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPH_H
11+
#define PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPH_H
12+
13+
#include "phasar/ControlFlow/CallGraph.h"
14+
15+
namespace llvm {
16+
class Instruction;
17+
class Function;
18+
} // namespace llvm
19+
20+
namespace psr {
21+
using LLVMBasedCallGraph =
22+
CallGraph<const llvm::Instruction *, const llvm::Function *>;
23+
} // namespace psr
24+
25+
#endif // PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPH_H
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/******************************************************************************
2+
* Copyright (c) 2024 Fabian Schiebel.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Fabian Schiebel and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPHBUILDER_H
11+
#define PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPHBUILDER_H
12+
13+
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCallGraph.h"
14+
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
15+
#include "phasar/Utils/Soundness.h"
16+
17+
namespace psr {
18+
class LLVMProjectIRDB;
19+
enum class CallGraphAnalysisType;
20+
class LLVMTypeHierarchy;
21+
class LLVMVFTableProvider;
22+
class Resolver;
23+
24+
[[nodiscard]] LLVMBasedCallGraph
25+
buildLLVMBasedCallGraph(LLVMProjectIRDB &IRDB, CallGraphAnalysisType CGType,
26+
llvm::ArrayRef<const llvm::Function *> EntryPoints,
27+
LLVMTypeHierarchy &TH, LLVMVFTableProvider &VTP,
28+
LLVMAliasInfoRef PT = nullptr,
29+
Soundness S = Soundness::Soundy);
30+
31+
[[nodiscard]] LLVMBasedCallGraph
32+
buildLLVMBasedCallGraph(const LLVMProjectIRDB &IRDB, Resolver &CGResolver,
33+
llvm::ArrayRef<const llvm::Function *> EntryPoints,
34+
Soundness S = Soundness::Soundy);
35+
36+
[[nodiscard]] LLVMBasedCallGraph
37+
buildLLVMBasedCallGraph(LLVMProjectIRDB &IRDB, CallGraphAnalysisType CGType,
38+
llvm::ArrayRef<std::string> EntryPoints,
39+
LLVMTypeHierarchy &TH, LLVMVFTableProvider &VTP,
40+
LLVMAliasInfoRef PT = nullptr,
41+
Soundness S = Soundness::Soundy);
42+
43+
[[nodiscard]] LLVMBasedCallGraph
44+
buildLLVMBasedCallGraph(const LLVMProjectIRDB &IRDB, Resolver &CGResolver,
45+
llvm::ArrayRef<std::string> EntryPoints,
46+
Soundness S = Soundness::Soundy);
47+
} // namespace psr
48+
49+
#endif // PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPHBUILDER_H

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@
2020
#include "phasar/ControlFlow/CallGraph.h"
2121
#include "phasar/ControlFlow/CallGraphAnalysisType.h"
2222
#include "phasar/ControlFlow/ICFGBase.h"
23+
#include "phasar/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.h"
2324
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
25+
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCallGraph.h"
2426
#include "phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h"
2527
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
2628
#include "phasar/PhasarLLVM/Utils/LLVMBasedContainerConfig.h"
29+
#include "phasar/Utils/MaybeUniquePtr.h"
2730
#include "phasar/Utils/Soundness.h"
2831

2932
#include "llvm/ADT/ArrayRef.h"
@@ -46,20 +49,10 @@ template <> struct CFGTraits<LLVMBasedICFG> : CFGTraits<LLVMBasedCFG> {};
4649
class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
4750
friend ICFGBase;
4851

49-
struct Builder;
50-
5152
public:
53+
// For backward compatibility
5254
static constexpr llvm::StringLiteral GlobalCRuntimeModelName =
53-
"__psrCRuntimeGlobalCtorsModel";
54-
55-
static constexpr llvm::StringLiteral GlobalCRuntimeDtorModelName =
56-
"__psrCRuntimeGlobalDtorsModel";
57-
58-
static constexpr llvm::StringLiteral GlobalCRuntimeDtorsCallerName =
59-
"__psrGlobalDtorsCaller";
60-
61-
static constexpr llvm::StringLiteral GlobalCRuntimeUserEntrySelectorName =
62-
"__psrCRuntimeUserEntrySelector";
55+
GlobalCtorsDtorsModel::ModelName;
6356

6457
/// Constructs the ICFG based on the given IRDB and the entry-points using a
6558
/// fixpoint iteration. This may take a long time.
@@ -95,9 +88,9 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
9588
bool IncludeGlobals = true);
9689

9790
/// Creates an ICFG with an already given call-graph
98-
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB);
91+
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, const LLVMProjectIRDB *IRDB);
9992

100-
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB,
93+
explicit LLVMBasedICFG(const LLVMProjectIRDB *IRDB,
10194
const CallGraphData &SerializedCG);
10295

10396
// Deleter of LLVMTypeHierarchy may be unknown here...
@@ -131,10 +124,13 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
131124
}
132125

133126
/// Gets the underlying IRDB
134-
[[nodiscard]] LLVMProjectIRDB *getIRDB() const noexcept { return IRDB; }
127+
[[nodiscard]] const LLVMProjectIRDB *getIRDB() const noexcept { return IRDB; }
135128

136129
/// Returns true, if a function was generated by phasar.
137-
[[nodiscard]] static bool isPhasarGenerated(const llvm::Function &) noexcept;
130+
[[nodiscard]] static bool
131+
isPhasarGenerated(const llvm::Function &F) noexcept {
132+
return GlobalCtorsDtorsModel::isPhasarGenerated(F);
133+
}
138134

139135
using CFGBase::print;
140136
using ICFGBase::print;
@@ -157,22 +153,21 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
157153
void printImpl(llvm::raw_ostream &OS) const;
158154
void printAsJsonImpl(llvm::raw_ostream &OS) const;
159155
[[nodiscard, deprecated]] nlohmann::json getAsJsonImpl() const;
160-
[[nodiscard]] const CallGraph<n_t, f_t> &getCallGraphImpl() const noexcept {
156+
[[nodiscard]] const LLVMBasedCallGraph &getCallGraphImpl() const noexcept {
161157
return CG;
162158
}
163159

164160
[[nodiscard]] llvm::Function *buildCRuntimeGlobalCtorsDtorsModel(
165161
llvm::Module &M, llvm::ArrayRef<llvm::Function *> UserEntryPoints);
166162

167163
void initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
168-
llvm::ArrayRef<std::string> EntryPoints,
169-
const LLVMVFTableProvider &VTP, Soundness S,
164+
llvm::ArrayRef<std::string> EntryPoints, Soundness S,
170165
bool IncludeGlobals);
171166

172167
// ---
173168

174-
CallGraph<const llvm::Instruction *, const llvm::Function *> CG;
175-
LLVMProjectIRDB *IRDB = nullptr;
169+
LLVMBasedCallGraph CG;
170+
const LLVMProjectIRDB *IRDB = nullptr;
176171
LLVMVFTableProvider VTP;
177172
};
178173

include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
namespace llvm {
2424
class CallBase;
25-
class Function;
2625
} // namespace llvm
2726

2827
namespace psr {
@@ -38,6 +37,11 @@ class CHAResolver : public Resolver {
3837

3938
[[nodiscard]] std::string str() const override;
4039

40+
[[nodiscard]] bool
41+
mutatesHelperAnalysisInformation() const noexcept override {
42+
return false;
43+
}
44+
4145
protected:
4246
MaybeUniquePtr<const LLVMTypeHierarchy, true> TH;
4347
};

include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,22 @@ class DTAResolver : public CHAResolver {
3737
public:
3838
using TypeGraph_t = CachedTypeGraph;
3939

40+
DTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
41+
const LLVMTypeHierarchy *TH);
42+
43+
~DTAResolver() override = default;
44+
45+
FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override;
46+
47+
void otherInst(const llvm::Instruction *Inst) override;
48+
49+
[[nodiscard]] std::string str() const override;
50+
51+
[[nodiscard]] bool
52+
mutatesHelperAnalysisInformation() const noexcept override {
53+
return false;
54+
}
55+
4056
protected:
4157
TypeGraph_t TypeGraph;
4258

@@ -53,18 +69,6 @@ class DTAResolver : public CHAResolver {
5369
* of vtable)
5470
*/
5571
bool heuristicAntiConstructorVtablePos(const llvm::BitCastInst *BitCast);
56-
57-
public:
58-
DTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
59-
const LLVMTypeHierarchy *TH);
60-
61-
~DTAResolver() override = default;
62-
63-
FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override;
64-
65-
void otherInst(const llvm::Instruction *Inst) override;
66-
67-
[[nodiscard]] std::string str() const override;
6872
};
6973
} // namespace psr
7074

include/phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,27 @@
1313
#include "phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h"
1414

1515
namespace llvm {
16-
class Instruction;
1716
class CallBase;
18-
class Function;
19-
class StructType;
2017
} // namespace llvm
2118

2219
namespace psr {
2320

2421
class NOResolver final : public Resolver {
25-
protected:
26-
const llvm::Function *
27-
getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx,
28-
const llvm::CallBase *CallSite);
29-
3022
public:
31-
NOResolver(const LLVMProjectIRDB *IRDB);
23+
NOResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP);
3224

3325
~NOResolver() override = default;
3426

35-
void preCall(const llvm::Instruction *Inst) override;
36-
37-
void handlePossibleTargets(const llvm::CallBase *CallSite,
38-
FunctionSetTy &PossibleTargets) override;
39-
40-
void postCall(const llvm::Instruction *Inst) override;
41-
4227
FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override;
4328

4429
FunctionSetTy resolveFunctionPointer(const llvm::CallBase *CallSite) override;
4530

46-
void otherInst(const llvm::Instruction *Inst) override;
47-
4831
[[nodiscard]] std::string str() const override;
32+
33+
[[nodiscard]] bool
34+
mutatesHelperAnalysisInformation() const noexcept override {
35+
return false;
36+
}
4937
};
5038
} // namespace psr
5139

0 commit comments

Comments
 (0)