diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h')
-rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h b/contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h index fcfbf41b0eaf..c73c97146abc 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h +++ b/contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h @@ -16,8 +16,11 @@ #include "EHScopeStack.h" #include "Address.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/IR/Instruction.h" namespace llvm { class BasicBlock; @@ -40,6 +43,10 @@ struct CatchTypeInfo { /// A protected scope for zero-cost EH handling. class EHScope { +public: + enum Kind { Cleanup, Catch, Terminate, Filter }; + +private: llvm::BasicBlock *CachedLandingPad; llvm::BasicBlock *CachedEHDispatchBlock; @@ -47,6 +54,7 @@ class EHScope { class CommonBitFields { friend class EHScope; + LLVM_PREFERRED_TYPE(Kind) unsigned Kind : 3; }; enum { NumCommonBits = 3 }; @@ -64,21 +72,27 @@ protected: unsigned : NumCommonBits; /// Whether this cleanup needs to be run along normal edges. + LLVM_PREFERRED_TYPE(bool) unsigned IsNormalCleanup : 1; /// Whether this cleanup needs to be run along exception edges. + LLVM_PREFERRED_TYPE(bool) unsigned IsEHCleanup : 1; /// Whether this cleanup is currently active. + LLVM_PREFERRED_TYPE(bool) unsigned IsActive : 1; /// Whether this cleanup is a lifetime marker + LLVM_PREFERRED_TYPE(bool) unsigned IsLifetimeMarker : 1; /// Whether the normal cleanup should test the activation flag. + LLVM_PREFERRED_TYPE(bool) unsigned TestFlagInNormalCleanup : 1; /// Whether the EH cleanup should test the activation flag. + LLVM_PREFERRED_TYPE(bool) unsigned TestFlagInEHCleanup : 1; /// The amount of extra storage needed by the Cleanup. @@ -101,8 +115,6 @@ protected: }; public: - enum Kind { Cleanup, Catch, Terminate, Filter }; - EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope) : CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr), EnclosingEHScope(enclosingEHScope) { @@ -257,6 +269,51 @@ class alignas(8) EHCleanupScope : public EHScope { }; mutable struct ExtInfo *ExtInfo; + /// Erases auxillary allocas and their usages for an unused cleanup. + /// Cleanups should mark these allocas as 'used' if the cleanup is + /// emitted, otherwise these instructions would be erased. + struct AuxillaryAllocas { + SmallVector<llvm::Instruction *, 1> AuxAllocas; + bool used = false; + + // Records a potentially unused instruction to be erased later. + void Add(llvm::AllocaInst *Alloca) { AuxAllocas.push_back(Alloca); } + + // Mark all recorded instructions as used. These will not be erased later. + void MarkUsed() { + used = true; + AuxAllocas.clear(); + } + + ~AuxillaryAllocas() { + if (used) + return; + llvm::SetVector<llvm::Instruction *> Uses; + for (auto *Inst : llvm::reverse(AuxAllocas)) + CollectUses(Inst, Uses); + // Delete uses in the reverse order of insertion. + for (auto *I : llvm::reverse(Uses)) + I->eraseFromParent(); + } + + private: + void CollectUses(llvm::Instruction *I, + llvm::SetVector<llvm::Instruction *> &Uses) { + if (!I || !Uses.insert(I)) + return; + for (auto *User : I->users()) + CollectUses(cast<llvm::Instruction>(User), Uses); + } + }; + mutable struct AuxillaryAllocas *AuxAllocas; + + AuxillaryAllocas &getAuxillaryAllocas() { + if (!AuxAllocas) { + AuxAllocas = new struct AuxillaryAllocas(); + } + return *AuxAllocas; + } + /// The number of fixups required by enclosing scopes (not including /// this one). If this is the top cleanup scope, all the fixups /// from this index onwards belong to this scope. @@ -289,7 +346,7 @@ public: EHScopeStack::stable_iterator enclosingEH) : EHScope(EHScope::Cleanup, enclosingEH), EnclosingNormal(enclosingNormal), NormalBlock(nullptr), - ActiveFlag(Address::invalid()), ExtInfo(nullptr), + ActiveFlag(Address::invalid()), ExtInfo(nullptr), AuxAllocas(nullptr), FixupDepth(fixupDepth) { CleanupBits.IsNormalCleanup = isNormal; CleanupBits.IsEHCleanup = isEH; @@ -303,8 +360,15 @@ public: } void Destroy() { + if (AuxAllocas) + delete AuxAllocas; delete ExtInfo; } + void AddAuxAllocas(llvm::SmallVector<llvm::AllocaInst *> Allocas) { + for (auto *Alloca : Allocas) + getAuxillaryAllocas().Add(Alloca); + } + void MarkEmitted() { getAuxillaryAllocas().MarkUsed(); } // Objects of EHCleanupScope are not destructed. Use Destroy(). ~EHCleanupScope() = delete; @@ -324,7 +388,7 @@ public: Address getActiveFlag() const { return ActiveFlag; } - void setActiveFlag(Address Var) { + void setActiveFlag(RawAddress Var) { assert(Var.getAlignment().isOne()); ActiveFlag = Var; } |