aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h')
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h72
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;
}