LLVM: lib/Transforms/Coroutines/SuspendCrossingInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

17

18

19

20#define DEBUG_TYPE "coro-suspend-crossing"

21

22namespace llvm {

23#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

27 return;

28 }

29

31}

32

37 dbgs() << Label << ":";

40 if (BV[BBNo]) {

41 dbgs() << " ";

43 }

44 }

45 dbgs() << "\n";

46}

47

49 if (Block.empty())

50 return;

51

54

57

62 dbgs() << ":\n";

63 dump(" Consumes", Block[BBNo].Consumes, RPOT, MST);

64 dump(" Kills", Block[BBNo].Kills, RPOT, MST);

65 }

66 dbgs() << "\n";

67}

68#endif

69

73 size_t const ToIndex = Mapping.blockToIndex(To);

74 bool const Result = Block[ToIndex].Kills[FromIndex];

76 << " crosses suspend point\n");

77 return Result;

78}

79

83 size_t const ToIndex = Mapping.blockToIndex(To);

84 bool Result = Block[ToIndex].Kills[FromIndex] ||

85 (From == To && Block[ToIndex].KillLoop);

87 << " crosses suspend point (path or loop)\n");

88 return Result;

89}

90

91template

92bool SuspendCrossingInfo::computeBlockData(

94 bool Changed = false;

95

98 auto &B = Block[BBNo];

99

100

101 if constexpr (!Initialize)

102

103

105 return !Block[Mapping.blockToIndex(BB)].Changed;

106 })) {

107 B.Changed = false;

108 continue;

109 }

110

111

112

113 auto SavedConsumes = B.Consumes;

114 auto SavedKills = B.Kills;

115

116 for (BasicBlock *PI : predecessors(B)) {

118 auto &P = Block[PrevNo];

119

120

121 B.Consumes |= P.Consumes;

122 B.Kills |= P.Kills;

123

124

125

126 if (P.Suspend)

127 B.Kills |= P.Consumes;

128 }

129

130 if (B.Suspend) {

131

132

133 B.Kills |= B.Consumes;

134 } else if (B.End) {

135

136

137

138

139 B.Kills.reset();

140 } else {

141

142

143 B.KillLoop |= B.Kills[BBNo];

144 B.Kills.reset(BBNo);

145 }

146

147 if constexpr (!Initialize) {

148 B.Changed = (B.Kills != SavedKills) || (B.Consumes != SavedConsumes);

149 Changed |= B.Changed;

150 }

151 }

152

153 return Changed;

154}

155

159 : Mapping(F) {

160 const size_t N = Mapping.size();

162

163

164 for (size_t I = 0; I < N; ++I) {

165 auto &B = Block[I];

166 B.Consumes.resize(N);

167 B.Kills.resize(N);

168 B.Consumes.set(I);

169 B.Changed = true;

170 }

171

172

173

174

175 for (auto *CE : CoroEnds) {

176

177 assert(CE->getParent()->getFirstInsertionPt() == CE->getIterator() &&

178 CE->getParent()->size() <= 2 && "CoroEnd must be in its own BB");

179

180 getBlockData(CE->getParent()).End = true;

181 }

182

183

184

185

186

187 auto markSuspendBlock = [&](IntrinsicInst *BarrierInst) {

189 auto &B = getBlockData(SuspendBlock);

190 B.Suspend = true;

191 B.Kills |= B.Consumes;

192 };

193 for (auto *CSI : CoroSuspends) {

194

195 assert(CSI->getParent()->getFirstInsertionPt() == CSI->getIterator() &&

196 CSI->getParent()->size() <= 2 &&

197 "CoroSuspend must be in its own BB");

198

199 markSuspendBlock(CSI);

200 if (auto *Save = CSI->getCoroSave())

201 markSuspendBlock(Save);

202 }

203

204

205

207 computeBlockData<true>(RPOT);

208 while (computeBlockData</*Initialize*/ false>(RPOT))

209 ;

210

212}

213

214}

BlockVerifier::State From

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

LLVM Basic Block Representation.

const Function * getParent() const

Return the enclosing method, or null if none.

size_t blockToIndex(BasicBlock const *BB) const

BasicBlock * indexToBlock(unsigned Index) const

A wrapper class for inspecting calls to intrinsic functions.

Manage lifetime of a slot tracker for printing IR.

int getLocalSlot(const Value *V)

Return the slot number of the specified local value.

void incorporateFunction(const Function &F)

Incorporate the given function.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

StringRef - Represent a constant reference to a string, i.e.

bool hasPathCrossingSuspendPoint(BasicBlock *From, BasicBlock *To) const

Returns true if there is a path from From to To crossing a suspend point without crossing From a 2nd ...

SuspendCrossingInfo(Function &F, const SmallVectorImpl< AnyCoroSuspendInst * > &CoroSuspends, const SmallVectorImpl< AnyCoroEndInst * > &CoroEnds)

bool hasPathOrLoopCrossingSuspendPoint(BasicBlock *From, BasicBlock *To) const

Returns true if there is a path from From to To crossing a suspend point without crossing From a 2nd ...

StringRef getName() const

Return a constant reference to the value's name.

This is an optimization pass for GlobalISel generic memory operations.

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

static void dumpBasicBlockLabel(const BasicBlock *BB, ModuleSlotTracker &MST)

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.