Skip to content

Commit 7f0f756

Browse files
fabianbs96mxHuberSanthoshMohan97sritejakvMMory
authored
DI-based LLVM Type Hierarchy (#702)
* small backup safe * backup save, still needs metadata extraction * refactoring + some basic functions implemented * basic structure of constructHierarchy() * DIBasedTypeHierarchy structure * basic impl of constructor and hasVFTable * impl edges of graph, isSubType, getSubType and print * untested version of transitive closure * added transitive closure and changed print * fixed transitive closure + refactoring * bug fixes + tests * debugging Debug info extraction * Fixed type extraction, untested transitive hull * fixed includes + more debug info * bug fixes and non recursive transitive hull * working direct edge detection * BitVector, cleanup, start of vtable impl * vtables and dotgraph * review changes + vtable fix, 50% finished * impl review suggestions * removed old type_hierarchy unittests * impl .set_bits() loop * fixed vtables * fixes and code cleanup * added llvm::interleaveComma * fixed wrong assertion * public LLVMVFTable constructor * small refactor * important bugfixes * unittests for multiple base classes * unittests not finished, backup * more unittests, all pass * reworked unittests * review changes * review changes * myphasartools.cpp revert * current final version * Bump submodules * backup of fixes + unittests * more unittests * new unittest * Pin swift version * basicRecoTH backup * backup of structure * Analysis Printer (#17) * Initial Commit * AnalysisPrinter Second commit * Initial Commit * Integrate Printer with client Analysis and test * Addressing Review comments * Integrate AnalysisPrinter with all analyses and template class modified * vector emplace_back instead of push_back * Testcase for AnalysisPrinter * GroundTruth derived class initial commit * AnalysisPrinter Test complete and Test * fixing myphasartool file * Test pre-commit fix * Adding Test cases and fixing PR failure * 1.template params to N,D,L 2.remove AnalysisType param from AnalysisResults 3.rearranging class variables * 1.template params to N,D,L 2.remove AnalysisType param from AnalysisResults 3.rearranging class variables * Null AnalysisPrinter singleton * Adding AnalysisPrinter to IDETabulation Problem * making free (N,D,L)ToString functions * disable copy and move for analysis-printer * Default NullAnalysisPrinter and explicit print methods * removing SetAnalysisPrinter from client analyses and modified Testcase for AnalysisPrinter * Adding superclass for AnalysisPrinter * Addressing review comments and fixing PR build failure * fix: minors * fix: minor (clang-tidy) * fix: review feedback * misc: minor refactoring --------- Co-authored-by: SanthoshMohan <santhoshmohan0897@gmail.com> Co-authored-by: Sriteja Kummita <sriteja.ku@gmail.com> * new unittests, some fail * unittests fixed, all pass * Add LLVM-RTTI-style type-hierarchy layout * fix: review feedback * Fix logging macro invocation * Split giant DIBasedTypeHierarchy ctor into multiple functions --------- Co-authored-by: mxHuber <huber.maximilian.leo@gmail.com> Co-authored-by: SanthoshMohan <santhoshmohan0897@gmail.com> Co-authored-by: Sriteja Kummita <sriteja.ku@gmail.com> Co-authored-by: Martin Mory <mmo@mail.upb.de>
1 parent a56fc58 commit 7f0f756

14 files changed

Lines changed: 2820 additions & 5 deletions

File tree

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/******************************************************************************
2+
* Copyright (c) 2023 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_TYPEHIERARCHY_DIBASEDTYPEHIERARCHY_H
11+
#define PHASAR_PHASARLLVM_TYPEHIERARCHY_DIBASEDTYPEHIERARCHY_H
12+
13+
#include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h"
14+
#include "phasar/TypeHierarchy/TypeHierarchy.h"
15+
16+
#include "llvm/ADT/BitVector.h"
17+
#include "llvm/ADT/DenseMap.h"
18+
#include "llvm/ADT/StringMap.h"
19+
#include "llvm/ADT/StringRef.h"
20+
#include "llvm/IR/DebugInfo.h"
21+
#include "llvm/IR/DebugInfoMetadata.h"
22+
23+
#include <deque>
24+
25+
namespace psr {
26+
class LLVMProjectIRDB;
27+
28+
class DIBasedTypeHierarchy
29+
: public TypeHierarchy<const llvm::DIType *, const llvm::Function *> {
30+
public:
31+
using ClassType = const llvm::DIType *;
32+
using f_t = const llvm::Function *;
33+
34+
explicit DIBasedTypeHierarchy(const LLVMProjectIRDB &IRDB);
35+
~DIBasedTypeHierarchy() override = default;
36+
37+
[[nodiscard]] bool hasType(ClassType Type) const override {
38+
return TypeToVertex.count(Type);
39+
}
40+
41+
[[nodiscard]] bool isSubType(ClassType Type, ClassType SubType) override {
42+
return llvm::is_contained(subTypesOf(Type), SubType);
43+
}
44+
45+
[[nodiscard]] std::set<ClassType> getSubTypes(ClassType Type) override {
46+
const auto &Range = subTypesOf(Type);
47+
return {Range.begin(), Range.end()};
48+
}
49+
50+
/// A more efficient version of getSubTypes()
51+
[[nodiscard]] llvm::iterator_range<const ClassType *>
52+
subTypesOf(ClassType Ty) const noexcept;
53+
54+
[[nodiscard]] bool isSuperType(ClassType Type, ClassType SuperType) override;
55+
56+
/// Not supported yet
57+
[[nodiscard]] std::set<ClassType> getSuperTypes(ClassType Type) override;
58+
59+
[[nodiscard]] ClassType
60+
getType(std::string TypeName) const noexcept override {
61+
return NameToType.lookup(TypeName);
62+
}
63+
64+
[[nodiscard]] std::set<ClassType> getAllTypes() const override {
65+
return {VertexTypes.begin(), VertexTypes.end()};
66+
}
67+
68+
[[nodiscard]] const auto &getAllVTables() const noexcept { return VTables; }
69+
70+
[[nodiscard]] std::string getTypeName(ClassType Type) const override {
71+
return Type->getName().str();
72+
}
73+
74+
[[nodiscard]] bool hasVFTable(ClassType Type) const override;
75+
76+
[[nodiscard]] const VFTable<f_t> *getVFTable(ClassType Type) const override {
77+
auto It = TypeToVertex.find(Type);
78+
if (It == TypeToVertex.end()) {
79+
return nullptr;
80+
}
81+
return &VTables[It->second];
82+
}
83+
84+
[[nodiscard]] size_t size() const override { return VertexTypes.size(); }
85+
86+
[[nodiscard]] bool empty() const override { return VertexTypes.empty(); }
87+
88+
void print(llvm::raw_ostream &OS = llvm::outs()) const override;
89+
90+
/**
91+
* @brief Prints the class hierarchy to an ostream in dot format.
92+
* @param OS outputstream
93+
*/
94+
void printAsDot(llvm::raw_ostream &OS = llvm::outs()) const;
95+
96+
[[nodiscard]] nlohmann::json getAsJson() const override;
97+
98+
private:
99+
[[nodiscard]] llvm::iterator_range<const ClassType *>
100+
subTypesOf(size_t TypeIdx) const noexcept;
101+
102+
// ---
103+
104+
llvm::StringMap<ClassType> NameToType;
105+
// Map each type to an integer index that is used by VertexTypes and
106+
// DerivedTypesOf.
107+
// Note: all the below arrays should always have the same size (except for
108+
// Hierarchy)!
109+
llvm::DenseMap<ClassType, size_t> TypeToVertex;
110+
// The class types we care about ("VertexProperties")
111+
std::vector<const llvm::DICompositeType *> VertexTypes;
112+
std::vector<std::pair<uint32_t, uint32_t>> TransitiveDerivedIndex;
113+
// The inheritance graph linearized as-if constructed by L2R pre-order
114+
// traversal from the roots. Allows efficient access to the transitive closure
115+
// without ever storing it explicitly. This only works, because the type-graph
116+
// is known to never contain loops
117+
std::vector<ClassType> Hierarchy;
118+
119+
// The VTables of the polymorphic types in the TH. default-constructed if not
120+
// exists
121+
std::deque<LLVMVFTable> VTables;
122+
};
123+
} // namespace psr
124+
125+
#endif // PHASAR_PHASARLLVM_TYPEHIERARCHY_DIBASEDTYPEHIERARCHY_H

include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ namespace psr {
3232
class LLVMVFTable : public VFTable<const llvm::Function *> {
3333
private:
3434
friend class LLVMTypeHierarchy;
35+
friend class DIBasedTypeHierarchy;
3536
std::vector<const llvm::Function *> VFT;
36-
LLVMVFTable(std::vector<const llvm::Function *> Fs) : VFT(std::move(Fs)) {}
3737

3838
public:
3939
LLVMVFTable() = default;
40+
LLVMVFTable(std::vector<const llvm::Function *> Fs) : VFT(std::move(Fs)) {}
4041
~LLVMVFTable() override = default;
4142

4243
/**

0 commit comments

Comments
 (0)