Skip to content

Commit

Permalink
Introduce a GCStatepointInst type analogous to IntrinsicInst subclasses
Browse files Browse the repository at this point in the history
Back when we had CallSite, we implemented the current Statepoint/ImmutableStatepoint structure in analogous manner.  Now that CallSite has been removed, the structure used for statepoints looks decidely out of place.  gc.statepoint is one of the small handful of intrinsics which are invokable.  Because of this, it can't subclass IntrinsicInst as is idiomatic.

This change simply introduces the GCStatepointInst class, restructures the existing Statepoint/ImmutableStatepoint types to wrap it.  I will be landing a series of changes to sink functionality into GCStatepointInst and updating callers to be more idiomatic.
  • Loading branch information
preames committed May 28, 2020
1 parent eca963f commit c94c5bf
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 18 deletions.
44 changes: 32 additions & 12 deletions llvm/include/llvm/IR/Statepoint.h
Expand Up @@ -65,26 +65,46 @@ bool isGCRelocate(const Value *V);
bool isGCResult(const CallBase *Call);
bool isGCResult(const Value *V);

/// Represents a gc.statepoint intrinsic call. This extends directly from
/// CallBase as the IntrinsicInst only supports calls and gc.statepoint is
/// invokable.
class GCStatepointInst : public CallBase {
public:
GCStatepointInst() = delete;
GCStatepointInst(const GCStatepointInst &) = delete;
GCStatepointInst &operator=(const GCStatepointInst &) = delete;

static bool classof(const CallBase *I) {
if (const Function *CF = I->getCalledFunction())
return CF->getIntrinsicID() == Intrinsic::experimental_gc_statepoint;
return false;
}

static bool classof(const Value *V) {
return isa<CallBase>(V) && classof(cast<CallBase>(V));
}
};

/// A wrapper around a GC intrinsic call, 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.
template <typename FunTy, typename InstructionTy, typename ValueTy,
typename CallBaseTy>
typename CallTy>
class StatepointBase {
CallBaseTy *StatepointCall;
CallTy *StatepointCall;

protected:
explicit StatepointBase(InstructionTy *I) {
StatepointCall = isStatepoint(I) ? cast<CallBaseTy>(I) : nullptr;
StatepointCall = isStatepoint(I) ? cast<CallTy>(I) : nullptr;
}

explicit StatepointBase(CallBaseTy *Call) {
explicit StatepointBase(CallTy *Call) {
StatepointCall = isStatepoint(Call) ? Call : nullptr;
}

public:
using arg_iterator = typename CallBaseTy::const_op_iterator;
using arg_iterator = typename CallTy::const_op_iterator;

enum {
IDPos = 0,
Expand All @@ -104,7 +124,7 @@ class StatepointBase {
}

/// Return the underlying call instruction.
CallBaseTy *getCall() const {
CallTy *getCall() const {
assert(*this && "check validity first!");
return StatepointCall;
}
Expand Down Expand Up @@ -291,9 +311,9 @@ class StatepointBase {
/// to a gc.statepoint.
class ImmutableStatepoint
: public StatepointBase<const Function, const Instruction, const Value,
const CallBase> {
const GCStatepointInst> {
using Base = StatepointBase<const Function, const Instruction, const Value,
const CallBase>;
const GCStatepointInst>;

public:
explicit ImmutableStatepoint(const Instruction *I) : Base(I) {}
Expand All @@ -303,8 +323,8 @@ class ImmutableStatepoint
/// A specialization of it's base class for read-write access
/// to a gc.statepoint.
class Statepoint
: public StatepointBase<Function, Instruction, Value, CallBase> {
using Base = StatepointBase<Function, Instruction, Value, CallBase>;
: public StatepointBase<Function, Instruction, Value, GCStatepointInst> {
using Base = StatepointBase<Function, Instruction, Value, GCStatepointInst>;

public:
explicit Statepoint(Instruction *I) : Base(I) {}
Expand Down Expand Up @@ -402,9 +422,9 @@ class GCResultInst : public GCProjectionInst {
};

template <typename FunTy, typename InstructionTy, typename ValueTy,
typename CallBaseTy>
typename CallTy>
std::vector<const GCRelocateInst *>
StatepointBase<FunTy, InstructionTy, ValueTy, CallBaseTy>::getRelocates()
StatepointBase<FunTy, InstructionTy, ValueTy, CallTy>::getRelocates()
const {
std::vector<const GCRelocateInst *> Result;

Expand Down
8 changes: 2 additions & 6 deletions llvm/lib/IR/Statepoint.cpp
Expand Up @@ -18,15 +18,11 @@
using namespace llvm;

bool llvm::isStatepoint(const CallBase *Call) {
if (auto *F = Call->getCalledFunction())
return F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint;
return false;
return isa<GCStatepointInst>(Call);
}

bool llvm::isStatepoint(const Value *V) {
if (auto *Call = dyn_cast<CallBase>(V))
return isStatepoint(Call);
return false;
return isa<GCStatepointInst>(V);
}

bool llvm::isStatepoint(const Value &V) {
Expand Down

0 comments on commit c94c5bf

Please sign in to comment.