CGCleanup.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. //===-- CGCleanup.h - Classes for cleanups IR generation --------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // These classes support the generation of LLVM IR for cleanups.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H
  14. #define LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H
  15. #include "EHScopeStack.h"
  16. #include "llvm/ADT/SmallPtrSet.h"
  17. #include "llvm/ADT/SmallVector.h"
  18. namespace llvm {
  19. class BasicBlock;
  20. class Value;
  21. class ConstantInt;
  22. class AllocaInst;
  23. }
  24. namespace clang {
  25. namespace CodeGen {
  26. /// A protected scope for zero-cost EH handling.
  27. class EHScope {
  28. llvm::BasicBlock *CachedLandingPad;
  29. llvm::BasicBlock *CachedEHDispatchBlock;
  30. EHScopeStack::stable_iterator EnclosingEHScope;
  31. class CommonBitFields {
  32. friend class EHScope;
  33. unsigned Kind : 2;
  34. };
  35. enum { NumCommonBits = 2 };
  36. protected:
  37. class CatchBitFields {
  38. friend class EHCatchScope;
  39. unsigned : NumCommonBits;
  40. unsigned NumHandlers : 32 - NumCommonBits;
  41. };
  42. class CleanupBitFields {
  43. friend class EHCleanupScope;
  44. unsigned : NumCommonBits;
  45. /// Whether this cleanup needs to be run along normal edges.
  46. unsigned IsNormalCleanup : 1;
  47. /// Whether this cleanup needs to be run along exception edges.
  48. unsigned IsEHCleanup : 1;
  49. /// Whether this cleanup is currently active.
  50. unsigned IsActive : 1;
  51. /// Whether this cleanup is a lifetime marker
  52. unsigned IsLifetimeMarker : 1;
  53. /// Whether the normal cleanup should test the activation flag.
  54. unsigned TestFlagInNormalCleanup : 1;
  55. /// Whether the EH cleanup should test the activation flag.
  56. unsigned TestFlagInEHCleanup : 1;
  57. /// The amount of extra storage needed by the Cleanup.
  58. /// Always a multiple of the scope-stack alignment.
  59. unsigned CleanupSize : 12;
  60. /// The number of fixups required by enclosing scopes (not including
  61. /// this one). If this is the top cleanup scope, all the fixups
  62. /// from this index onwards belong to this scope.
  63. unsigned FixupDepth : 32 - 18 - NumCommonBits; // currently 13
  64. };
  65. class FilterBitFields {
  66. friend class EHFilterScope;
  67. unsigned : NumCommonBits;
  68. unsigned NumFilters : 32 - NumCommonBits;
  69. };
  70. union {
  71. CommonBitFields CommonBits;
  72. CatchBitFields CatchBits;
  73. CleanupBitFields CleanupBits;
  74. FilterBitFields FilterBits;
  75. };
  76. public:
  77. enum Kind { Cleanup, Catch, Terminate, Filter };
  78. EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope)
  79. : CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr),
  80. EnclosingEHScope(enclosingEHScope) {
  81. CommonBits.Kind = kind;
  82. }
  83. Kind getKind() const { return static_cast<Kind>(CommonBits.Kind); }
  84. llvm::BasicBlock *getCachedLandingPad() const {
  85. return CachedLandingPad;
  86. }
  87. void setCachedLandingPad(llvm::BasicBlock *block) {
  88. CachedLandingPad = block;
  89. }
  90. llvm::BasicBlock *getCachedEHDispatchBlock() const {
  91. return CachedEHDispatchBlock;
  92. }
  93. void setCachedEHDispatchBlock(llvm::BasicBlock *block) {
  94. CachedEHDispatchBlock = block;
  95. }
  96. bool hasEHBranches() const {
  97. if (llvm::BasicBlock *block = getCachedEHDispatchBlock())
  98. return !block->use_empty();
  99. return false;
  100. }
  101. EHScopeStack::stable_iterator getEnclosingEHScope() const {
  102. return EnclosingEHScope;
  103. }
  104. };
  105. /// A scope which attempts to handle some, possibly all, types of
  106. /// exceptions.
  107. ///
  108. /// Objective C \@finally blocks are represented using a cleanup scope
  109. /// after the catch scope.
  110. class EHCatchScope : public EHScope {
  111. // In effect, we have a flexible array member
  112. // Handler Handlers[0];
  113. // But that's only standard in C99, not C++, so we have to do
  114. // annoying pointer arithmetic instead.
  115. public:
  116. struct Handler {
  117. /// A type info value, or null (C++ null, not an LLVM null pointer)
  118. /// for a catch-all.
  119. llvm::Constant *Type;
  120. /// The catch handler for this type.
  121. llvm::BasicBlock *Block;
  122. bool isCatchAll() const { return Type == nullptr; }
  123. };
  124. private:
  125. friend class EHScopeStack;
  126. Handler *getHandlers() {
  127. return reinterpret_cast<Handler*>(this+1);
  128. }
  129. const Handler *getHandlers() const {
  130. return reinterpret_cast<const Handler*>(this+1);
  131. }
  132. public:
  133. static size_t getSizeForNumHandlers(unsigned N) {
  134. return sizeof(EHCatchScope) + N * sizeof(Handler);
  135. }
  136. EHCatchScope(unsigned numHandlers,
  137. EHScopeStack::stable_iterator enclosingEHScope)
  138. : EHScope(Catch, enclosingEHScope) {
  139. CatchBits.NumHandlers = numHandlers;
  140. }
  141. unsigned getNumHandlers() const {
  142. return CatchBits.NumHandlers;
  143. }
  144. void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block) {
  145. setHandler(I, /*catchall*/ nullptr, Block);
  146. }
  147. void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block) {
  148. assert(I < getNumHandlers());
  149. getHandlers()[I].Type = Type;
  150. getHandlers()[I].Block = Block;
  151. }
  152. const Handler &getHandler(unsigned I) const {
  153. assert(I < getNumHandlers());
  154. return getHandlers()[I];
  155. }
  156. // Clear all handler blocks.
  157. // FIXME: it's better to always call clearHandlerBlocks in DTOR and have a
  158. // 'takeHandler' or some such function which removes ownership from the
  159. // EHCatchScope object if the handlers should live longer than EHCatchScope.
  160. void clearHandlerBlocks() {
  161. for (unsigned I = 0, N = getNumHandlers(); I != N; ++I)
  162. delete getHandler(I).Block;
  163. }
  164. typedef const Handler *iterator;
  165. iterator begin() const { return getHandlers(); }
  166. iterator end() const { return getHandlers() + getNumHandlers(); }
  167. static bool classof(const EHScope *Scope) {
  168. return Scope->getKind() == Catch;
  169. }
  170. };
  171. /// A cleanup scope which generates the cleanup blocks lazily.
  172. class EHCleanupScope : public EHScope {
  173. /// The nearest normal cleanup scope enclosing this one.
  174. EHScopeStack::stable_iterator EnclosingNormal;
  175. /// The nearest EH scope enclosing this one.
  176. EHScopeStack::stable_iterator EnclosingEH;
  177. /// The dual entry/exit block along the normal edge. This is lazily
  178. /// created if needed before the cleanup is popped.
  179. llvm::BasicBlock *NormalBlock;
  180. /// An optional i1 variable indicating whether this cleanup has been
  181. /// activated yet.
  182. llvm::AllocaInst *ActiveFlag;
  183. /// Extra information required for cleanups that have resolved
  184. /// branches through them. This has to be allocated on the side
  185. /// because everything on the cleanup stack has be trivially
  186. /// movable.
  187. struct ExtInfo {
  188. /// The destinations of normal branch-afters and branch-throughs.
  189. llvm::SmallPtrSet<llvm::BasicBlock*, 4> Branches;
  190. /// Normal branch-afters.
  191. SmallVector<std::pair<llvm::BasicBlock*,llvm::ConstantInt*>, 4>
  192. BranchAfters;
  193. };
  194. mutable struct ExtInfo *ExtInfo;
  195. struct ExtInfo &getExtInfo() {
  196. if (!ExtInfo) ExtInfo = new struct ExtInfo();
  197. return *ExtInfo;
  198. }
  199. const struct ExtInfo &getExtInfo() const {
  200. if (!ExtInfo) ExtInfo = new struct ExtInfo();
  201. return *ExtInfo;
  202. }
  203. public:
  204. /// Gets the size required for a lazy cleanup scope with the given
  205. /// cleanup-data requirements.
  206. static size_t getSizeForCleanupSize(size_t Size) {
  207. return sizeof(EHCleanupScope) + Size;
  208. }
  209. size_t getAllocatedSize() const {
  210. return sizeof(EHCleanupScope) + CleanupBits.CleanupSize;
  211. }
  212. EHCleanupScope(bool isNormal, bool isEH, bool isActive,
  213. unsigned cleanupSize, unsigned fixupDepth,
  214. EHScopeStack::stable_iterator enclosingNormal,
  215. EHScopeStack::stable_iterator enclosingEH)
  216. : EHScope(EHScope::Cleanup, enclosingEH), EnclosingNormal(enclosingNormal),
  217. NormalBlock(nullptr), ActiveFlag(nullptr), ExtInfo(nullptr) {
  218. CleanupBits.IsNormalCleanup = isNormal;
  219. CleanupBits.IsEHCleanup = isEH;
  220. CleanupBits.IsActive = isActive;
  221. CleanupBits.IsLifetimeMarker = false;
  222. CleanupBits.TestFlagInNormalCleanup = false;
  223. CleanupBits.TestFlagInEHCleanup = false;
  224. CleanupBits.CleanupSize = cleanupSize;
  225. CleanupBits.FixupDepth = fixupDepth;
  226. assert(CleanupBits.CleanupSize == cleanupSize && "cleanup size overflow");
  227. }
  228. void Destroy() {
  229. delete ExtInfo;
  230. }
  231. // Objects of EHCleanupScope are not destructed. Use Destroy().
  232. ~EHCleanupScope() = delete;
  233. bool isNormalCleanup() const { return CleanupBits.IsNormalCleanup; }
  234. llvm::BasicBlock *getNormalBlock() const { return NormalBlock; }
  235. void setNormalBlock(llvm::BasicBlock *BB) { NormalBlock = BB; }
  236. bool isEHCleanup() const { return CleanupBits.IsEHCleanup; }
  237. bool isActive() const { return CleanupBits.IsActive; }
  238. void setActive(bool A) { CleanupBits.IsActive = A; }
  239. bool isLifetimeMarker() const { return CleanupBits.IsLifetimeMarker; }
  240. void setLifetimeMarker() { CleanupBits.IsLifetimeMarker = true; }
  241. llvm::AllocaInst *getActiveFlag() const { return ActiveFlag; }
  242. void setActiveFlag(llvm::AllocaInst *Var) { ActiveFlag = Var; }
  243. void setTestFlagInNormalCleanup() {
  244. CleanupBits.TestFlagInNormalCleanup = true;
  245. }
  246. bool shouldTestFlagInNormalCleanup() const {
  247. return CleanupBits.TestFlagInNormalCleanup;
  248. }
  249. void setTestFlagInEHCleanup() {
  250. CleanupBits.TestFlagInEHCleanup = true;
  251. }
  252. bool shouldTestFlagInEHCleanup() const {
  253. return CleanupBits.TestFlagInEHCleanup;
  254. }
  255. unsigned getFixupDepth() const { return CleanupBits.FixupDepth; }
  256. EHScopeStack::stable_iterator getEnclosingNormalCleanup() const {
  257. return EnclosingNormal;
  258. }
  259. size_t getCleanupSize() const { return CleanupBits.CleanupSize; }
  260. void *getCleanupBuffer() { return this + 1; }
  261. EHScopeStack::Cleanup *getCleanup() {
  262. return reinterpret_cast<EHScopeStack::Cleanup*>(getCleanupBuffer());
  263. }
  264. /// True if this cleanup scope has any branch-afters or branch-throughs.
  265. bool hasBranches() const { return ExtInfo && !ExtInfo->Branches.empty(); }
  266. /// Add a branch-after to this cleanup scope. A branch-after is a
  267. /// branch from a point protected by this (normal) cleanup to a
  268. /// point in the normal cleanup scope immediately containing it.
  269. /// For example,
  270. /// for (;;) { A a; break; }
  271. /// contains a branch-after.
  272. ///
  273. /// Branch-afters each have their own destination out of the
  274. /// cleanup, guaranteed distinct from anything else threaded through
  275. /// it. Therefore branch-afters usually force a switch after the
  276. /// cleanup.
  277. void addBranchAfter(llvm::ConstantInt *Index,
  278. llvm::BasicBlock *Block) {
  279. struct ExtInfo &ExtInfo = getExtInfo();
  280. if (ExtInfo.Branches.insert(Block).second)
  281. ExtInfo.BranchAfters.push_back(std::make_pair(Block, Index));
  282. }
  283. /// Return the number of unique branch-afters on this scope.
  284. unsigned getNumBranchAfters() const {
  285. return ExtInfo ? ExtInfo->BranchAfters.size() : 0;
  286. }
  287. llvm::BasicBlock *getBranchAfterBlock(unsigned I) const {
  288. assert(I < getNumBranchAfters());
  289. return ExtInfo->BranchAfters[I].first;
  290. }
  291. llvm::ConstantInt *getBranchAfterIndex(unsigned I) const {
  292. assert(I < getNumBranchAfters());
  293. return ExtInfo->BranchAfters[I].second;
  294. }
  295. /// Add a branch-through to this cleanup scope. A branch-through is
  296. /// a branch from a scope protected by this (normal) cleanup to an
  297. /// enclosing scope other than the immediately-enclosing normal
  298. /// cleanup scope.
  299. ///
  300. /// In the following example, the branch through B's scope is a
  301. /// branch-through, while the branch through A's scope is a
  302. /// branch-after:
  303. /// for (;;) { A a; B b; break; }
  304. ///
  305. /// All branch-throughs have a common destination out of the
  306. /// cleanup, one possibly shared with the fall-through. Therefore
  307. /// branch-throughs usually don't force a switch after the cleanup.
  308. ///
  309. /// \return true if the branch-through was new to this scope
  310. bool addBranchThrough(llvm::BasicBlock *Block) {
  311. return getExtInfo().Branches.insert(Block).second;
  312. }
  313. /// Determines if this cleanup scope has any branch throughs.
  314. bool hasBranchThroughs() const {
  315. if (!ExtInfo) return false;
  316. return (ExtInfo->BranchAfters.size() != ExtInfo->Branches.size());
  317. }
  318. static bool classof(const EHScope *Scope) {
  319. return (Scope->getKind() == Cleanup);
  320. }
  321. };
  322. /// An exceptions scope which filters exceptions thrown through it.
  323. /// Only exceptions matching the filter types will be permitted to be
  324. /// thrown.
  325. ///
  326. /// This is used to implement C++ exception specifications.
  327. class EHFilterScope : public EHScope {
  328. // Essentially ends in a flexible array member:
  329. // llvm::Value *FilterTypes[0];
  330. llvm::Value **getFilters() {
  331. return reinterpret_cast<llvm::Value**>(this+1);
  332. }
  333. llvm::Value * const *getFilters() const {
  334. return reinterpret_cast<llvm::Value* const *>(this+1);
  335. }
  336. public:
  337. EHFilterScope(unsigned numFilters)
  338. : EHScope(Filter, EHScopeStack::stable_end()) {
  339. FilterBits.NumFilters = numFilters;
  340. }
  341. static size_t getSizeForNumFilters(unsigned numFilters) {
  342. return sizeof(EHFilterScope) + numFilters * sizeof(llvm::Value*);
  343. }
  344. unsigned getNumFilters() const { return FilterBits.NumFilters; }
  345. void setFilter(unsigned i, llvm::Value *filterValue) {
  346. assert(i < getNumFilters());
  347. getFilters()[i] = filterValue;
  348. }
  349. llvm::Value *getFilter(unsigned i) const {
  350. assert(i < getNumFilters());
  351. return getFilters()[i];
  352. }
  353. static bool classof(const EHScope *scope) {
  354. return scope->getKind() == Filter;
  355. }
  356. };
  357. /// An exceptions scope which calls std::terminate if any exception
  358. /// reaches it.
  359. class EHTerminateScope : public EHScope {
  360. public:
  361. EHTerminateScope(EHScopeStack::stable_iterator enclosingEHScope)
  362. : EHScope(Terminate, enclosingEHScope) {}
  363. static size_t getSize() { return sizeof(EHTerminateScope); }
  364. static bool classof(const EHScope *scope) {
  365. return scope->getKind() == Terminate;
  366. }
  367. };
  368. /// A non-stable pointer into the scope stack.
  369. class EHScopeStack::iterator {
  370. char *Ptr;
  371. friend class EHScopeStack;
  372. explicit iterator(char *Ptr) : Ptr(Ptr) {}
  373. public:
  374. iterator() : Ptr(nullptr) {}
  375. EHScope *get() const {
  376. return reinterpret_cast<EHScope*>(Ptr);
  377. }
  378. EHScope *operator->() const { return get(); }
  379. EHScope &operator*() const { return *get(); }
  380. iterator &operator++() {
  381. switch (get()->getKind()) {
  382. case EHScope::Catch:
  383. Ptr += EHCatchScope::getSizeForNumHandlers(
  384. static_cast<const EHCatchScope*>(get())->getNumHandlers());
  385. break;
  386. case EHScope::Filter:
  387. Ptr += EHFilterScope::getSizeForNumFilters(
  388. static_cast<const EHFilterScope*>(get())->getNumFilters());
  389. break;
  390. case EHScope::Cleanup:
  391. Ptr += static_cast<const EHCleanupScope*>(get())
  392. ->getAllocatedSize();
  393. break;
  394. case EHScope::Terminate:
  395. Ptr += EHTerminateScope::getSize();
  396. break;
  397. }
  398. return *this;
  399. }
  400. iterator next() {
  401. iterator copy = *this;
  402. ++copy;
  403. return copy;
  404. }
  405. iterator operator++(int) {
  406. iterator copy = *this;
  407. operator++();
  408. return copy;
  409. }
  410. bool encloses(iterator other) const { return Ptr >= other.Ptr; }
  411. bool strictlyEncloses(iterator other) const { return Ptr > other.Ptr; }
  412. bool operator==(iterator other) const { return Ptr == other.Ptr; }
  413. bool operator!=(iterator other) const { return Ptr != other.Ptr; }
  414. };
  415. inline EHScopeStack::iterator EHScopeStack::begin() const {
  416. return iterator(StartOfData);
  417. }
  418. inline EHScopeStack::iterator EHScopeStack::end() const {
  419. return iterator(EndOfBuffer);
  420. }
  421. inline void EHScopeStack::popCatch() {
  422. assert(!empty() && "popping exception stack when not empty");
  423. EHCatchScope &scope = cast<EHCatchScope>(*begin());
  424. InnermostEHScope = scope.getEnclosingEHScope();
  425. StartOfData += EHCatchScope::getSizeForNumHandlers(scope.getNumHandlers());
  426. }
  427. inline void EHScopeStack::popTerminate() {
  428. assert(!empty() && "popping exception stack when not empty");
  429. EHTerminateScope &scope = cast<EHTerminateScope>(*begin());
  430. InnermostEHScope = scope.getEnclosingEHScope();
  431. StartOfData += EHTerminateScope::getSize();
  432. }
  433. inline EHScopeStack::iterator EHScopeStack::find(stable_iterator sp) const {
  434. assert(sp.isValid() && "finding invalid savepoint");
  435. assert(sp.Size <= stable_begin().Size && "finding savepoint after pop");
  436. return iterator(EndOfBuffer - sp.Size);
  437. }
  438. inline EHScopeStack::stable_iterator
  439. EHScopeStack::stabilize(iterator ir) const {
  440. assert(StartOfData <= ir.Ptr && ir.Ptr <= EndOfBuffer);
  441. return stable_iterator(EndOfBuffer - ir.Ptr);
  442. }
  443. }
  444. }
  445. #endif