1010#ifndef PHASAR_PHASARLLVM_POINTER_POINTSTOSETOWNER_H
1111#define PHASAR_PHASARLLVM_POINTER_POINTSTOSETOWNER_H
1212
13- #include < memory_resource>
13+ #include " phasar/PhasarLLVM/ControlFlow/CFG.h"
14+ #include " phasar/PhasarLLVM/Pointer/DynamicPointsToSetPtr.h"
15+ #include " phasar/PhasarLLVM/Pointer/LLVMPointsToInfo.h"
16+ #include " phasar/Utils/StableVector.h"
1417
1518#include " llvm/ADT/DenseSet.h"
1619#include " llvm/Support/ErrorHandling.h"
1720
18- #include " phasar/PhasarLLVM/Pointer/DynamicPointsToSetPtr.h"
19- #include " phasar/PhasarLLVM/Pointer/LLVMPointsToInfo.h"
20- #include " phasar/Utils/StableVector.h"
21+ #include < type_traits>
22+
23+ // / On some MAC systems, <memory_resource> is still not fully implemented, so do
24+ // / a workaround here
25+
26+ #if !defined(__has_include) || __has_include(<memory_resource>)
27+ #define HAS_MEMORY_RESOURCE 1
28+ #include < memory_resource>
29+ #else
30+ #define HAS_MEMORY_RESOURCE 0
31+ #include " llvm/Support/RecyclingAllocator.h"
32+ #endif
2133
2234namespace llvm {
2335class Value ;
@@ -26,9 +38,27 @@ class Value;
2638namespace psr {
2739template <typename PointsToSetTy> class PointsToSetOwner {
2840public:
29- PointsToSetOwner (std::pmr::polymorphic_allocator<PointsToSetTy> Alloc =
30- std::pmr::get_default_resource ()) noexcept
31- : Alloc(Alloc) {}
41+ using allocator_type =
42+ #if HAS_MEMORY_RESOURCE
43+ std::pmr::polymorphic_allocator<PointsToSetTy>
44+ #else
45+ llvm::RecyclingAllocator<llvm::BumpPtrAllocator, PointsToSetTy> *
46+ #endif
47+ ;
48+
49+ using memory_resource_type =
50+ #if HAS_MEMORY_RESOURCE
51+ std::pmr::unsynchronized_pool_resource
52+ #else
53+ llvm::RecyclingAllocator<llvm::BumpPtrAllocator, PointsToSetTy>
54+ #endif
55+ ;
56+
57+ PointsToSetOwner (allocator_type Alloc) noexcept : Alloc(Alloc) {
58+ if constexpr (std::is_pointer_v<allocator_type>) {
59+ assert (Alloc != nullptr );
60+ }
61+ }
3262 PointsToSetOwner (PointsToSetOwner &&) noexcept = default ;
3363
3464 PointsToSetOwner (const PointsToSetOwner &) = delete ;
@@ -38,31 +68,47 @@ template <typename PointsToSetTy> class PointsToSetOwner {
3868 ~PointsToSetOwner () {
3969 for (auto PTS : OwnedPTS) {
4070 std::destroy_at (PTS);
71+ #if HAS_MEMORY_RESOURCE
4172 Alloc.deallocate (PTS, 1 );
73+ #else
74+ Alloc->Deallocate (PTS);
75+ #endif
4276 }
4377 OwnedPTS.clear ();
4478 }
4579
4680 DynamicPointsToSetPtr<PointsToSetTy> acquire () {
47- auto Ptr = new (Alloc.allocate (1 )) PointsToSetTy ();
81+ auto RawMem =
82+ #if HAS_MEMORY_RESOURCE
83+ Alloc.allocate (1 )
84+ #else
85+ Alloc->Allocate ()
86+ #endif
87+ ;
88+ auto Ptr = new (RawMem) PointsToSetTy ();
4889 OwnedPTS.insert (Ptr);
4990 return &AllPTS.emplace_back (Ptr);
5091 }
92+
5193 void release (PointsToSetTy *PTS) noexcept {
5294 if (LLVM_UNLIKELY (!OwnedPTS.erase (PTS))) {
5395 llvm::report_fatal_error (
5496 " ERROR: release PointsToSet that was either already "
5597 " freed, or never allocated with this PointsToSetOwner!" );
5698 }
5799 std::destroy_at (PTS);
100+ #if HAS_MEMORY_RESOURCE
58101 Alloc.deallocate (PTS, 1 );
102+ #else
103+ Alloc->Deallocate (PTS);
104+ #endif
59105 // / NOTE: Do not delete from AllPTS!
60106 }
61107
62108 void reserve (size_t Capacity) { OwnedPTS.reserve (Capacity); }
63109
64110private:
65- std::pmr::polymorphic_allocator<PointsToSetTy> Alloc;
111+ allocator_type Alloc{} ;
66112 llvm::DenseSet<PointsToSetTy *> OwnedPTS;
67113 StableVector<PointsToSetTy *> AllPTS;
68114};
0 commit comments