[Statepoint] Sink actual_args and gc_args to GCStatepointInst [NFC]

These are the two operand sets which are expected to survive more than another week or so.  Instead of bothering to update the deopt and gc-transition operands, we'll just wait until those are removed and delete the code.

For those following along, this is likely to be the last (major) change in this sequence for about a week.  I want to wait until all of this has been merged downstream to ensure I haven't introduced any bugs (and migrate some downstream code to the new interfaces).  Once that's done, we should be able to delete Statepoint/ImmutableStatepoint without too much work.
This commit is contained in:
Philip Reames 2020-05-28 13:34:12 -07:00
parent 4d6cda9bda
commit a0d2fd4a1f
3 changed files with 69 additions and 34 deletions

View File

@ -134,6 +134,53 @@ public:
cast<PointerType>(getActualCalledOperand()->getType())->getElementType();
return cast<FunctionType>(CalleeTy)->getReturnType();
}
/// Return the number of arguments to the underlying call.
size_t actual_arg_size() const { return getNumCallArgs(); }
/// Return an iterator to the begining of the arguments to the underlying call
const_op_iterator actual_arg_begin() const {
assert(CallArgsBeginPos <= (int)arg_size());
return arg_begin() + CallArgsBeginPos;
}
/// Return an end iterator of the arguments to the underlying call
const_op_iterator actual_arg_end() const {
auto I = actual_arg_begin() + actual_arg_size();
assert((arg_end() - I) >= 0);
return I;
}
/// range adapter for actual call arguments
iterator_range<const_op_iterator> actual_args() const {
return make_range(actual_arg_begin(), actual_arg_end());
}
/// Returns an iterator to the begining of the argument range describing gc
/// values for the statepoint.
const_op_iterator gc_args_begin() const {
// The current format has two length prefix bundles between call args and
// start of gc args. This will be removed in the near future.
const Value *NumGCTransitionArgs = *actual_arg_end();
uint64_t NumTrans = cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue();
const_op_iterator trans_end = actual_arg_end() + 1 + NumTrans;
const Value *NumDeoptArgs = *trans_end;
uint64_t NumDeopt = cast<ConstantInt>(NumDeoptArgs)->getZExtValue();
auto I = trans_end + 1 + NumDeopt;
assert((arg_end() - I) >= 0);
return I;
}
/// Return an end iterator for the gc argument range
const_op_iterator gc_args_end() const { return arg_end(); }
/// Return the operand index at which the gc args begin
unsigned gcArgsStartIdx() const {
return gc_args_begin() - op_begin();
}
/// range adapter for gc arguments
iterator_range<const_op_iterator> gc_args() const {
return make_range(gc_args_begin(), gc_args_end());
}
};
/// A wrapper around a GC intrinsic call, this provides most of the actual
@ -201,16 +248,11 @@ public:
return getCall()->doesNotThrow() || (F ? F->doesNotThrow() : false);
}
size_t arg_size() const { return getNumCallArgs(); }
arg_iterator arg_begin() const {
assert(CallArgsBeginPos <= (int)getCall()->arg_size());
return getCall()->arg_begin() + CallArgsBeginPos;
}
arg_iterator arg_end() const {
auto I = arg_begin() + arg_size();
assert((getCall()->arg_end() - I) >= 0);
return I;
size_t arg_size() const { return getCall()->actual_arg_size(); }
arg_iterator arg_begin() const { return getCall()->actual_arg_begin(); }
arg_iterator arg_end() const { return getCall()->actual_arg_end(); }
iterator_range<arg_iterator> call_args() const {
return getCall()->actual_args();
}
ValueTy *getArgument(unsigned Index) {
@ -218,11 +260,6 @@ public:
return *(arg_begin() + Index);
}
/// range adapter for call arguments
iterator_range<arg_iterator> call_args() const {
return make_range(arg_begin(), arg_end());
}
/// Return true if the call or the callee has the given attribute.
bool paramHasAttr(unsigned i, Attribute::AttrKind A) const {
Function *F = getCalledFunction();
@ -274,16 +311,15 @@ public:
return make_range(deopt_begin(), deopt_end());
}
arg_iterator gc_args_begin() const { return deopt_end(); }
arg_iterator gc_args_end() const { return getCall()->arg_end(); }
unsigned gcArgsStartIdx() const {
return gc_args_begin() - getCall()->op_begin();
arg_iterator gc_args_begin() const {
auto I = getCall()->gc_args_begin();
assert(I == deopt_end());
return I;
}
/// range adapter for gc arguments
arg_iterator gc_args_end() const { return getCall()->gc_args_end(); }
unsigned gcArgsStartIdx() const { return getCall()->gcArgsStartIdx(); }
iterator_range<arg_iterator> gc_args() const {
return make_range(gc_args_begin(), gc_args_end());
return getCall()->gc_args();
}
/// Get list of all gc reloactes linked to this statepoint

View File

@ -864,7 +864,7 @@ SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I,
}
}
SI.GCArgs = ArrayRef<const Use>(ISP.gc_args_begin(), ISP.gc_args_end());
SI.GCArgs = ArrayRef<const Use>(I.gc_args_begin(), I.gc_args_end());
SI.StatepointInstr = &I;
SI.ID = I.getID();

