aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/IR/Statepoint.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/IR/Statepoint.h')
-rw-r--r--include/llvm/IR/Statepoint.h78
1 files changed, 61 insertions, 17 deletions
diff --git a/include/llvm/IR/Statepoint.h b/include/llvm/IR/Statepoint.h
index 51a0951a9798..5cd7fe1b576c 100644
--- a/include/llvm/IR/Statepoint.h
+++ b/include/llvm/IR/Statepoint.h
@@ -8,8 +8,9 @@
//===----------------------------------------------------------------------===//
//
// This file contains utility functions and a wrapper class analogous to
-// CallSite for accessing the fields of gc.statepoint, gc.relocate, and
-// gc.result intrinsics
+// CallSite for accessing the fields of gc.statepoint, gc.relocate,
+// gc.result intrinsics; and some general utilities helpful when dealing with
+// gc.statepoint.
//
//===----------------------------------------------------------------------===//
@@ -17,6 +18,7 @@
#define LLVM_IR_STATEPOINT_H
#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
@@ -24,7 +26,6 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
-#include "llvm/Support/Compiler.h"
namespace llvm {
/// The statepoint intrinsic accepts a set of flags as its third argument.
@@ -38,23 +39,22 @@ enum class StatepointFlags {
};
class GCRelocateInst;
+class GCResultInst;
class ImmutableStatepoint;
-bool isStatepoint(const ImmutableCallSite &CS);
+bool isStatepoint(ImmutableCallSite CS);
bool isStatepoint(const Value *V);
bool isStatepoint(const Value &V);
-bool isGCRelocate(const ImmutableCallSite &CS);
-
-bool isGCResult(const Value *V);
-bool isGCResult(const ImmutableCallSite &CS);
+bool isGCRelocate(ImmutableCallSite CS);
+bool isGCResult(ImmutableCallSite CS);
/// Analogous to CallSiteBase, this provides most of the actual
/// functionality for Statepoint and ImmutableStatepoint. It is
/// templatized to allow easily specializing of const and non-const
/// concrete subtypes. This is structured analogous to CallSite
-/// rather than the IntrinsicInst.h helpers since we want to support
-/// invokable statepoints in the near future.
+/// rather than the IntrinsicInst.h helpers since we need to support
+/// invokable statepoints.
template <typename FunTy, typename InstructionTy, typename ValueTy,
typename CallSiteTy>
class StatepointBase {
@@ -252,11 +252,10 @@ public:
/// Get the experimental_gc_result call tied to this statepoint. Can be
/// nullptr if there isn't a gc_result tied to this statepoint. Guaranteed to
/// be a CallInst if non-null.
- InstructionTy *getGCResult() const {
+ const GCResultInst *getGCResult() const {
for (auto *U : getInstruction()->users())
- if (isGCResult(U))
- return cast<CallInst>(U);
-
+ if (auto *GRI = dyn_cast<GCResultInst>(U))
+ return GRI;
return nullptr;
}
@@ -305,11 +304,13 @@ public:
explicit Statepoint(CallSite CS) : Base(CS) {}
};
-/// This represents the gc.relocate intrinsic.
-class GCRelocateInst : public IntrinsicInst {
+/// Common base class for representing values projected from a statepoint.
+/// Currently, the only projections available are gc.result and gc.relocate.
+class GCProjectionInst : public IntrinsicInst {
public:
static inline bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate;
+ return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate ||
+ I->getIntrinsicID() == Intrinsic::experimental_gc_result;
}
static inline bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
@@ -330,6 +331,7 @@ public:
// This takes care both of relocates for call statepoints and relocates
// on normal path of invoke statepoint.
if (!isa<LandingPadInst>(Token)) {
+ assert(isStatepoint(Token));
return cast<Instruction>(Token);
}
@@ -344,6 +346,17 @@ public:
return InvokeBB->getTerminator();
}
+};
+
+/// Represents calls to the gc.relocate intrinsic.
+class GCRelocateInst : public GCProjectionInst {
+public:
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
/// The index into the associate statepoint's argument list
/// which contains the base pointer of the pointer whose
@@ -369,6 +382,17 @@ public:
}
};
+/// Represents calls to the gc.result intrinsic.
+class GCResultInst : public GCProjectionInst {
+public:
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::experimental_gc_result;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
template <typename FunTy, typename InstructionTy, typename ValueTy,
typename CallSiteTy>
std::vector<const GCRelocateInst *>
@@ -400,6 +424,26 @@ StatepointBase<FunTy, InstructionTy, ValueTy, CallSiteTy>::getRelocates()
}
return Result;
}
+
+/// Call sites that get wrapped by a gc.statepoint (currently only in
+/// RewriteStatepointsForGC and potentially in other passes in the future) can
+/// have attributes that describe properties of gc.statepoint call they will be
+/// eventually be wrapped in. This struct is used represent such directives.
+struct StatepointDirectives {
+ Optional<uint32_t> NumPatchBytes;
+ Optional<uint64_t> StatepointID;
+
+ static const uint64_t DefaultStatepointID = 0xABCDEF00;
+ static const uint64_t DeoptBundleStatepointID = 0xABCDEF0F;
+};
+
+/// Parse out statepoint directives from the function attributes present in \p
+/// AS.
+StatepointDirectives parseStatepointDirectivesFromAttrs(AttributeSet AS);
+
+/// Return \c true if the the \p Attr is an attribute that is a statepoint
+/// directive.
+bool isStatepointDirectiveAttr(Attribute Attr);
}
#endif