LLVM: include/llvm/ADT/LazyAtomicPointer.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9#ifndef LLVM_ADT_LAZYATOMICPOINTER_H

10#define LLVM_ADT_LAZYATOMICPOINTER_H

11

14#include <assert.h>

15#include

16

17namespace llvm {

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

35 static constexpr uintptr_t getNull() { return 0; }

36 static constexpr uintptr_t getBusy() { return UINTPTR_MAX; }

37

38 static T *makePointer(uintptr_t Value) {

40 return Value ? reinterpret_cast<T *>(Value) : nullptr;

41 }

42 static uintptr_t makeRaw(T *Value) {

43 uintptr_t Raw = Value ? reinterpret_cast<uintptr_t>(Value) : getNull();

44 assert(Raw != getBusy());

45 return Raw;

46 }

47

48public:

49

51

52

53

55

56

57 T *Old = nullptr;

59 }

60 return Old;

61 }

62

63

64

66 uintptr_t RawExistingValue = makeRaw(ExistingValue);

67 if (Storage.compare_exchange_weak(RawExistingValue, makeRaw(NewValue)))

68 return true;

69

70

71 if (RawExistingValue == getBusy())

72 ExistingValue = nullptr;

73 else

74 ExistingValue = makePointer(RawExistingValue);

75 return false;

76 }

77

78

79

81 uintptr_t RawExistingValue = makeRaw(ExistingValue);

82 const uintptr_t OriginalRawExistingValue = RawExistingValue;

83 if (Storage.compare_exchange_strong(RawExistingValue, makeRaw(NewValue)))

84 return true;

85

86

87 if (LLVM_UNLIKELY(RawExistingValue == getBusy())) {

88 while (RawExistingValue == getBusy()) {

89 RawExistingValue = OriginalRawExistingValue;

90 if (Storage.compare_exchange_weak(RawExistingValue, makeRaw(NewValue)))

91 return true;

92 }

93 }

94 ExistingValue = makePointer(RawExistingValue);

95 return false;

96 }

97

98

99

101 uintptr_t RawValue = Storage.load();

102 return RawValue == getBusy() ? nullptr : makePointer(RawValue);

103 }

104

105

106

107

108

110

111 uintptr_t Raw = Storage.load();

112 if (Raw != getNull() && Raw != getBusy())

113 return *makePointer(Raw);

114

115

117 Storage.compare_exchange_strong(Raw, getBusy()))) {

118 Raw = makeRaw(Generator());

119 assert(Raw != getNull() && "Expected non-null from generator");

120 Storage.store(Raw);

121 return *makePointer(Raw);

122 }

123

124

125 while (Raw == getBusy())

126 Raw = Storage.load();

127 assert(Raw != getNull() && "Expected non-null from competing generator");

128 return *makePointer(Raw);

129 }

130

131 explicit operator bool() const { return load(); }

132 operator T *() const { return load(); }

133

136 assert(P && "Unexpected null dereference");

137 return *P;

138 }

140

145 : Storage(makeRaw(RHS.load())) {}

146

159

160private:

161 std::atomic<uintptr_t> Storage;

162};

163

164}

165

166#endif

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

#define LLVM_UNLIKELY(EXPR)

#define LLVM_LIKELY(EXPR)

void store(T *Value)

Store a value. Waits for concurrent loadOrGenerate() calls.

Definition LazyAtomicPointer.h:50

LazyAtomicPointer & operator=(T *RHS)

Definition LazyAtomicPointer.h:151

bool compare_exchange_strong(T *&ExistingValue, T *NewValue)

Compare-exchange.

Definition LazyAtomicPointer.h:80

T * load() const

Return the current stored value.

Definition LazyAtomicPointer.h:100

T * operator->() const

Definition LazyAtomicPointer.h:139

LazyAtomicPointer(const LazyAtomicPointer &RHS)

Definition LazyAtomicPointer.h:144

LazyAtomicPointer(std::nullptr_t)

Definition LazyAtomicPointer.h:142

LazyAtomicPointer & operator=(const LazyAtomicPointer &RHS)

Definition LazyAtomicPointer.h:155

T & operator*() const

Definition LazyAtomicPointer.h:134

LazyAtomicPointer & operator=(std::nullptr_t)

Definition LazyAtomicPointer.h:147

bool compare_exchange_weak(T *&ExistingValue, T *NewValue)

Compare-exchange.

Definition LazyAtomicPointer.h:65

T & loadOrGenerate(function_ref< T *()> Generator)

Get the current value, or call Generator to generate a value.

Definition LazyAtomicPointer.h:109

LazyAtomicPointer()

Definition LazyAtomicPointer.h:141

T * exchange(T *Value)

Set a value.

Definition LazyAtomicPointer.h:54

LazyAtomicPointer(T *Value)

Definition LazyAtomicPointer.h:143

LLVM Value Representation.

An efficient, type-erasing, non-owning reference to a callable.

This is an optimization pass for GlobalISel generic memory operations.