View File

@ -271,7 +271,7 @@ struct PartiallyConstructedSafepointRecord {
/// The *new* gc.statepoint instruction itself. This produces the token
/// that normal path gc.relocates and the gc.result are tied to.
Instruction *StatepointToken;
GCStatepointInst *StatepointToken;
/// Instruction to which exceptional gc relocates are attached
/// Makes it easier to iterate through them during relocationViaAlloca.
@ -1546,7 +1546,7 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
}
// Create the statepoint given all the arguments
Instruction *Token = nullptr;
GCStatepointInst *Token = nullptr;
if (auto *CI = dyn_cast<CallInst>(Call)) {
CallInst *SPCall = Builder.CreateGCStatepointCall(
StatepointID, NumPatchBytes, CallTarget, Flags, CallArgs,
@ -1562,7 +1562,7 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
SPCall->setAttributes(
legalizeCallAttributes(CI->getContext(), CI->getAttributes()));
Token = SPCall;
Token = cast<GCStatepointInst>(SPCall);
// Put the following gc_result and gc_relocate calls immediately after the
// the old call (which we're about to delete)
@ -1589,7 +1589,7 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
SPInvoke->setAttributes(
legalizeCallAttributes(II->getContext(), II->getAttributes()));
Token = SPInvoke;
Token = cast<GCStatepointInst>(SPInvoke);
// Generate gc relocates in exceptional path
BasicBlock *UnwindBlock = II->getUnwindDest();
@ -1604,7 +1604,7 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
Instruction *ExceptionalToken = UnwindBlock->getLandingPadInst();
Result.UnwindToken = ExceptionalToken;
const unsigned LiveStartIdx = Statepoint(Token).gcArgsStartIdx();
const unsigned LiveStartIdx = Token->gcArgsStartIdx();
CreateGCRelocates(LiveVariables, LiveStartIdx, BasePtrs, ExceptionalToken,
Builder);
@ -1652,7 +1652,7 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
Result.StatepointToken = Token;
// Second, create a gc.relocate for every live variable
const unsigned LiveStartIdx = Statepoint(Token).gcArgsStartIdx();
const unsigned LiveStartIdx = Token->gcArgsStartIdx();
CreateGCRelocates(LiveVariables, LiveStartIdx, BasePtrs, Token, Builder);
}
@ -2409,9 +2409,8 @@ static bool insertParsePoints(Function &F, DominatorTree &DT,
// That Value* no longer exists and we need to use the new gc_result.
// Thankfully, the live set is embedded in the statepoint (and updated), so
// we just grab that.
Statepoint Statepoint(Info.StatepointToken);
Live.insert(Live.end(), Statepoint.gc_args_begin(),
Statepoint.gc_args_end());
Live.insert(Live.end(), Info.StatepointToken->gc_args_begin(),
Info.StatepointToken->gc_args_end());
#ifndef NDEBUG
// Do some basic sanity checks on our liveness results before performing
// relocation. Relocation can and will turn mistakes in liveness results
@ -2419,7 +2418,7 @@ static bool insertParsePoints(Function &F, DominatorTree &DT,
// TODO: It would be nice to test consistency as well
assert(DT.isReachableFromEntry(Info.StatepointToken->getParent()) &&
"statepoint must be reachable or liveness is meaningless");
for (Value *V : Statepoint.gc_args()) {
for (Value *V : Info.StatepointToken->gc_args()) {
if (!isa<Instruction>(V))
// Non-instruction values trivial dominate all possible uses
continue;