mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-22 13:29:44 +00:00
[Statepoints] Support for "patchable" statepoints.
Summary: This change adds two new parameters to the statepoint intrinsic, `i64 id` and `i32 num_patch_bytes`. `id` gets propagated to the ID field in the generated StackMap section. If the `num_patch_bytes` is non-zero then the statepoint is lowered to `num_patch_bytes` bytes of nops instead of a call (the spill and reload code remains unchanged). A non-zero `num_patch_bytes` is useful in situations where a language runtime requires complete control over how a call is lowered. This change brings statepoints one step closer to patchpoints. With some additional work (that is not part of this patch) it should be possible to get rid of `TargetOpcode::STATEPOINT` altogether. PlaceSafepoints generates `statepoint` wrappers with `id` set to `0xABCDEF00` (the old default value for the ID reported in the stackmap) and `num_patch_bytes` set to `0`. This can be made more sophisticated later. Reviewers: reames, pgavlin, swaroop.sridhar, AndyAyers Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D9546 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237214 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
36cb3ce66a
commit
ead2d1fbe0
@ -142,7 +142,7 @@ resulting relocation sequence is:
|
|||||||
|
|
||||||
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
|
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
|
||||||
gc "statepoint-example" {
|
gc "statepoint-example" {
|
||||||
%0 = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
|
%0 = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
|
||||||
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 4, i32 4)
|
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 4, i32 4)
|
||||||
ret i8 addrspace(1)* %obj.relocated
|
ret i8 addrspace(1)* %obj.relocated
|
||||||
}
|
}
|
||||||
@ -297,7 +297,8 @@ Syntax:
|
|||||||
::
|
::
|
||||||
|
|
||||||
declare i32
|
declare i32
|
||||||
@llvm.experimental.gc.statepoint(func_type <target>,
|
@llvm.experimental.gc.statepoint(i64 <id>, i32 <num patch bytes>,
|
||||||
|
func_type <target>,
|
||||||
i64 <#call args>. i64 <flags>,
|
i64 <#call args>. i64 <flags>,
|
||||||
... (call parameters),
|
... (call parameters),
|
||||||
i64 <# transition args>, ... (transition parameters),
|
i64 <# transition args>, ... (transition parameters),
|
||||||
@ -313,11 +314,31 @@ runtime.
|
|||||||
Operands:
|
Operands:
|
||||||
"""""""""
|
"""""""""
|
||||||
|
|
||||||
|
The 'id' operand is a constant integer that is reported as the ID
|
||||||
|
field in the generated stackmap. LLVM does not interpret this
|
||||||
|
parameter in any way and its meaning is up to the statepoint user to
|
||||||
|
decide. Note that LLVM is free to duplicate code containing
|
||||||
|
statepoint calls, and this may transform IR that had a unique 'id' per
|
||||||
|
lexical call to statepoint to IR that does not.
|
||||||
|
|
||||||
|
If 'num patch bytes' is non-zero then the call instruction
|
||||||
|
corresponding to the statepoint is not emitted and LLVM emits 'num
|
||||||
|
patch bytes' bytes of nops in its place. LLVM will emit code to
|
||||||
|
prepare the function arguments and retrieve the function return value
|
||||||
|
in accordance to the calling convention; the former before the nop
|
||||||
|
sequence and the latter after the nop sequence. It is expected that
|
||||||
|
the user will patch over the 'num patch bytes' bytes of nops with a
|
||||||
|
calling sequence specific to their runtime before executing the
|
||||||
|
generated machine code. There are no guarantees with respect to the
|
||||||
|
alignment of the nop sequence. Unlike :doc:`StackMaps` statepoints do
|
||||||
|
not have a concept of shadow bytes.
|
||||||
|
|
||||||
The 'target' operand is the function actually being called. The
|
The 'target' operand is the function actually being called. The
|
||||||
target can be specified as either a symbolic LLVM function, or as an
|
target can be specified as either a symbolic LLVM function, or as an
|
||||||
arbitrary Value of appropriate function type. Note that the function
|
arbitrary Value of appropriate function type. Note that the function
|
||||||
type must match the signature of the callee and the types of the 'call
|
type must match the signature of the callee and the types of the 'call
|
||||||
parameters' arguments.
|
parameters' arguments. If 'num patch bytes' is non-zero then 'target'
|
||||||
|
has to be the constant pointer null of the appropriate function type.
|
||||||
|
|
||||||
The '#call args' operand is the number of arguments to the actual
|
The '#call args' operand is the number of arguments to the actual
|
||||||
call. It must exactly match the number of arguments passed in the
|
call. It must exactly match the number of arguments passed in the
|
||||||
@ -506,9 +527,6 @@ Note that the Locations used in each section may describe the same
|
|||||||
physical location. e.g. A stack slot may appear as a deopt location,
|
physical location. e.g. A stack slot may appear as a deopt location,
|
||||||
a gc base pointer, and a gc derived pointer.
|
a gc base pointer, and a gc derived pointer.
|
||||||
|
|
||||||
The ID field of the 'StkMapRecord' for a statepoint is meaningless and
|
|
||||||
it's value is explicitly unspecified.
|
|
||||||
|
|
||||||
The LiveOut section of the StkMapRecord will be empty for a statepoint
|
The LiveOut section of the StkMapRecord will be empty for a statepoint
|
||||||
record.
|
record.
|
||||||
|
|
||||||
|
@ -85,8 +85,8 @@ public:
|
|||||||
/// MI-level Statepoint operands
|
/// MI-level Statepoint operands
|
||||||
///
|
///
|
||||||
/// Statepoint operands take the form:
|
/// Statepoint operands take the form:
|
||||||
/// <num call arguments>, <call target>, [call arguments],
|
/// <id>, <num patch bytes >, <num call arguments>, <call target>,
|
||||||
/// <StackMaps::ConstantOp>, <calling convention>,
|
/// [call arguments], <StackMaps::ConstantOp>, <calling convention>,
|
||||||
/// <StackMaps::ConstantOp>, <statepoint flags>,
|
/// <StackMaps::ConstantOp>, <statepoint flags>,
|
||||||
/// <StackMaps::ConstantOp>, <num other args>, [other args],
|
/// <StackMaps::ConstantOp>, <num other args>, [other args],
|
||||||
/// [gc values]
|
/// [gc values]
|
||||||
@ -94,10 +94,7 @@ class StatepointOpers {
|
|||||||
private:
|
private:
|
||||||
// These values are aboolute offsets into the operands of the statepoint
|
// These values are aboolute offsets into the operands of the statepoint
|
||||||
// instruction.
|
// instruction.
|
||||||
enum {
|
enum { IDPos, NBytesPos, NCallArgsPos, CallTargetPos, MetaEnd };
|
||||||
NCallArgsPos = 0,
|
|
||||||
CallTargetPos = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// These values are relative offests from the start of the statepoint meta
|
// These values are relative offests from the start of the statepoint meta
|
||||||
// arguments (i.e. the end of the call arguments).
|
// arguments (i.e. the end of the call arguments).
|
||||||
@ -114,20 +111,15 @@ public:
|
|||||||
/// Get starting index of non call related arguments
|
/// Get starting index of non call related arguments
|
||||||
/// (calling convention, statepoint flags, vm state and gc state).
|
/// (calling convention, statepoint flags, vm state and gc state).
|
||||||
unsigned getVarIdx() const {
|
unsigned getVarIdx() const {
|
||||||
return MI->getOperand(NCallArgsPos).getImm() + 2;
|
return MI->getOperand(NCallArgsPos).getImm() + MetaEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the index of the operand containing the number of non-gc non-call
|
/// Return the ID for the given statepoint.
|
||||||
/// arguments.
|
uint64_t getID() const { return MI->getOperand(IDPos).getImm(); }
|
||||||
unsigned getNumVMSArgsIdx() const {
|
|
||||||
return getVarIdx() + NumVMSArgsOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the number of non-gc non-call arguments attached to the
|
/// Return the number of patchable bytes the given statepoint should emit.
|
||||||
/// statepoint. Note that this is the number of arguments, not the number of
|
uint32_t getNumPatchBytes() const {
|
||||||
/// operands required to represent those arguments.
|
return MI->getOperand(NBytesPos).getImm();
|
||||||
unsigned getNumVMSArgs() const {
|
|
||||||
return MI->getOperand(getNumVMSArgsIdx()).getImm();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the target of the underlying call.
|
/// Returns the target of the underlying call.
|
||||||
|
@ -447,7 +447,8 @@ public:
|
|||||||
|
|
||||||
/// \brief Create a call to the experimental.gc.statepoint intrinsic to
|
/// \brief Create a call to the experimental.gc.statepoint intrinsic to
|
||||||
/// start a new statepoint sequence.
|
/// start a new statepoint sequence.
|
||||||
CallInst *CreateGCStatepointCall(Value *ActualCallee,
|
CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
|
||||||
|
Value *ActualCallee,
|
||||||
ArrayRef<Value *> CallArgs,
|
ArrayRef<Value *> CallArgs,
|
||||||
ArrayRef<Value *> DeoptArgs,
|
ArrayRef<Value *> DeoptArgs,
|
||||||
ArrayRef<Value *> GCArgs,
|
ArrayRef<Value *> GCArgs,
|
||||||
@ -456,7 +457,8 @@ public:
|
|||||||
// \brief Conveninence function for the common case when CallArgs are filled
|
// \brief Conveninence function for the common case when CallArgs are filled
|
||||||
// in using makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be
|
// in using makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be
|
||||||
// .get()'ed to get the Value pointer.
|
// .get()'ed to get the Value pointer.
|
||||||
CallInst *CreateGCStatepointCall(Value *ActualCallee, ArrayRef<Use> CallArgs,
|
CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
|
||||||
|
Value *ActualCallee, ArrayRef<Use> CallArgs,
|
||||||
ArrayRef<Value *> DeoptArgs,
|
ArrayRef<Value *> DeoptArgs,
|
||||||
ArrayRef<Value *> GCArgs,
|
ArrayRef<Value *> GCArgs,
|
||||||
const Twine &Name = "");
|
const Twine &Name = "");
|
||||||
@ -464,7 +466,8 @@ public:
|
|||||||
/// brief Create an invoke to the experimental.gc.statepoint intrinsic to
|
/// brief Create an invoke to the experimental.gc.statepoint intrinsic to
|
||||||
/// start a new statepoint sequence.
|
/// start a new statepoint sequence.
|
||||||
InvokeInst *
|
InvokeInst *
|
||||||
CreateGCStatepointInvoke(Value *ActualInvokee, BasicBlock *NormalDest,
|
CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes,
|
||||||
|
Value *ActualInvokee, BasicBlock *NormalDest,
|
||||||
BasicBlock *UnwindDest, ArrayRef<Value *> InvokeArgs,
|
BasicBlock *UnwindDest, ArrayRef<Value *> InvokeArgs,
|
||||||
ArrayRef<Value *> DeoptArgs,
|
ArrayRef<Value *> DeoptArgs,
|
||||||
ArrayRef<Value *> GCArgs, const Twine &Name = "");
|
ArrayRef<Value *> GCArgs, const Twine &Name = "");
|
||||||
@ -473,7 +476,8 @@ public:
|
|||||||
// makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be .get()'ed to
|
// makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be .get()'ed to
|
||||||
// get the Value *.
|
// get the Value *.
|
||||||
InvokeInst *
|
InvokeInst *
|
||||||
CreateGCStatepointInvoke(Value *ActualInvokee, BasicBlock *NormalDest,
|
CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes,
|
||||||
|
Value *ActualInvokee, BasicBlock *NormalDest,
|
||||||
BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
|
BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
|
||||||
ArrayRef<Value *> DeoptArgs,
|
ArrayRef<Value *> DeoptArgs,
|
||||||
ArrayRef<Value *> GCArgs, const Twine &Name = "");
|
ArrayRef<Value *> GCArgs, const Twine &Name = "");
|
||||||
|
@ -528,7 +528,8 @@ def int_experimental_patchpoint_i64 : Intrinsic<[llvm_i64_ty],
|
|||||||
// These are documented in docs/Statepoint.rst
|
// These are documented in docs/Statepoint.rst
|
||||||
|
|
||||||
def int_experimental_gc_statepoint : Intrinsic<[llvm_i32_ty],
|
def int_experimental_gc_statepoint : Intrinsic<[llvm_i32_ty],
|
||||||
[llvm_anyptr_ty, llvm_i32_ty,
|
[llvm_i64_ty, llvm_i32_ty,
|
||||||
|
llvm_anyptr_ty, llvm_i32_ty,
|
||||||
llvm_i32_ty, llvm_vararg_ty]>;
|
llvm_i32_ty, llvm_vararg_ty]>;
|
||||||
|
|
||||||
def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_i32_ty]>;
|
def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_i32_ty]>;
|
||||||
|
@ -74,16 +74,35 @@ public:
|
|||||||
typedef typename CallSiteTy::arg_iterator arg_iterator;
|
typedef typename CallSiteTy::arg_iterator arg_iterator;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ActualCalleePos = 0,
|
IDPos = 0,
|
||||||
NumCallArgsPos = 1,
|
NumPatchBytesPos = 1,
|
||||||
CallArgsBeginPos = 3,
|
ActualCalleePos = 2,
|
||||||
|
NumCallArgsPos = 3,
|
||||||
|
FlagsPos = 4,
|
||||||
|
CallArgsBeginPos = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Return the underlying CallSite.
|
/// Return the underlying CallSite.
|
||||||
CallSiteTy getCallSite() { return StatepointCS; }
|
CallSiteTy getCallSite() { return StatepointCS; }
|
||||||
|
|
||||||
uint64_t getFlags() const {
|
uint64_t getFlags() const {
|
||||||
return cast<ConstantInt>(StatepointCS.getArgument(2))->getZExtValue();
|
return cast<ConstantInt>(StatepointCS.getArgument(FlagsPos))
|
||||||
|
->getZExtValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the ID associated with this statepoint.
|
||||||
|
uint64_t getID() {
|
||||||
|
const Value *IDVal = StatepointCS.getArgument(IDPos);
|
||||||
|
return cast<ConstantInt>(IDVal)->getZExtValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the number of patchable bytes associated with this statepoint.
|
||||||
|
uint32_t getNumPatchBytes() {
|
||||||
|
const Value *NumPatchBytesVal = StatepointCS.getArgument(NumPatchBytesPos);
|
||||||
|
uint64_t NumPatchBytes =
|
||||||
|
cast<ConstantInt>(NumPatchBytesVal)->getZExtValue();
|
||||||
|
assert(isInt<32>(NumPatchBytes) && "should fit in 32 bits!");
|
||||||
|
return NumPatchBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the value actually being called or invoked.
|
/// Return the value actually being called or invoked.
|
||||||
|
@ -583,11 +583,6 @@ void SelectionDAGBuilder::LowerStatepoint(
|
|||||||
// Construct the actual GC_TRANSITION_START, STATEPOINT, and GC_TRANSITION_END
|
// Construct the actual GC_TRANSITION_START, STATEPOINT, and GC_TRANSITION_END
|
||||||
// nodes with all the appropriate arguments and return values.
|
// nodes with all the appropriate arguments and return values.
|
||||||
|
|
||||||
// TODO: Currently, all of these operands are being marked as read/write in
|
|
||||||
// PrologEpilougeInserter.cpp, we should special case the VMState arguments
|
|
||||||
// and flags to be read-only.
|
|
||||||
SmallVector<SDValue, 40> Ops;
|
|
||||||
|
|
||||||
// Call Node: Chain, Target, {Args}, RegMask, [Glue]
|
// Call Node: Chain, Target, {Args}, RegMask, [Glue]
|
||||||
SDValue Chain = CallNode->getOperand(0);
|
SDValue Chain = CallNode->getOperand(0);
|
||||||
|
|
||||||
@ -634,6 +629,16 @@ void SelectionDAGBuilder::LowerStatepoint(
|
|||||||
Glue = GCTransitionStart.getValue(1);
|
Glue = GCTransitionStart.getValue(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Currently, all of these operands are being marked as read/write in
|
||||||
|
// PrologEpilougeInserter.cpp, we should special case the VMState arguments
|
||||||
|
// and flags to be read-only.
|
||||||
|
SmallVector<SDValue, 40> Ops;
|
||||||
|
|
||||||
|
// Add the <id> and <numBytes> constants.
|
||||||
|
Ops.push_back(DAG.getTargetConstant(ISP.getID(), getCurSDLoc(), MVT::i64));
|
||||||
|
Ops.push_back(
|
||||||
|
DAG.getTargetConstant(ISP.getNumPatchBytes(), getCurSDLoc(), MVT::i32));
|
||||||
|
|
||||||
// Calculate and push starting position of vmstate arguments
|
// Calculate and push starting position of vmstate arguments
|
||||||
// Get number of arguments incoming directly into call node
|
// Get number of arguments incoming directly into call node
|
||||||
unsigned NumCallRegArgs =
|
unsigned NumCallRegArgs =
|
||||||
@ -657,7 +662,7 @@ void SelectionDAGBuilder::LowerStatepoint(
|
|||||||
pushStackMapConstant(Ops, *this, CS.getCallingConv());
|
pushStackMapConstant(Ops, *this, CS.getCallingConv());
|
||||||
|
|
||||||
// Add a constant argument for the flags
|
// Add a constant argument for the flags
|
||||||
uint64_t Flags = cast<ConstantInt>(CS.getArgument(2))->getZExtValue();
|
uint64_t Flags = ISP.getFlags();
|
||||||
assert(
|
assert(
|
||||||
((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0)
|
((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0)
|
||||||
&& "unknown flag used");
|
&& "unknown flag used");
|
||||||
|
@ -370,9 +370,8 @@ void StackMaps::recordStatepoint(const MachineInstr &MI) {
|
|||||||
// Record all the deopt and gc operands (they're contiguous and run from the
|
// Record all the deopt and gc operands (they're contiguous and run from the
|
||||||
// initial index to the end of the operand list)
|
// initial index to the end of the operand list)
|
||||||
const unsigned StartIdx = opers.getVarIdx();
|
const unsigned StartIdx = opers.getVarIdx();
|
||||||
recordStackMapOpers(MI, 0xABCDEF00,
|
recordStackMapOpers(MI, opers.getID(), MI.operands_begin() + StartIdx,
|
||||||
MI.operands_begin() + StartIdx, MI.operands_end(),
|
MI.operands_end(), false);
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emit the stackmap header.
|
/// Emit the stackmap header.
|
||||||
|
@ -245,12 +245,13 @@ CallInst *IRBuilderBase::CreateMaskedIntrinsic(unsigned Id,
|
|||||||
return createCallHelper(TheFn, Ops, this, Name);
|
return createCallHelper(TheFn, Ops, this, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<Value *> getStatepointArgs(IRBuilderBase &B,
|
static std::vector<Value *>
|
||||||
Value *ActualCallee,
|
getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
|
||||||
ArrayRef<Value *> CallArgs,
|
Value *ActualCallee, ArrayRef<Value *> CallArgs,
|
||||||
ArrayRef<Value *> DeoptArgs,
|
ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs) {
|
||||||
ArrayRef<Value *> GCArgs) {
|
|
||||||
std::vector<Value *> Args;
|
std::vector<Value *> Args;
|
||||||
|
Args.push_back(B.getInt64(ID));
|
||||||
|
Args.push_back(B.getInt32(NumPatchBytes));
|
||||||
Args.push_back(ActualCallee);
|
Args.push_back(ActualCallee);
|
||||||
Args.push_back(B.getInt32(CallArgs.size()));
|
Args.push_back(B.getInt32(CallArgs.size()));
|
||||||
Args.push_back(B.getInt32((unsigned)StatepointFlags::None));
|
Args.push_back(B.getInt32((unsigned)StatepointFlags::None));
|
||||||
@ -263,11 +264,10 @@ static std::vector<Value *> getStatepointArgs(IRBuilderBase &B,
|
|||||||
return Args;
|
return Args;
|
||||||
}
|
}
|
||||||
|
|
||||||
CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee,
|
CallInst *IRBuilderBase::CreateGCStatepointCall(
|
||||||
ArrayRef<Value *> CallArgs,
|
uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
|
||||||
ArrayRef<Value *> DeoptArgs,
|
ArrayRef<Value *> CallArgs, ArrayRef<Value *> DeoptArgs,
|
||||||
ArrayRef<Value *> GCArgs,
|
ArrayRef<Value *> GCArgs, const Twine &Name) {
|
||||||
const Twine &Name) {
|
|
||||||
// Extract out the type of the callee.
|
// Extract out the type of the callee.
|
||||||
PointerType *FuncPtrType = cast<PointerType>(ActualCallee->getType());
|
PointerType *FuncPtrType = cast<PointerType>(ActualCallee->getType());
|
||||||
assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
|
assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
|
||||||
@ -280,25 +280,25 @@ CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee,
|
|||||||
Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
|
Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
|
||||||
ArgTypes);
|
ArgTypes);
|
||||||
|
|
||||||
std::vector<llvm::Value *> Args =
|
std::vector<llvm::Value *> Args = getStatepointArgs(
|
||||||
getStatepointArgs(*this, ActualCallee, CallArgs, DeoptArgs, GCArgs);
|
*this, ID, NumPatchBytes, ActualCallee, CallArgs, DeoptArgs, GCArgs);
|
||||||
return createCallHelper(FnStatepoint, Args, this, Name);
|
return createCallHelper(FnStatepoint, Args, this, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee,
|
CallInst *IRBuilderBase::CreateGCStatepointCall(
|
||||||
ArrayRef<Use> CallArgs,
|
uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
|
||||||
ArrayRef<Value *> DeoptArgs,
|
ArrayRef<Use> CallArgs, ArrayRef<Value *> DeoptArgs,
|
||||||
ArrayRef<Value *> GCArgs,
|
ArrayRef<Value *> GCArgs, const Twine &Name) {
|
||||||
const Twine &Name) {
|
|
||||||
std::vector<Value *> VCallArgs;
|
std::vector<Value *> VCallArgs;
|
||||||
for (auto &U : CallArgs)
|
for (auto &U : CallArgs)
|
||||||
VCallArgs.push_back(U.get());
|
VCallArgs.push_back(U.get());
|
||||||
return CreateGCStatepointCall(ActualCallee, VCallArgs, DeoptArgs, GCArgs,
|
return CreateGCStatepointCall(ID, NumPatchBytes, ActualCallee, VCallArgs,
|
||||||
Name);
|
DeoptArgs, GCArgs, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
|
InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
|
||||||
Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
|
uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
|
||||||
|
BasicBlock *NormalDest, BasicBlock *UnwindDest,
|
||||||
ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs,
|
ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs,
|
||||||
ArrayRef<Value *> GCArgs, const Twine &Name) {
|
ArrayRef<Value *> GCArgs, const Twine &Name) {
|
||||||
// Extract out the type of the callee.
|
// Extract out the type of the callee.
|
||||||
@ -311,21 +311,22 @@ InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
|
|||||||
Function *FnStatepoint = Intrinsic::getDeclaration(
|
Function *FnStatepoint = Intrinsic::getDeclaration(
|
||||||
M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
|
M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
|
||||||
|
|
||||||
std::vector<llvm::Value *> Args =
|
std::vector<llvm::Value *> Args = getStatepointArgs(
|
||||||
getStatepointArgs(*this, ActualInvokee, InvokeArgs, DeoptArgs, GCArgs);
|
*this, ID, NumPatchBytes, ActualInvokee, InvokeArgs, DeoptArgs, GCArgs);
|
||||||
return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, this,
|
return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, this,
|
||||||
Name);
|
Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
|
InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
|
||||||
Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
|
uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
|
||||||
ArrayRef<Use> InvokeArgs, ArrayRef<Value *> DeoptArgs,
|
BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
|
||||||
ArrayRef<Value *> GCArgs, const Twine &Name) {
|
ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
|
||||||
std::vector<Value *> VCallArgs;
|
std::vector<Value *> VCallArgs;
|
||||||
for (auto &U : InvokeArgs)
|
for (auto &U : InvokeArgs)
|
||||||
VCallArgs.push_back(U.get());
|
VCallArgs.push_back(U.get());
|
||||||
return CreateGCStatepointInvoke(ActualInvokee, NormalDest, UnwindDest,
|
return CreateGCStatepointInvoke(ID, NumPatchBytes, ActualInvokee, NormalDest,
|
||||||
VCallArgs, DeoptArgs, GCArgs, Name);
|
UnwindDest, VCallArgs, DeoptArgs, GCArgs,
|
||||||
|
Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
|
CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
|
||||||
|
@ -1499,13 +1499,34 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) {
|
|||||||
"reordering restrictions required by safepoint semantics",
|
"reordering restrictions required by safepoint semantics",
|
||||||
&CI);
|
&CI);
|
||||||
|
|
||||||
const Value *Target = CS.getArgument(0);
|
const Value *IDV = CS.getArgument(0);
|
||||||
|
Assert(isa<ConstantInt>(IDV), "gc.statepoint ID must be a constant integer",
|
||||||
|
&CI);
|
||||||
|
|
||||||
|
const Value *NumPatchBytesV = CS.getArgument(1);
|
||||||
|
Assert(isa<ConstantInt>(NumPatchBytesV),
|
||||||
|
"gc.statepoint number of patchable bytes must be a constant integer",
|
||||||
|
&CI);
|
||||||
|
const uint64_t NumPatchBytes =
|
||||||
|
cast<ConstantInt>(NumPatchBytesV)->getSExtValue();
|
||||||
|
assert(isInt<32>(NumPatchBytes) && "NumPatchBytesV is an i32!");
|
||||||
|
Assert(NumPatchBytes >= 0, "gc.statepoint number of patchable bytes must be "
|
||||||
|
"positive",
|
||||||
|
&CI);
|
||||||
|
|
||||||
|
const Value *Target = CS.getArgument(2);
|
||||||
const PointerType *PT = dyn_cast<PointerType>(Target->getType());
|
const PointerType *PT = dyn_cast<PointerType>(Target->getType());
|
||||||
Assert(PT && PT->getElementType()->isFunctionTy(),
|
Assert(PT && PT->getElementType()->isFunctionTy(),
|
||||||
"gc.statepoint callee must be of function pointer type", &CI, Target);
|
"gc.statepoint callee must be of function pointer type", &CI, Target);
|
||||||
FunctionType *TargetFuncType = cast<FunctionType>(PT->getElementType());
|
FunctionType *TargetFuncType = cast<FunctionType>(PT->getElementType());
|
||||||
|
|
||||||
const Value *NumCallArgsV = CS.getArgument(1);
|
if (NumPatchBytes)
|
||||||
|
Assert(isa<ConstantPointerNull>(Target->stripPointerCasts()),
|
||||||
|
"gc.statepoint must have null as call target if number of patchable "
|
||||||
|
"bytes is non zero",
|
||||||
|
&CI);
|
||||||
|
|
||||||
|
const Value *NumCallArgsV = CS.getArgument(3);
|
||||||
Assert(isa<ConstantInt>(NumCallArgsV),
|
Assert(isa<ConstantInt>(NumCallArgsV),
|
||||||
"gc.statepoint number of arguments to underlying call "
|
"gc.statepoint number of arguments to underlying call "
|
||||||
"must be constant integer",
|
"must be constant integer",
|
||||||
@ -1529,7 +1550,7 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) {
|
|||||||
Assert(NumCallArgs == NumParams,
|
Assert(NumCallArgs == NumParams,
|
||||||
"gc.statepoint mismatch in number of call args", &CI);
|
"gc.statepoint mismatch in number of call args", &CI);
|
||||||
|
|
||||||
const Value *FlagsV = CS.getArgument(2);
|
const Value *FlagsV = CS.getArgument(4);
|
||||||
Assert(isa<ConstantInt>(FlagsV),
|
Assert(isa<ConstantInt>(FlagsV),
|
||||||
"gc.statepoint flags must be constant integer", &CI);
|
"gc.statepoint flags must be constant integer", &CI);
|
||||||
const uint64_t Flags = cast<ConstantInt>(FlagsV)->getZExtValue();
|
const uint64_t Flags = cast<ConstantInt>(FlagsV)->getZExtValue();
|
||||||
@ -1540,13 +1561,14 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) {
|
|||||||
// the type of the wrapped callee.
|
// the type of the wrapped callee.
|
||||||
for (int i = 0; i < NumParams; i++) {
|
for (int i = 0; i < NumParams; i++) {
|
||||||
Type *ParamType = TargetFuncType->getParamType(i);
|
Type *ParamType = TargetFuncType->getParamType(i);
|
||||||
Type *ArgType = CS.getArgument(3+i)->getType();
|
Type *ArgType = CS.getArgument(5 + i)->getType();
|
||||||
Assert(ArgType == ParamType,
|
Assert(ArgType == ParamType,
|
||||||
"gc.statepoint call argument does not match wrapped "
|
"gc.statepoint call argument does not match wrapped "
|
||||||
"function type",
|
"function type",
|
||||||
&CI);
|
&CI);
|
||||||
}
|
}
|
||||||
const int EndCallArgsInx = 2+NumCallArgs;
|
|
||||||
|
const int EndCallArgsInx = 4 + NumCallArgs;
|
||||||
|
|
||||||
const Value *NumTransitionArgsV = CS.getArgument(EndCallArgsInx+1);
|
const Value *NumTransitionArgsV = CS.getArgument(EndCallArgsInx+1);
|
||||||
Assert(isa<ConstantInt>(NumTransitionArgsV),
|
Assert(isa<ConstantInt>(NumTransitionArgsV),
|
||||||
@ -1570,7 +1592,7 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) {
|
|||||||
&CI);
|
&CI);
|
||||||
|
|
||||||
const int ExpectedNumArgs =
|
const int ExpectedNumArgs =
|
||||||
5 + NumCallArgs + NumTransitionArgs + NumDeoptArgs;
|
7 + NumCallArgs + NumTransitionArgs + NumDeoptArgs;
|
||||||
Assert(ExpectedNumArgs <= (int)CS.arg_size(),
|
Assert(ExpectedNumArgs <= (int)CS.arg_size(),
|
||||||
"gc.statepoint too few arguments according to length fields", &CI);
|
"gc.statepoint too few arguments according to length fields", &CI);
|
||||||
|
|
||||||
@ -3289,7 +3311,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
|
|||||||
CI.getArgOperand(0));
|
CI.getArgOperand(0));
|
||||||
|
|
||||||
// Assert that result type matches wrapped callee.
|
// Assert that result type matches wrapped callee.
|
||||||
const Value *Target = StatepointCS.getArgument(0);
|
const Value *Target = StatepointCS.getArgument(2);
|
||||||
const PointerType *PT = cast<PointerType>(Target->getType());
|
const PointerType *PT = cast<PointerType>(Target->getType());
|
||||||
const FunctionType *TargetFuncType =
|
const FunctionType *TargetFuncType =
|
||||||
cast<FunctionType>(PT->getElementType());
|
cast<FunctionType>(PT->getElementType());
|
||||||
@ -3356,18 +3378,19 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
|
|||||||
// section of the statepoint's argument
|
// section of the statepoint's argument
|
||||||
Assert(StatepointCS.arg_size() > 0,
|
Assert(StatepointCS.arg_size() > 0,
|
||||||
"gc.statepoint: insufficient arguments");
|
"gc.statepoint: insufficient arguments");
|
||||||
Assert(isa<ConstantInt>(StatepointCS.getArgument(1)),
|
Assert(isa<ConstantInt>(StatepointCS.getArgument(3)),
|
||||||
"gc.statement: number of call arguments must be constant integer");
|
"gc.statement: number of call arguments must be constant integer");
|
||||||
const unsigned NumCallArgs =
|
const unsigned NumCallArgs =
|
||||||
cast<ConstantInt>(StatepointCS.getArgument(1))->getZExtValue();
|
cast<ConstantInt>(StatepointCS.getArgument(3))->getZExtValue();
|
||||||
Assert(StatepointCS.arg_size() > NumCallArgs+3,
|
Assert(StatepointCS.arg_size() > NumCallArgs + 5,
|
||||||
"gc.statepoint: mismatch in number of call arguments");
|
"gc.statepoint: mismatch in number of call arguments");
|
||||||
Assert(isa<ConstantInt>(StatepointCS.getArgument(NumCallArgs+3)),
|
Assert(isa<ConstantInt>(StatepointCS.getArgument(NumCallArgs + 5)),
|
||||||
"gc.statepoint: number of transition arguments must be "
|
"gc.statepoint: number of transition arguments must be "
|
||||||
"a constant integer");
|
"a constant integer");
|
||||||
const int NumTransitionArgs =
|
const int NumTransitionArgs =
|
||||||
cast<ConstantInt>(StatepointCS.getArgument(NumCallArgs + 3))->getZExtValue();
|
cast<ConstantInt>(StatepointCS.getArgument(NumCallArgs + 5))
|
||||||
const int DeoptArgsStart = 2 + NumCallArgs + 1 + NumTransitionArgs + 1;
|
->getZExtValue();
|
||||||
|
const int DeoptArgsStart = 4 + NumCallArgs + 1 + NumTransitionArgs + 1;
|
||||||
Assert(isa<ConstantInt>(StatepointCS.getArgument(DeoptArgsStart)),
|
Assert(isa<ConstantInt>(StatepointCS.getArgument(DeoptArgsStart)),
|
||||||
"gc.statepoint: number of deoptimization arguments must be "
|
"gc.statepoint: number of deoptimization arguments must be "
|
||||||
"a constant integer");
|
"a constant integer");
|
||||||
|
@ -812,8 +812,14 @@ void X86AsmPrinter::LowerSTATEPOINT(const MachineInstr &MI,
|
|||||||
X86MCInstLower &MCIL) {
|
X86MCInstLower &MCIL) {
|
||||||
assert(Subtarget->is64Bit() && "Statepoint currently only supports X86-64");
|
assert(Subtarget->is64Bit() && "Statepoint currently only supports X86-64");
|
||||||
|
|
||||||
|
StatepointOpers SOpers(&MI);
|
||||||
|
|
||||||
|
if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {
|
||||||
|
EmitNops(*OutStreamer, PatchBytes, Subtarget->is64Bit(),
|
||||||
|
getSubtargetInfo());
|
||||||
|
} else {
|
||||||
// Lower call target and choose correct opcode
|
// Lower call target and choose correct opcode
|
||||||
const MachineOperand &CallTarget = StatepointOpers(&MI).getCallTarget();
|
const MachineOperand &CallTarget = SOpers.getCallTarget();
|
||||||
MCOperand CallTargetMCOp;
|
MCOperand CallTargetMCOp;
|
||||||
unsigned CallOpcode;
|
unsigned CallOpcode;
|
||||||
switch (CallTarget.getType()) {
|
switch (CallTarget.getType()) {
|
||||||
@ -849,6 +855,7 @@ void X86AsmPrinter::LowerSTATEPOINT(const MachineInstr &MI,
|
|||||||
CallInst.setOpcode(CallOpcode);
|
CallInst.setOpcode(CallOpcode);
|
||||||
CallInst.addOperand(CallTargetMCOp);
|
CallInst.addOperand(CallTargetMCOp);
|
||||||
OutStreamer->EmitInstruction(CallInst, getSubtargetInfo());
|
OutStreamer->EmitInstruction(CallInst, getSubtargetInfo());
|
||||||
|
}
|
||||||
|
|
||||||
// Record our statepoint node in the same section used by STACKMAP
|
// Record our statepoint node in the same section used by STACKMAP
|
||||||
// and PATCHPOINT
|
// and PATCHPOINT
|
||||||
|
@ -904,8 +904,8 @@ static Value *ReplaceWithStatepoint(const CallSite &CS, /* to replace */
|
|||||||
if (CS.isCall()) {
|
if (CS.isCall()) {
|
||||||
CallInst *ToReplace = cast<CallInst>(CS.getInstruction());
|
CallInst *ToReplace = cast<CallInst>(CS.getInstruction());
|
||||||
CallInst *Call = Builder.CreateGCStatepointCall(
|
CallInst *Call = Builder.CreateGCStatepointCall(
|
||||||
CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()), None,
|
0xABCDEF00, 0, CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()),
|
||||||
None, "safepoint_token");
|
None, None, "safepoint_token");
|
||||||
Call->setTailCall(ToReplace->isTailCall());
|
Call->setTailCall(ToReplace->isTailCall());
|
||||||
Call->setCallingConv(ToReplace->getCallingConv());
|
Call->setCallingConv(ToReplace->getCallingConv());
|
||||||
|
|
||||||
@ -933,7 +933,7 @@ static Value *ReplaceWithStatepoint(const CallSite &CS, /* to replace */
|
|||||||
// original block.
|
// original block.
|
||||||
Builder.SetInsertPoint(ToReplace->getParent());
|
Builder.SetInsertPoint(ToReplace->getParent());
|
||||||
InvokeInst *Invoke = Builder.CreateGCStatepointInvoke(
|
InvokeInst *Invoke = Builder.CreateGCStatepointInvoke(
|
||||||
CS.getCalledValue(), ToReplace->getNormalDest(),
|
0xABCDEF00, 0, CS.getCalledValue(), ToReplace->getNormalDest(),
|
||||||
ToReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()),
|
ToReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()),
|
||||||
Builder.getInt32(0), None, "safepoint_token");
|
Builder.getInt32(0), None, "safepoint_token");
|
||||||
|
|
||||||
|
@ -22,13 +22,13 @@ entry:
|
|||||||
%alloca = alloca i1
|
%alloca = alloca i1
|
||||||
%load2 = load i1, i1* %alloca
|
%load2 = load i1, i1* %alloca
|
||||||
%load3 = load i32, i32 addrspace(1)* %dparam
|
%load3 = load i32, i32 addrspace(1)* %dparam
|
||||||
%tok = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
|
%tok = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
|
||||||
%relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 5, i32 5)
|
%relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 7, i32 7)
|
||||||
%load4 = load i32, i32 addrspace(1)* %relocate
|
%load4 = load i32, i32 addrspace(1)* %relocate
|
||||||
%nparam = getelementptr i32, i32 addrspace(1)* %dparam, i32 5
|
%nparam = getelementptr i32, i32 addrspace(1)* %dparam, i32 5
|
||||||
%load5 = load i32, i32 addrspace(1)* %nparam
|
%load5 = load i32, i32 addrspace(1)* %nparam
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
|
||||||
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
|
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
|
@ -13,29 +13,29 @@
|
|||||||
|
|
||||||
; function and integer
|
; function and integer
|
||||||
define i32* @test_iAny(i32* %v) gc "statepoint-example" {
|
define i32* @test_iAny(i32* %v) gc "statepoint-example" {
|
||||||
%tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %v)
|
%tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %v)
|
||||||
%v-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5)
|
%v-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7)
|
||||||
ret i32* %v-new
|
ret i32* %v-new
|
||||||
}
|
}
|
||||||
|
|
||||||
; float
|
; float
|
||||||
define float* @test_fAny(float* %v) gc "statepoint-example" {
|
define float* @test_fAny(float* %v) gc "statepoint-example" {
|
||||||
%tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, float* %v)
|
%tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, float* %v)
|
||||||
%v-new = call float* @llvm.experimental.gc.relocate.p0f32(i32 %tok, i32 5, i32 5)
|
%v-new = call float* @llvm.experimental.gc.relocate.p0f32(i32 %tok, i32 7, i32 7)
|
||||||
ret float* %v-new
|
ret float* %v-new
|
||||||
}
|
}
|
||||||
|
|
||||||
; array of integers
|
; array of integers
|
||||||
define [3 x i32]* @test_aAny([3 x i32]* %v) gc "statepoint-example" {
|
define [3 x i32]* @test_aAny([3 x i32]* %v) gc "statepoint-example" {
|
||||||
%tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %v)
|
%tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %v)
|
||||||
%v-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 5, i32 5)
|
%v-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 7, i32 7)
|
||||||
ret [3 x i32]* %v-new
|
ret [3 x i32]* %v-new
|
||||||
}
|
}
|
||||||
|
|
||||||
; vector of integers
|
; vector of integers
|
||||||
define <3 x i32>* @test_vAny(<3 x i32>* %v) gc "statepoint-example" {
|
define <3 x i32>* @test_vAny(<3 x i32>* %v) gc "statepoint-example" {
|
||||||
%tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, <3 x i32>* %v)
|
%tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, <3 x i32>* %v)
|
||||||
%v-new = call <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(i32 %tok, i32 5, i32 5)
|
%v-new = call <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(i32 %tok, i32 7, i32 7)
|
||||||
ret <3 x i32>* %v-new
|
ret <3 x i32>* %v-new
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,13 +43,13 @@ define <3 x i32>* @test_vAny(<3 x i32>* %v) gc "statepoint-example" {
|
|||||||
|
|
||||||
; struct
|
; struct
|
||||||
define %struct.test* @test_struct(%struct.test* %v) gc "statepoint-example" {
|
define %struct.test* @test_struct(%struct.test* %v) gc "statepoint-example" {
|
||||||
%tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, %struct.test* %v)
|
%tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, %struct.test* %v)
|
||||||
%v-new = call %struct.test* @llvm.experimental.gc.relocate.p0struct.test(i32 %tok, i32 5, i32 5)
|
%v-new = call %struct.test* @llvm.experimental.gc.relocate.p0struct.test(i32 %tok, i32 7, i32 7)
|
||||||
ret %struct.test* %v-new
|
ret %struct.test* %v-new
|
||||||
}
|
}
|
||||||
|
|
||||||
declare zeroext i1 @return_i1()
|
declare zeroext i1 @return_i1()
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
|
||||||
declare i32* @llvm.experimental.gc.relocate.p0i32(i32, i32, i32)
|
declare i32* @llvm.experimental.gc.relocate.p0i32(i32, i32, i32)
|
||||||
declare float* @llvm.experimental.gc.relocate.p0f32(i32, i32, i32)
|
declare float* @llvm.experimental.gc.relocate.p0f32(i32, i32, i32)
|
||||||
declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32, i32, i32)
|
declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32, i32, i32)
|
||||||
|
@ -21,7 +21,7 @@ define i32 addrspace(1)* @test(i32 addrspace(1)* %ptr) gc "statepoint-example" {
|
|||||||
entry:
|
entry:
|
||||||
%alloca = alloca i32 addrspace(1)*, align 8
|
%alloca = alloca i32 addrspace(1)*, align 8
|
||||||
store i32 addrspace(1)* %ptr, i32 addrspace(1)** %alloca
|
store i32 addrspace(1)* %ptr, i32 addrspace(1)** %alloca
|
||||||
call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)** %alloca)
|
call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)** %alloca)
|
||||||
%rel = load i32 addrspace(1)*, i32 addrspace(1)** %alloca
|
%rel = load i32 addrspace(1)*, i32 addrspace(1)** %alloca
|
||||||
ret i32 addrspace(1)* %rel
|
ret i32 addrspace(1)* %rel
|
||||||
}
|
}
|
||||||
@ -38,11 +38,11 @@ define i32 addrspace(1)* @test2(i32 addrspace(1)* %ptr) gc "statepoint-example"
|
|||||||
entry:
|
entry:
|
||||||
%alloca = alloca i32 addrspace(1)*, align 8
|
%alloca = alloca i32 addrspace(1)*, align 8
|
||||||
store i32 addrspace(1)* %ptr, i32 addrspace(1)** %alloca
|
store i32 addrspace(1)* %ptr, i32 addrspace(1)** %alloca
|
||||||
call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 1, i32 addrspace(1)** %alloca)
|
call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 1, i32 addrspace(1)** %alloca)
|
||||||
ret i32 addrspace(1)* null
|
ret i32 addrspace(1)* null
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
|
||||||
|
|
||||||
|
|
||||||
; CHECK-LABEL: .section .llvm_stackmaps
|
; CHECK-LABEL: .section .llvm_stackmaps
|
||||||
@ -66,7 +66,7 @@ declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
|
|||||||
|
|
||||||
; Large Constants
|
; Large Constants
|
||||||
; Statepoint ID only
|
; Statepoint ID only
|
||||||
; CHECK: .quad 2882400000
|
; CHECK: .quad 0
|
||||||
|
|
||||||
; Callsites
|
; Callsites
|
||||||
; The GC one
|
; The GC one
|
||||||
@ -128,4 +128,3 @@ declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
|
|||||||
; CHECK: .short 0
|
; CHECK: .short 0
|
||||||
; CHECK: .align 8
|
; CHECK: .align 8
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ define i1 @test_i1_return() gc "statepoint-example" {
|
|||||||
; CHECK: popq %rdx
|
; CHECK: popq %rdx
|
||||||
; CHECK: retq
|
; CHECK: retq
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0)
|
||||||
%call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
%call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
||||||
ret i1 %call1
|
ret i1 %call1
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ define i32 @test_i32_return() gc "statepoint-example" {
|
|||||||
; CHECK: popq %rdx
|
; CHECK: popq %rdx
|
||||||
; CHECK: retq
|
; CHECK: retq
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()* @return_i32, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = tail call i32 (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 0, i32 0, i32 ()* @return_i32, i32 0, i32 0, i32 0, i32 0)
|
||||||
%call1 = call zeroext i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
|
%call1 = call zeroext i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
|
||||||
ret i32 %call1
|
ret i32 %call1
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ define i32* @test_i32ptr_return() gc "statepoint-example" {
|
|||||||
; CHECK: popq %rdx
|
; CHECK: popq %rdx
|
||||||
; CHECK: retq
|
; CHECK: retq
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()* @return_i32ptr, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = tail call i32 (i64, i32, i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i64 0, i32 0, i32* ()* @return_i32ptr, i32 0, i32 0, i32 0, i32 0)
|
||||||
%call1 = call i32* @llvm.experimental.gc.result.p0i32(i32 %safepoint_token)
|
%call1 = call i32* @llvm.experimental.gc.result.p0i32(i32 %safepoint_token)
|
||||||
ret i32* %call1
|
ret i32* %call1
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ define float @test_float_return() gc "statepoint-example" {
|
|||||||
; CHECK: popq %rax
|
; CHECK: popq %rax
|
||||||
; CHECK: retq
|
; CHECK: retq
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (float ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_f32f(float ()* @return_float, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = tail call i32 (i64, i32, float ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_f32f(i64 0, i32 0, float ()* @return_float, i32 0, i32 0, i32 0, i32 0)
|
||||||
%call1 = call float @llvm.experimental.gc.result.f32(i32 %safepoint_token)
|
%call1 = call float @llvm.experimental.gc.result.f32(i32 %safepoint_token)
|
||||||
ret float %call1
|
ret float %call1
|
||||||
}
|
}
|
||||||
@ -70,8 +70,8 @@ define i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" {
|
|||||||
; CHECK-NEXT: popq %rdx
|
; CHECK-NEXT: popq %rdx
|
||||||
; CHECK-NEXT: retq
|
; CHECK-NEXT: retq
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %a)
|
%safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %a)
|
||||||
%call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
|
%call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
|
||||||
%call2 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
%call2 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
||||||
ret i1 %call2
|
ret i1 %call2
|
||||||
}
|
}
|
||||||
@ -81,24 +81,37 @@ define void @test_void_vararg() gc "statepoint-example" {
|
|||||||
; Check a statepoint wrapping a *void* returning vararg function works
|
; Check a statepoint wrapping a *void* returning vararg function works
|
||||||
; CHECK: callq varargf
|
; CHECK: callq varargf
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (void (i32, ...)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)* @varargf, i32 2, i32 0, i32 42, i32 43, i32 0, i32 0)
|
%safepoint_token = tail call i32 (i64, i32, void (i32, ...)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64 0, i32 0, void (i32, ...)* @varargf, i32 2, i32 0, i32 42, i32 43, i32 0, i32 0)
|
||||||
;; if we try to use the result from a statepoint wrapping a
|
;; if we try to use the result from a statepoint wrapping a
|
||||||
;; non-void-returning varargf, we will experience a crash.
|
;; non-void-returning varargf, we will experience a crash.
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
|
define i1 @test_i1_return_patchable() gc "statepoint-example" {
|
||||||
|
; CHECK-LABEL: test_i1_return_patchable
|
||||||
|
; A patchable variant of test_i1_return
|
||||||
|
; CHECK: pushq %rax
|
||||||
|
; CHECK: nopl
|
||||||
|
; CHECK: popq %rdx
|
||||||
|
; CHECK: retq
|
||||||
|
entry:
|
||||||
|
%safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 3, i1 ()*null, i32 0, i32 0, i32 0, i32 0)
|
||||||
|
%call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
||||||
|
ret i1 %call1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
|
||||||
declare i1 @llvm.experimental.gc.result.i1(i32)
|
declare i1 @llvm.experimental.gc.result.i1(i32)
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i64, i32, i32 ()*, i32, i32, ...)
|
||||||
declare i32 @llvm.experimental.gc.result.i32(i32)
|
declare i32 @llvm.experimental.gc.result.i32(i32)
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i64, i32, i32* ()*, i32, i32, ...)
|
||||||
declare i32* @llvm.experimental.gc.result.p0i32(i32)
|
declare i32* @llvm.experimental.gc.result.p0i32(i32)
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(float ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(i64, i32, float ()*, i32, i32, ...)
|
||||||
declare float @llvm.experimental.gc.result.f32(i32)
|
declare float @llvm.experimental.gc.result.f32(i32)
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64, i32, void (i32, ...)*, i32, i32, ...)
|
||||||
|
|
||||||
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
|
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
|
||||||
|
@ -25,8 +25,8 @@ entry:
|
|||||||
%before = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %p
|
%before = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %p
|
||||||
%cmp1 = call i1 @f(i32 addrspace(1)* %before)
|
%cmp1 = call i1 @f(i32 addrspace(1)* %before)
|
||||||
call void @llvm.assume(i1 %cmp1)
|
call void @llvm.assume(i1 %cmp1)
|
||||||
%safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* addrspace(1)* %p)
|
%safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* addrspace(1)* %p)
|
||||||
%pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 5, i32 5)
|
%pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 7, i32 7)
|
||||||
%after = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %pnew
|
%after = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %pnew
|
||||||
%cmp2 = call i1 @f(i32 addrspace(1)* %after)
|
%cmp2 = call i1 @f(i32 addrspace(1)* %after)
|
||||||
ret i1 %cmp2
|
ret i1 %cmp2
|
||||||
@ -44,8 +44,8 @@ entry:
|
|||||||
%cmp1 = call i1 @f(i32 addrspace(1)* %v)
|
%cmp1 = call i1 @f(i32 addrspace(1)* %v)
|
||||||
call void @llvm.assume(i1 %cmp1)
|
call void @llvm.assume(i1 %cmp1)
|
||||||
store i32 addrspace(1)* %v, i32 addrspace(1)* addrspace(1)* %p
|
store i32 addrspace(1)* %v, i32 addrspace(1)* addrspace(1)* %p
|
||||||
%safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* addrspace(1)* %p)
|
%safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* addrspace(1)* %p)
|
||||||
%pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 5, i32 5)
|
%pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 7, i32 7)
|
||||||
%after = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %pnew
|
%after = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %pnew
|
||||||
%cmp2 = call i1 @f(i32 addrspace(1)* %after)
|
%cmp2 = call i1 @f(i32 addrspace(1)* %after)
|
||||||
ret i1 %cmp2
|
ret i1 %cmp2
|
||||||
@ -72,7 +72,7 @@ entry:
|
|||||||
%before = load i32 addrspace(1)*, i32 addrspace(1)** %p
|
%before = load i32 addrspace(1)*, i32 addrspace(1)** %p
|
||||||
%cmp1 = call i1 @f(i32 addrspace(1)* %before)
|
%cmp1 = call i1 @f(i32 addrspace(1)* %before)
|
||||||
call void @llvm.assume(i1 %cmp1)
|
call void @llvm.assume(i1 %cmp1)
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0)
|
||||||
%after = load i32 addrspace(1)*, i32 addrspace(1)** %p
|
%after = load i32 addrspace(1)*, i32 addrspace(1)** %p
|
||||||
%cmp2 = call i1 @f(i32 addrspace(1)* %after)
|
%cmp2 = call i1 @f(i32 addrspace(1)* %after)
|
||||||
ret i1 %cmp2
|
ret i1 %cmp2
|
||||||
@ -90,7 +90,7 @@ entry:
|
|||||||
%cmp1 = call i1 @f(i32 addrspace(1)* %v)
|
%cmp1 = call i1 @f(i32 addrspace(1)* %v)
|
||||||
call void @llvm.assume(i1 %cmp1)
|
call void @llvm.assume(i1 %cmp1)
|
||||||
store i32 addrspace(1)* %v, i32 addrspace(1)** %p
|
store i32 addrspace(1)* %v, i32 addrspace(1)** %p
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0)
|
||||||
%after = load i32 addrspace(1)*, i32 addrspace(1)** %p
|
%after = load i32 addrspace(1)*, i32 addrspace(1)** %p
|
||||||
%cmp2 = call i1 @f(i32 addrspace(1)* %after)
|
%cmp2 = call i1 @f(i32 addrspace(1)* %after)
|
||||||
ret i1 %cmp2
|
ret i1 %cmp2
|
||||||
@ -102,6 +102,5 @@ entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.assume(i1)
|
declare void @llvm.assume(i1)
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
declare i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32, i32, i32) #3
|
declare i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32, i32, i32) #3
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ define i1 @test_i1_return() gc "statepoint-example" {
|
|||||||
; CHECK: popq %rdx
|
; CHECK: popq %rdx
|
||||||
; CHECK: retq
|
; CHECK: retq
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 1, i32 0, i32 0)
|
%safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 1, i32 0, i32 0)
|
||||||
%call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
%call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
||||||
ret i1 %call1
|
ret i1 %call1
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ define i32 @test_i32_return() gc "statepoint-example" {
|
|||||||
; CHECK: popq %rdx
|
; CHECK: popq %rdx
|
||||||
; CHECK: retq
|
; CHECK: retq
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()* @return_i32, i32 0, i32 1, i32 0, i32 0)
|
%safepoint_token = tail call i32 (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 0, i32 0, i32 ()* @return_i32, i32 0, i32 1, i32 0, i32 0)
|
||||||
%call1 = call zeroext i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
|
%call1 = call zeroext i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
|
||||||
ret i32 %call1
|
ret i32 %call1
|
||||||
}
|
}
|
||||||
@ -45,7 +45,7 @@ define i32* @test_i32ptr_return() gc "statepoint-example" {
|
|||||||
; CHECK: popq %rdx
|
; CHECK: popq %rdx
|
||||||
; CHECK: retq
|
; CHECK: retq
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()* @return_i32ptr, i32 0, i32 1, i32 0, i32 0)
|
%safepoint_token = tail call i32 (i64, i32, i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i64 0, i32 0, i32* ()* @return_i32ptr, i32 0, i32 1, i32 0, i32 0)
|
||||||
%call1 = call i32* @llvm.experimental.gc.result.p0i32(i32 %safepoint_token)
|
%call1 = call i32* @llvm.experimental.gc.result.p0i32(i32 %safepoint_token)
|
||||||
ret i32* %call1
|
ret i32* %call1
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ define float @test_float_return() gc "statepoint-example" {
|
|||||||
; CHECK: popq %rax
|
; CHECK: popq %rax
|
||||||
; CHECK: retq
|
; CHECK: retq
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (float ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_f32f(float ()* @return_float, i32 0, i32 1, i32 0, i32 0)
|
%safepoint_token = tail call i32 (i64, i32, float ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_f32f(i64 0, i32 0, float ()* @return_float, i32 0, i32 1, i32 0, i32 0)
|
||||||
%call1 = call float @llvm.experimental.gc.result.f32(i32 %safepoint_token)
|
%call1 = call float @llvm.experimental.gc.result.f32(i32 %safepoint_token)
|
||||||
ret float %call1
|
ret float %call1
|
||||||
}
|
}
|
||||||
@ -71,8 +71,8 @@ define i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" {
|
|||||||
; CHECK-NEXT: popq %rdx
|
; CHECK-NEXT: popq %rdx
|
||||||
; CHECK-NEXT: retq
|
; CHECK-NEXT: retq
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 1, i32 0, i32 0, i32 addrspace(1)* %a)
|
%safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 1, i32 0, i32 0, i32 addrspace(1)* %a)
|
||||||
%call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
|
%call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
|
||||||
%call2 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
%call2 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
||||||
ret i1 %call2
|
ret i1 %call2
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ define void @test_void_vararg() gc "statepoint-example" {
|
|||||||
; Check a statepoint wrapping a *void* returning vararg function works
|
; Check a statepoint wrapping a *void* returning vararg function works
|
||||||
; CHECK: callq varargf
|
; CHECK: callq varargf
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (void (i32, ...)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)* @varargf, i32 2, i32 1, i32 42, i32 43, i32 0, i32 0)
|
%safepoint_token = tail call i32 (i64, i32, void (i32, ...)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64 0, i32 0, void (i32, ...)* @varargf, i32 2, i32 1, i32 42, i32 43, i32 0, i32 0)
|
||||||
;; if we try to use the result from a statepoint wrapping a
|
;; if we try to use the result from a statepoint wrapping a
|
||||||
;; non-void-returning varargf, we will experience a crash.
|
;; non-void-returning varargf, we will experience a crash.
|
||||||
ret void
|
ret void
|
||||||
@ -96,7 +96,7 @@ define i32 @test_transition_args() gc "statepoint-example" {
|
|||||||
; CHECK: retq
|
; CHECK: retq
|
||||||
entry:
|
entry:
|
||||||
%val = alloca i32
|
%val = alloca i32
|
||||||
%safepoint_token = call i32 (i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()* @return_i32, i32 0, i32 1, i32 2, i32* %val, i64 42, i32 0)
|
%safepoint_token = call i32 (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 0, i32 0, i32 ()* @return_i32, i32 0, i32 1, i32 2, i32* %val, i64 42, i32 0)
|
||||||
%call1 = call i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
|
%call1 = call i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
|
||||||
ret i32 %call1
|
ret i32 %call1
|
||||||
}
|
}
|
||||||
@ -110,24 +110,24 @@ define i32 @test_transition_args_2() gc "statepoint-example" {
|
|||||||
entry:
|
entry:
|
||||||
%val = alloca i32
|
%val = alloca i32
|
||||||
%arg = alloca i8
|
%arg = alloca i8
|
||||||
%safepoint_token = call i32 (i32 (i32, i8*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32i32p0i8f(i32 (i32, i8*)* @return_i32_with_args, i32 2, i32 1, i32 0, i8* %arg, i32 2, i32* %val, i64 42, i32 0)
|
%safepoint_token = call i32 (i64, i32, i32 (i32, i8*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32i32p0i8f(i64 0, i32 0, i32 (i32, i8*)* @return_i32_with_args, i32 2, i32 1, i32 0, i8* %arg, i32 2, i32* %val, i64 42, i32 0)
|
||||||
%call1 = call i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
|
%call1 = call i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
|
||||||
ret i32 %call1
|
ret i32 %call1
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
|
||||||
declare i1 @llvm.experimental.gc.result.i1(i32)
|
declare i1 @llvm.experimental.gc.result.i1(i32)
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i64, i32, i32 ()*, i32, i32, ...)
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i32i32p0i8f(i32 (i32, i8*)*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i32i32p0i8f(i64, i32, i32 (i32, i8*)*, i32, i32, ...)
|
||||||
declare i32 @llvm.experimental.gc.result.i32(i32)
|
declare i32 @llvm.experimental.gc.result.i32(i32)
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i64, i32, i32* ()*, i32, i32, ...)
|
||||||
declare i32* @llvm.experimental.gc.result.p0i32(i32)
|
declare i32* @llvm.experimental.gc.result.p0i32(i32)
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(float ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(i64, i32, float ()*, i32, i32, ...)
|
||||||
declare float @llvm.experimental.gc.result.f32(i32)
|
declare float @llvm.experimental.gc.result.f32(i32)
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64, i32, void (i32, ...)*, i32, i32, ...)
|
||||||
|
|
||||||
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
|
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
|
@ -13,7 +13,7 @@ entry:
|
|||||||
; CHECK: .Ltmp{{[0-9]+}}:
|
; CHECK: .Ltmp{{[0-9]+}}:
|
||||||
; CHECK: callq some_other_call
|
; CHECK: callq some_other_call
|
||||||
; CHECK: .Ltmp{{[0-9]+}}:
|
; CHECK: .Ltmp{{[0-9]+}}:
|
||||||
%0 = invoke i32 (i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 addrspace(1)* (i64 addrspace(1)*)* @some_other_call, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1)
|
%0 = invoke i32 (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 0, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @some_other_call, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1)
|
||||||
to label %normal_return unwind label %exceptional_return
|
to label %normal_return unwind label %exceptional_return
|
||||||
|
|
||||||
normal_return:
|
normal_return:
|
||||||
@ -36,5 +36,5 @@ exceptional_return:
|
|||||||
; CHECK: .byte 0
|
; CHECK: .byte 0
|
||||||
; CHECK: .align 4
|
; CHECK: .align 4
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...)
|
||||||
declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32)
|
declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32)
|
@ -14,17 +14,17 @@ define i32 @back_to_back_calls(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 a
|
|||||||
; CHECK: movq %rdi, 16(%rsp)
|
; CHECK: movq %rdi, 16(%rsp)
|
||||||
; CHECK: movq %rdx, 8(%rsp)
|
; CHECK: movq %rdx, 8(%rsp)
|
||||||
; CHECK: movq %rsi, (%rsp)
|
; CHECK: movq %rsi, (%rsp)
|
||||||
%safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c)
|
%safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c)
|
||||||
%a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 10)
|
%a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 12)
|
||||||
%b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 11)
|
%b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 13)
|
||||||
%c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 12)
|
%c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 14)
|
||||||
; CHECK: callq
|
; CHECK: callq
|
||||||
; This is the key check. There should NOT be any memory moves here
|
; This is the key check. There should NOT be any memory moves here
|
||||||
; CHECK-NOT: movq
|
; CHECK-NOT: movq
|
||||||
%safepoint_token2 = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %c1, i32 addrspace(1)* %b1, i32 addrspace(1)* %a1)
|
%safepoint_token2 = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %c1, i32 addrspace(1)* %b1, i32 addrspace(1)* %a1)
|
||||||
%a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 12)
|
%a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 14)
|
||||||
%b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 11)
|
%b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 13)
|
||||||
%c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 10)
|
%c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 12)
|
||||||
; CHECK: callq
|
; CHECK: callq
|
||||||
ret i32 1
|
ret i32 1
|
||||||
}
|
}
|
||||||
@ -37,17 +37,17 @@ define i32 @reserve_first(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrsp
|
|||||||
; CHECK: movq %rdi, 16(%rsp)
|
; CHECK: movq %rdi, 16(%rsp)
|
||||||
; CHECK: movq %rdx, 8(%rsp)
|
; CHECK: movq %rdx, 8(%rsp)
|
||||||
; CHECK: movq %rsi, (%rsp)
|
; CHECK: movq %rsi, (%rsp)
|
||||||
%safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c)
|
%safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c)
|
||||||
%a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 10)
|
%a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 12)
|
||||||
%b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 11)
|
%b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 13)
|
||||||
%c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 12)
|
%c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 14)
|
||||||
; CHECK: callq
|
; CHECK: callq
|
||||||
; This is the key check. There should NOT be any memory moves here
|
; This is the key check. There should NOT be any memory moves here
|
||||||
; CHECK-NOT: movq
|
; CHECK-NOT: movq
|
||||||
%safepoint_token2 = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 addrspace(1)* %a1, i32 0, i32 addrspace(1)* %c1, i32 0, i32 0, i32 addrspace(1)* %c1, i32 addrspace(1)* %b1, i32 addrspace(1)* %a1)
|
%safepoint_token2 = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 addrspace(1)* %a1, i32 0, i32 addrspace(1)* %c1, i32 0, i32 0, i32 addrspace(1)* %c1, i32 addrspace(1)* %b1, i32 addrspace(1)* %a1)
|
||||||
%a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 12)
|
%a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 14)
|
||||||
%b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 11)
|
%b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 13)
|
||||||
%c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 10)
|
%c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 12)
|
||||||
; CHECK: callq
|
; CHECK: callq
|
||||||
ret i32 1
|
ret i32 1
|
||||||
}
|
}
|
||||||
@ -55,6 +55,6 @@ define i32 @reserve_first(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrsp
|
|||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
|
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
|
|
||||||
attributes #1 = { uwtable }
|
attributes #1 = { uwtable }
|
@ -24,11 +24,11 @@ entry:
|
|||||||
%metadata1 = alloca i32 addrspace(1)*, i32 2, align 8
|
%metadata1 = alloca i32 addrspace(1)*, i32 2, align 8
|
||||||
store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1
|
store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1
|
||||||
%ptr_derived = getelementptr i32, i32 addrspace(1)* %ptr_base, i32 %arg
|
%ptr_derived = getelementptr i32, i32 addrspace(1)* %ptr_base, i32 %arg
|
||||||
%safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null)
|
%safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null)
|
||||||
%call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
%call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
||||||
%a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
|
%a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9)
|
||||||
%b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 8)
|
%b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 10)
|
||||||
%c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9)
|
%c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 11, i32 11)
|
||||||
;
|
;
|
||||||
ret i1 %call1
|
ret i1 %call1
|
||||||
}
|
}
|
||||||
@ -52,17 +52,26 @@ define i1 @test_derived_arg(i32 addrspace(1)* %ptr_base,
|
|||||||
entry:
|
entry:
|
||||||
%metadata1 = alloca i32 addrspace(1)*, i32 2, align 8
|
%metadata1 = alloca i32 addrspace(1)*, i32 2, align 8
|
||||||
store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1
|
store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1
|
||||||
%safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null)
|
%safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null)
|
||||||
%call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
%call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
||||||
%a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
|
%a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9)
|
||||||
%b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 8)
|
%b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 10)
|
||||||
%c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9)
|
%c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 11, i32 11)
|
||||||
;
|
;
|
||||||
ret i1 %call1
|
ret i1 %call1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Simple test case to check that we emit the ID field correctly
|
||||||
|
define i1 @test_id() gc "statepoint-example" {
|
||||||
|
; CHECK-LABEL: test_id
|
||||||
|
entry:
|
||||||
|
%safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 237, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0)
|
||||||
|
%call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
||||||
|
ret i1 %call1
|
||||||
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
|
|
||||||
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
|
||||||
declare i1 @llvm.experimental.gc.result.i1(i32)
|
declare i1 @llvm.experimental.gc.result.i1(i32)
|
||||||
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
|
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
|
||||||
|
|
||||||
@ -73,11 +82,11 @@ declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
|
|||||||
; CHECK-NEXT: .byte 0
|
; CHECK-NEXT: .byte 0
|
||||||
; CHECK-NEXT: .short 0
|
; CHECK-NEXT: .short 0
|
||||||
; Num Functions
|
; Num Functions
|
||||||
; CHECK-NEXT: .long 2
|
; CHECK-NEXT: .long 3
|
||||||
; Num LargeConstants
|
; Num LargeConstants
|
||||||
; CHECK-NEXT: .long 0
|
; CHECK-NEXT: .long 0
|
||||||
; Num Callsites
|
; Num Callsites
|
||||||
; CHECK-NEXT: .long 2
|
; CHECK-NEXT: .long 3
|
||||||
|
|
||||||
; Functions and stack size
|
; Functions and stack size
|
||||||
; CHECK-NEXT: .quad test
|
; CHECK-NEXT: .quad test
|
||||||
@ -91,7 +100,7 @@ declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
|
|||||||
|
|
||||||
; Large Constants
|
; Large Constants
|
||||||
; Statepoint ID only
|
; Statepoint ID only
|
||||||
; CHECK: .quad 2882400000
|
; CHECK: .quad 0
|
||||||
|
|
||||||
; Callsites
|
; Callsites
|
||||||
; Constant arguments
|
; Constant arguments
|
||||||
@ -165,7 +174,7 @@ declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
|
|||||||
|
|
||||||
; Large Constants
|
; Large Constants
|
||||||
; Statepoint ID only
|
; Statepoint ID only
|
||||||
; CHECK: .quad 2882400000
|
; CHECK: .quad 0
|
||||||
|
|
||||||
; Callsites
|
; Callsites
|
||||||
; Constant arguments
|
; Constant arguments
|
||||||
@ -227,3 +236,45 @@ declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
|
|||||||
; CHECK: .short 0
|
; CHECK: .short 0
|
||||||
; CHECK: .short 0
|
; CHECK: .short 0
|
||||||
; CHECK: .align 8
|
; CHECK: .align 8
|
||||||
|
|
||||||
|
; Records for the test_id function:
|
||||||
|
; No large constants
|
||||||
|
|
||||||
|
; The Statepoint ID:
|
||||||
|
; CHECK: .quad 237
|
||||||
|
|
||||||
|
; Instruction Offset
|
||||||
|
; CHECK: .long .Ltmp5-test_id
|
||||||
|
|
||||||
|
; Reserved:
|
||||||
|
; CHECK: .short 0
|
||||||
|
|
||||||
|
; NumLocations:
|
||||||
|
; CHECK: .short 3
|
||||||
|
|
||||||
|
; StkMapRecord[0]:
|
||||||
|
; SmallConstant(0):
|
||||||
|
; CHECK: .byte 4
|
||||||
|
; CHECK: .byte 8
|
||||||
|
; CHECK: .short 0
|
||||||
|
; CHECK: .long 0
|
||||||
|
|
||||||
|
; StkMapRecord[1]:
|
||||||
|
; SmallConstant(0):
|
||||||
|
; CHECK: .byte 4
|
||||||
|
; CHECK: .byte 8
|
||||||
|
; CHECK: .short 0
|
||||||
|
; CHECK: .long 0
|
||||||
|
|
||||||
|
; StkMapRecord[2]:
|
||||||
|
; SmallConstant(0):
|
||||||
|
; CHECK: .byte 4
|
||||||
|
; CHECK: .byte 8
|
||||||
|
; CHECK: .short 0
|
||||||
|
; CHECK: .long 0
|
||||||
|
|
||||||
|
; No padding or LiveOuts
|
||||||
|
; CHECK: .short 0
|
||||||
|
; CHECK: .short 0
|
||||||
|
; CHECK: .align 8
|
||||||
|
|
||||||
|
@ -10,9 +10,9 @@ define i32 @test_sor_basic(i32* %base) gc "statepoint-example" {
|
|||||||
; CHECK: getelementptr i32, i32* %base-new, i32 15
|
; CHECK: getelementptr i32, i32* %base-new, i32 15
|
||||||
entry:
|
entry:
|
||||||
%ptr = getelementptr i32, i32* %base, i32 15
|
%ptr = getelementptr i32, i32* %base, i32 15
|
||||||
%tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
|
%tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
|
||||||
%base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5)
|
%base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7)
|
||||||
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
|
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
|
||||||
%ret = load i32, i32* %ptr-new
|
%ret = load i32, i32* %ptr-new
|
||||||
ret i32 %ret
|
ret i32 %ret
|
||||||
}
|
}
|
||||||
@ -25,10 +25,10 @@ define i32 @test_sor_two_derived(i32* %base) gc "statepoint-example" {
|
|||||||
entry:
|
entry:
|
||||||
%ptr = getelementptr i32, i32* %base, i32 15
|
%ptr = getelementptr i32, i32* %base, i32 15
|
||||||
%ptr2 = getelementptr i32, i32* %base, i32 12
|
%ptr2 = getelementptr i32, i32* %base, i32 12
|
||||||
%tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
|
%tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
|
||||||
%base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5)
|
%base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7)
|
||||||
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
|
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
|
||||||
%ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 7)
|
%ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 9)
|
||||||
%ret = load i32, i32* %ptr-new
|
%ret = load i32, i32* %ptr-new
|
||||||
ret i32 %ret
|
ret i32 %ret
|
||||||
}
|
}
|
||||||
@ -38,9 +38,9 @@ define i32 @test_sor_ooo(i32* %base) gc "statepoint-example" {
|
|||||||
; CHECK: getelementptr i32, i32* %base-new, i32 15
|
; CHECK: getelementptr i32, i32* %base-new, i32 15
|
||||||
entry:
|
entry:
|
||||||
%ptr = getelementptr i32, i32* %base, i32 15
|
%ptr = getelementptr i32, i32* %base, i32 15
|
||||||
%tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
|
%tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
|
||||||
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
|
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
|
||||||
%base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5)
|
%base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7)
|
||||||
%ret = load i32, i32* %ptr-new
|
%ret = load i32, i32* %ptr-new
|
||||||
ret i32 %ret
|
ret i32 %ret
|
||||||
}
|
}
|
||||||
@ -50,9 +50,9 @@ define i32 @test_sor_gep_smallint([3 x i32]* %base) gc "statepoint-example" {
|
|||||||
; CHECK: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 2
|
; CHECK: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 2
|
||||||
entry:
|
entry:
|
||||||
%ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 2
|
%ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 2
|
||||||
%tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
|
%tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
|
||||||
%base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 5, i32 5)
|
%base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 7, i32 7)
|
||||||
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
|
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
|
||||||
%ret = load i32, i32* %ptr-new
|
%ret = load i32, i32* %ptr-new
|
||||||
ret i32 %ret
|
ret i32 %ret
|
||||||
}
|
}
|
||||||
@ -62,27 +62,27 @@ define i32 @test_sor_gep_largeint([3 x i32]* %base) gc "statepoint-example" {
|
|||||||
; CHECK-NOT: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 21
|
; CHECK-NOT: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 21
|
||||||
entry:
|
entry:
|
||||||
%ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 21
|
%ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 21
|
||||||
%tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
|
%tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
|
||||||
%base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 5, i32 5)
|
%base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 7, i32 7)
|
||||||
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
|
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
|
||||||
%ret = load i32, i32* %ptr-new
|
%ret = load i32, i32* %ptr-new
|
||||||
ret i32 %ret
|
ret i32 %ret
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_sor_noop(i32* %base) gc "statepoint-example" {
|
define i32 @test_sor_noop(i32* %base) gc "statepoint-example" {
|
||||||
; CHECK: getelementptr i32, i32* %base, i32 15
|
; CHECK: getelementptr i32, i32* %base, i32 15
|
||||||
; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
|
; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
|
||||||
; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 7)
|
; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 9)
|
||||||
entry:
|
entry:
|
||||||
%ptr = getelementptr i32, i32* %base, i32 15
|
%ptr = getelementptr i32, i32* %base, i32 15
|
||||||
%ptr2 = getelementptr i32, i32* %base, i32 12
|
%ptr2 = getelementptr i32, i32* %base, i32 12
|
||||||
%tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
|
%tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
|
||||||
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
|
%ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
|
||||||
%ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 7)
|
%ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 9)
|
||||||
%ret = load i32, i32* %ptr-new
|
%ret = load i32, i32* %ptr-new
|
||||||
ret i32 %ret
|
ret i32 %ret
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
|
||||||
declare i32* @llvm.experimental.gc.relocate.p0i32(i32, i32, i32)
|
declare i32* @llvm.experimental.gc.relocate.p0i32(i32, i32, i32)
|
||||||
declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32, i32, i32)
|
declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32, i32, i32)
|
||||||
|
@ -6,7 +6,7 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3
|
|||||||
; then the return attribute of gc.relocate is dereferenceable(N).
|
; then the return attribute of gc.relocate is dereferenceable(N).
|
||||||
|
|
||||||
declare zeroext i1 @return_i1()
|
declare zeroext i1 @return_i1()
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
|
||||||
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
|
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
|
||||||
|
|
||||||
define i32 addrspace(1)* @deref(i32 addrspace(1)* dereferenceable(8) %dparam) gc "statepoint-example" {
|
define i32 addrspace(1)* @deref(i32 addrspace(1)* dereferenceable(8) %dparam) gc "statepoint-example" {
|
||||||
@ -15,7 +15,7 @@ define i32 addrspace(1)* @deref(i32 addrspace(1)* dereferenceable(8) %dparam) gc
|
|||||||
; CHECK: call dereferenceable(8)
|
; CHECK: call dereferenceable(8)
|
||||||
entry:
|
entry:
|
||||||
%load = load i32, i32 addrspace(1)* %dparam
|
%load = load i32, i32 addrspace(1)* %dparam
|
||||||
%tok = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
|
%tok = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
|
||||||
%relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 5, i32 5)
|
%relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 7, i32 7)
|
||||||
ret i32 addrspace(1)* %relocate
|
ret i32 addrspace(1)* %relocate
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ declare void @func()
|
|||||||
|
|
||||||
define i1 @test_negative(i32 addrspace(1)* %p) gc "statepoint-example" {
|
define i1 @test_negative(i32 addrspace(1)* %p) gc "statepoint-example" {
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %p)
|
%safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %p)
|
||||||
%pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
|
%pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
|
||||||
%cmp = icmp eq i32 addrspace(1)* %pnew, null
|
%cmp = icmp eq i32 addrspace(1)* %pnew, null
|
||||||
ret i1 %cmp
|
ret i1 %cmp
|
||||||
; CHECK-LABEL: test_negative
|
; CHECK-LABEL: test_negative
|
||||||
@ -18,8 +18,8 @@ entry:
|
|||||||
|
|
||||||
define i1 @test_nonnull(i32 addrspace(1)* nonnull %p) gc "statepoint-example" {
|
define i1 @test_nonnull(i32 addrspace(1)* nonnull %p) gc "statepoint-example" {
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %p)
|
%safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %p)
|
||||||
%pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
|
%pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
|
||||||
%cmp = icmp eq i32 addrspace(1)* %pnew, null
|
%cmp = icmp eq i32 addrspace(1)* %pnew, null
|
||||||
ret i1 %cmp
|
ret i1 %cmp
|
||||||
; CHECK-LABEL: test_nonnull
|
; CHECK-LABEL: test_nonnull
|
||||||
@ -28,8 +28,8 @@ entry:
|
|||||||
|
|
||||||
define i1 @test_null() gc "statepoint-example" {
|
define i1 @test_null() gc "statepoint-example" {
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* null)
|
%safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* null)
|
||||||
%pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
|
%pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
|
||||||
%cmp = icmp eq i32 addrspace(1)* %pnew, null
|
%cmp = icmp eq i32 addrspace(1)* %pnew, null
|
||||||
ret i1 %cmp
|
ret i1 %cmp
|
||||||
; CHECK-LABEL: test_null
|
; CHECK-LABEL: test_null
|
||||||
@ -39,8 +39,8 @@ entry:
|
|||||||
|
|
||||||
define i1 @test_undef() gc "statepoint-example" {
|
define i1 @test_undef() gc "statepoint-example" {
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* undef)
|
%safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* undef)
|
||||||
%pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
|
%pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
|
||||||
%cmp = icmp eq i32 addrspace(1)* %pnew, null
|
%cmp = icmp eq i32 addrspace(1)* %pnew, null
|
||||||
ret i1 %cmp
|
ret i1 %cmp
|
||||||
; CHECK-LABEL: test_undef
|
; CHECK-LABEL: test_undef
|
||||||
@ -48,5 +48,5 @@ entry:
|
|||||||
; CHECK: ret i1 undef
|
; CHECK: ret i1 undef
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
|
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
|
||||||
|
@ -73,7 +73,7 @@ define i1 @test_call_with_result() gc "statepoint-example" {
|
|||||||
; inserted for a function that takes 1 argument.
|
; inserted for a function that takes 1 argument.
|
||||||
; CHECK: gc.statepoint.p0f_isVoidf
|
; CHECK: gc.statepoint.p0f_isVoidf
|
||||||
; CHECK: gc.statepoint.p0f_i1i1f
|
; CHECK: gc.statepoint.p0f_i1i1f
|
||||||
; CHECK: (i1 (i1)* @i1_return_i1, i32 1, i32 0, i1 false, i32 0, i32 0)
|
; CHECK: (i64 2882400000, i32 0, i1 (i1)* @i1_return_i1, i32 1, i32 0, i1 false, i32 0, i32 0)
|
||||||
; CHECK: %call1.2 = call i1 @llvm.experimental.gc.result.i1
|
; CHECK: %call1.2 = call i1 @llvm.experimental.gc.result.i1
|
||||||
entry:
|
entry:
|
||||||
%call1 = tail call i1 (i1) @i1_return_i1(i1 false)
|
%call1 = tail call i1 (i1) @i1_return_i1(i1 false)
|
||||||
|
@ -15,7 +15,7 @@ entry:
|
|||||||
|
|
||||||
loop:
|
loop:
|
||||||
; CHECK-LABEL: loop
|
; CHECK-LABEL: loop
|
||||||
; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo
|
; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo
|
||||||
; CHECK-NOT: statepoint
|
; CHECK-NOT: statepoint
|
||||||
call void @foo()
|
call void @foo()
|
||||||
br label %loop
|
br label %loop
|
||||||
|
@ -20,9 +20,9 @@ merge:
|
|||||||
; CHECK-LABEL: merge:
|
; CHECK-LABEL: merge:
|
||||||
; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %here ], [ %base_obj_y, %there ]
|
; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %here ], [ %base_obj_y, %there ]
|
||||||
%merged_value = phi i64 addrspace(1)* [ %x, %here ], [ %y, %there ]
|
%merged_value = phi i64 addrspace(1)* [ %x, %here ], [ %y, %there ]
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
ret i64 addrspace(1)* %merged_value
|
ret i64 addrspace(1)* %merged_value
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @foo()
|
declare void @foo()
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
@ -30,8 +30,8 @@ false:
|
|||||||
|
|
||||||
merge:
|
merge:
|
||||||
%next = phi i64 addrspace(1)* [ %next_x, %true ], [ %next_y, %false ]
|
%next = phi i64 addrspace(1)* [ %next_x, %true ], [ %next_y, %false ]
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %loop
|
br label %loop
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
@ -19,8 +19,8 @@ loop: ; preds = %loop, %entry
|
|||||||
; CHECK-DAG: [ %next.relocated.casted, %loop ]
|
; CHECK-DAG: [ %next.relocated.casted, %loop ]
|
||||||
%current = phi i64 addrspace(1)* [ %obj, %entry ], [ %next, %loop ]
|
%current = phi i64 addrspace(1)* [ %obj, %entry ], [ %next, %loop ]
|
||||||
%next = getelementptr i64, i64 addrspace(1)* %current, i32 1
|
%next = getelementptr i64, i64 addrspace(1)* %current, i32 1
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %loop
|
br label %loop
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
@ -13,9 +13,9 @@ there:
|
|||||||
|
|
||||||
merge:
|
merge:
|
||||||
%merged_value = phi i64 addrspace(1)* [ %base_obj, %entry ], [ %derived_obj, %there ]
|
%merged_value = phi i64 addrspace(1)* [ %base_obj, %entry ], [ %derived_obj, %there ]
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
ret i64 addrspace(1)* %merged_value
|
ret i64 addrspace(1)* %merged_value
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @foo()
|
declare void @foo()
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
@ -12,9 +12,9 @@ loop:
|
|||||||
%current.i32 = bitcast i64 addrspace(1)* %current to i32 addrspace(1)*
|
%current.i32 = bitcast i64 addrspace(1)* %current to i32 addrspace(1)*
|
||||||
%next.i32 = getelementptr i32, i32 addrspace(1)* %current.i32, i32 1
|
%next.i32 = getelementptr i32, i32 addrspace(1)* %current.i32, i32 1
|
||||||
%next.i64 = bitcast i32 addrspace(1)* %next.i32 to i64 addrspace(1)*
|
%next.i64 = bitcast i32 addrspace(1)* %next.i32 to i64 addrspace(1)*
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %loop
|
br label %loop
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @do_safepoint()
|
declare void @do_safepoint()
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
@ -13,9 +13,9 @@ entry:
|
|||||||
|
|
||||||
loop:
|
loop:
|
||||||
; CHECK: loop:
|
; CHECK: loop:
|
||||||
; CHECK: %safepoint_token1 = call i32 (i64 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 addrspace(1)* ()* @generate_obj, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i3
|
; CHECK: %safepoint_token1 = call i32 (i64, i32, i64 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 0, i32 0, i64 addrspace(1)* ()* @generate_obj, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i3
|
||||||
; CHECK-NEXT: %obj2 = call i64 addrspace(1)* @llvm.experimental.gc.result
|
; CHECK-NEXT: %obj2 = call i64 addrspace(1)* @llvm.experimental.gc.result
|
||||||
%safepoint_token1 = call i32 (i64 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 addrspace(1)* ()* @generate_obj, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token1 = call i32 (i64, i32, i64 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 0, i32 0, i64 addrspace(1)* ()* @generate_obj, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
%obj2 = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32 %safepoint_token1)
|
%obj2 = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32 %safepoint_token1)
|
||||||
switch i32 %condition, label %dest_a [
|
switch i32 %condition, label %dest_a [
|
||||||
i32 0, label %dest_b
|
i32 0, label %dest_b
|
||||||
@ -37,17 +37,17 @@ merge:
|
|||||||
; CHECK: %obj_to_consume = phi i64 addrspace(1)* [ %obj2, %dest_a ], [ null, %dest_b ], [ null, %dest_c ]
|
; CHECK: %obj_to_consume = phi i64 addrspace(1)* [ %obj2, %dest_a ], [ null, %dest_b ], [ null, %dest_c ]
|
||||||
|
|
||||||
%obj_to_consume = phi i64 addrspace(1)* [ %obj2, %dest_a ], [ null, %dest_b ], [ null, %dest_c ]
|
%obj_to_consume = phi i64 addrspace(1)* [ %obj2, %dest_a ], [ null, %dest_b ], [ null, %dest_c ]
|
||||||
%safepoint_token3 = call i32 (void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(void (i64 addrspace(1)*)* @consume_obj, i32 1, i32 0, i64 addrspace(1)* %obj_to_consume, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token3 = call i32 (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 0, i32 0, void (i64 addrspace(1)*)* @consume_obj, i32 1, i32 0, i64 addrspace(1)* %obj_to_consume, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %merge.split
|
br label %merge.split
|
||||||
|
|
||||||
merge.split: ; preds = %merge
|
merge.split: ; preds = %merge
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %loop
|
br label %loop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32) #0
|
declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32) #0
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 addrspace(1)* ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64f(i64, i32, i64 addrspace(1)* ()*, i32, i32, ...)
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(void (i64 addrspace(1)*)*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...)
|
@ -23,9 +23,8 @@ merge:
|
|||||||
; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %base_obj_y, %there ]
|
; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %base_obj_y, %there ]
|
||||||
; CHECK-NEXT: %merged_value = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %y, %there ]
|
; CHECK-NEXT: %merged_value = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %y, %there ]
|
||||||
%merged_value = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %y, %there ]
|
%merged_value = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %y, %there ]
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
ret i64 addrspace(1)* %merged_value
|
ret i64 addrspace(1)* %merged_value
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ merge:
|
|||||||
; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %merge_here ], [ %base_obj_y, %there ]
|
; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %merge_here ], [ %base_obj_y, %there ]
|
||||||
; CHECK-NEXT: %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
|
; CHECK-NEXT: %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
|
||||||
%merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
|
%merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
ret i64 addrspace(1)* %merged_value
|
ret i64 addrspace(1)* %merged_value
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @do_safepoint()
|
declare void @do_safepoint()
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
@ -44,10 +44,9 @@ merge:
|
|||||||
; CHECK: %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
|
; CHECK: %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
|
||||||
%merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
|
%merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
|
||||||
|
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
ret i64 addrspace(1)* %merged_value
|
ret i64 addrspace(1)* %merged_value
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @do_safepoint()
|
declare void @do_safepoint()
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ check_for_null:
|
|||||||
loop_back:
|
loop_back:
|
||||||
%next_element_ptr = getelementptr i64 addrspace(1)*, i64 addrspace(1)* addrspace(1)* %current_element_ptr, i32 1
|
%next_element_ptr = getelementptr i64 addrspace(1)*, i64 addrspace(1)* addrspace(1)* %current_element_ptr, i32 1
|
||||||
%next_index = add i32 %index, 1
|
%next_index = add i32 %index, 1
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %loop_check
|
br label %loop_check
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
@ -35,4 +35,4 @@ found:
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare void @do_safepoint()
|
declare void @do_safepoint()
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
@ -13,9 +13,9 @@ loop:
|
|||||||
%condition = call i1 @runtime_value()
|
%condition = call i1 @runtime_value()
|
||||||
%maybe_next = getelementptr i64, i64 addrspace(1)* %current, i32 1
|
%maybe_next = getelementptr i64, i64 addrspace(1)* %current, i32 1
|
||||||
%next = select i1 %condition, i64 addrspace(1)* %maybe_next, i64 addrspace(1)* %current
|
%next = select i1 %condition, i64 addrspace(1)* %maybe_next, i64 addrspace(1)* %current
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %loop
|
br label %loop
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @do_safepoint()
|
declare void @do_safepoint()
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
@ -16,7 +16,7 @@ loop:
|
|||||||
; CHECK-DAG: [ %obj.relocated.casted, %loop ]
|
; CHECK-DAG: [ %obj.relocated.casted, %loop ]
|
||||||
; CHECK-DAG: [ %obj, %entry ]
|
; CHECK-DAG: [ %obj, %entry ]
|
||||||
call void @use_obj(i64 addrspace(1)* %obj)
|
call void @use_obj(i64 addrspace(1)* %obj)
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %loop
|
br label %loop
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ define i64 addrspace(1)* @test1(i32 %caller, i8 addrspace(1)* %a, i8 addrspace(1
|
|||||||
; CHECK: merge:
|
; CHECK: merge:
|
||||||
; CHECK-NEXT: %base_phi = phi i64 addrspace(1)* [ [[CAST_L]], %left ], [ [[CAST_L]], %left ], [ [[CAST_L]], %left ], [ [[CAST_R]], %right ], !is_base_value !0
|
; CHECK-NEXT: %base_phi = phi i64 addrspace(1)* [ [[CAST_L]], %left ], [ [[CAST_L]], %left ], [ [[CAST_L]], %left ], [ [[CAST_R]], %right ], !is_base_value !0
|
||||||
%value = phi i64 addrspace(1)* [ %a.cast, %left], [ %a.cast, %left], [ %a.cast, %left], [ %b.cast, %right]
|
%value = phi i64 addrspace(1)* [ %a.cast, %left], [ %a.cast, %left], [ %a.cast, %left], [ %b.cast, %right]
|
||||||
%safepoint_token = call i32 (void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(void (i64 addrspace(1)*)* @parse_point, i32 1, i32 0, i64 addrspace(1)* %value, i32 0, i32 5, i32 0, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 0, i32 0, void (i64 addrspace(1)*)* @parse_point, i32 1, i32 0, i64 addrspace(1)* %value, i32 0, i32 5, i32 0, i32 0, i32 0, i32 0, i32 0)
|
||||||
|
|
||||||
ret i64 addrspace(1)* %value
|
ret i64 addrspace(1)* %value
|
||||||
}
|
}
|
||||||
@ -91,10 +91,10 @@ loop: ; preds = %loop, %entry
|
|||||||
%nexta = getelementptr i64, i64 addrspace(1)* %current, i32 1
|
%nexta = getelementptr i64, i64 addrspace(1)* %current, i32 1
|
||||||
%next = select i1 %cnd, i64 addrspace(1)* %nexta, i64 addrspace(1)* %base_arg2
|
%next = select i1 %cnd, i64 addrspace(1)* %nexta, i64 addrspace(1)* %base_arg2
|
||||||
%extra2 = select i1 %cnd, i64 addrspace(1)* %nexta, i64 addrspace(1)* %base_arg2
|
%extra2 = select i1 %cnd, i64 addrspace(1)* %nexta, i64 addrspace(1)* %base_arg2
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %loop
|
br label %loop
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @foo()
|
declare void @foo()
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(void (i64 addrspace(1)*)*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...)
|
@ -10,7 +10,7 @@ define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj) gc "statepoint-example" {
|
|||||||
; CHECK-NEXT: gc.statepoint
|
; CHECK-NEXT: gc.statepoint
|
||||||
; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
||||||
entry:
|
entry:
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
ret i8 addrspace(1)* %obj
|
ret i8 addrspace(1)* %obj
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,8 +23,8 @@ define i8 addrspace(1)* @test2(i8 addrspace(1)* %obj) gc "statepoint-example" {
|
|||||||
; CHECK-NEXT: gc.statepoint
|
; CHECK-NEXT: gc.statepoint
|
||||||
; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
|
; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
|
||||||
entry:
|
entry:
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
ret i8 addrspace(1)* %obj
|
ret i8 addrspace(1)* %obj
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ define i8 @test3(i8 addrspace(1)* %obj) gc "statepoint-example" {
|
|||||||
; CHECK-NEXT: load i8, i8 addrspace(1)* %obj.relocated
|
; CHECK-NEXT: load i8, i8 addrspace(1)* %obj.relocated
|
||||||
entry:
|
entry:
|
||||||
%derived = getelementptr i8, i8 addrspace(1)* %obj, i64 10
|
%derived = getelementptr i8, i8 addrspace(1)* %obj, i64 10
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
|
|
||||||
%a = load i8, i8 addrspace(1)* %derived
|
%a = load i8, i8 addrspace(1)* %derived
|
||||||
%b = load i8, i8 addrspace(1)* %obj
|
%b = load i8, i8 addrspace(1)* %obj
|
||||||
@ -57,14 +57,14 @@ taken:
|
|||||||
; CHECK-LABEL: taken:
|
; CHECK-LABEL: taken:
|
||||||
; CHECK-NEXT: gc.statepoint
|
; CHECK-NEXT: gc.statepoint
|
||||||
; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %merge
|
br label %merge
|
||||||
|
|
||||||
untaken:
|
untaken:
|
||||||
; CHECK-LABEL: untaken:
|
; CHECK-LABEL: untaken:
|
||||||
; CHECK-NEXT: gc.statepoint
|
; CHECK-NEXT: gc.statepoint
|
||||||
; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
|
; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %merge
|
br label %merge
|
||||||
|
|
||||||
merge:
|
merge:
|
||||||
@ -81,8 +81,8 @@ define i8 addrspace(1)* @test5(i8 addrspace(1)* %obj) gc "ocaml" {
|
|||||||
; CHECK-NEXT: gc.statepoint
|
; CHECK-NEXT: gc.statepoint
|
||||||
; CHECK-NOT: %obj.relocated = call coldcc i8 addrspace(1)*
|
; CHECK-NOT: %obj.relocated = call coldcc i8 addrspace(1)*
|
||||||
entry:
|
entry:
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
ret i8 addrspace(1)* %obj
|
ret i8 addrspace(1)* %obj
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
@ -1,7 +1,7 @@
|
|||||||
; RUN: opt -S -rewrite-statepoints-for-gc %s | FileCheck %s
|
; RUN: opt -S -rewrite-statepoints-for-gc %s | FileCheck %s
|
||||||
|
|
||||||
declare void @foo()
|
declare void @foo()
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
|
|
||||||
; constants don't get relocated.
|
; constants don't get relocated.
|
||||||
define i8 @test() gc "statepoint-example" {
|
define i8 @test() gc "statepoint-example" {
|
||||||
@ -9,7 +9,7 @@ define i8 @test() gc "statepoint-example" {
|
|||||||
; CHECK: gc.statepoint
|
; CHECK: gc.statepoint
|
||||||
; CHECK-NEXT: load i8, i8 addrspace(1)* inttoptr (i64 15 to i8 addrspace(1)*)
|
; CHECK-NEXT: load i8, i8 addrspace(1)* inttoptr (i64 15 to i8 addrspace(1)*)
|
||||||
entry:
|
entry:
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
%res = load i8, i8 addrspace(1)* inttoptr (i64 15 to i8 addrspace(1)*)
|
%res = load i8, i8 addrspace(1)* inttoptr (i64 15 to i8 addrspace(1)*)
|
||||||
ret i8 %res
|
ret i8 %res
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ define i8 @test2(i8 addrspace(1)* %p) gc "statepoint-example" {
|
|||||||
; CHECK-NEXT: gc.relocate
|
; CHECK-NEXT: gc.relocate
|
||||||
; CHECK-NEXT: icmp
|
; CHECK-NEXT: icmp
|
||||||
entry:
|
entry:
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
%cmp = icmp eq i8 addrspace(1)* %p, null
|
%cmp = icmp eq i8 addrspace(1)* %p, null
|
||||||
br i1 %cmp, label %taken, label %not_taken
|
br i1 %cmp, label %taken, label %not_taken
|
||||||
|
|
||||||
@ -52,10 +52,9 @@ define i8 @test3(i1 %always_true) gc "statepoint-example" {
|
|||||||
; CHECK: gc.statepoint
|
; CHECK: gc.statepoint
|
||||||
; CHECK-NEXT: load i8, i8 addrspace(1)* @G
|
; CHECK-NEXT: load i8, i8 addrspace(1)* @G
|
||||||
entry:
|
entry:
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
%res = load i8, i8 addrspace(1)* @G, align 1
|
%res = load i8, i8 addrspace(1)* @G, align 1
|
||||||
ret i8 %res
|
ret i8 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
declare void @foo()
|
declare void @foo()
|
||||||
declare void @use(...)
|
declare void @use(...)
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
|
|
||||||
define void @test1(<2 x i32 addrspace(1)*> addrspace(1)* %obj) gc "statepoint-example" {
|
define void @test1(<2 x i32 addrspace(1)*> addrspace(1)* %obj) gc "statepoint-example" {
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
; CHECK: %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 5, i32 5)
|
; CHECK: %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 7, i32 7)
|
||||||
; CHECK-NEXT: %obj.relocated.casted = bitcast i8 addrspace(1)* %obj.relocated to <2 x i32 addrspace(1)*> addrspace(1)*
|
; CHECK-NEXT: %obj.relocated.casted = bitcast i8 addrspace(1)* %obj.relocated to <2 x i32 addrspace(1)*> addrspace(1)*
|
||||||
call void (...) @use(<2 x i32 addrspace(1)*> addrspace(1)* %obj)
|
call void (...) @use(<2 x i32 addrspace(1)*> addrspace(1)* %obj)
|
||||||
ret void
|
ret void
|
||||||
|
@ -10,7 +10,7 @@ define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" {
|
|||||||
; CHECK-NEXT: bitcast
|
; CHECK-NEXT: bitcast
|
||||||
; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated.casted
|
; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated.casted
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
||||||
ret i64 addrspace(1)* %obj
|
ret i64 addrspace(1)* %obj
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ define <2 x i64 addrspace(1)*> @test2(<2 x i64 addrspace(1)*> %obj) gc "statepoi
|
|||||||
; CHECK-NEXT: insertelement
|
; CHECK-NEXT: insertelement
|
||||||
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
|
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
|
||||||
entry:
|
entry:
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
||||||
ret <2 x i64 addrspace(1)*> %obj
|
ret <2 x i64 addrspace(1)*> %obj
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ define <2 x i64 addrspace(1)*> @test3(<2 x i64 addrspace(1)*>* %ptr) gc "statepo
|
|||||||
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
|
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
|
||||||
entry:
|
entry:
|
||||||
%obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
|
%obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
||||||
ret <2 x i64 addrspace(1)*> %obj
|
ret <2 x i64 addrspace(1)*> %obj
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ define <2 x i64 addrspace(1)*> @test4(<2 x i64 addrspace(1)*>* %ptr) gc "statepo
|
|||||||
; CHECK-NEXT: gc.statepoint
|
; CHECK-NEXT: gc.statepoint
|
||||||
entry:
|
entry:
|
||||||
%obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
|
%obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
|
||||||
invoke i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
invoke i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
||||||
to label %normal_return unwind label %exceptional_return
|
to label %normal_return unwind label %exceptional_return
|
||||||
|
|
||||||
; CHECK-LABEL: normal_return:
|
; CHECK-LABEL: normal_return:
|
||||||
@ -112,10 +112,10 @@ define <2 x i64 addrspace(1)*> @test5(i64 addrspace(1)* %p)
|
|||||||
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
|
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
|
||||||
entry:
|
entry:
|
||||||
%vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %p, i32 0
|
%vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %p, i32 0
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
||||||
ret <2 x i64 addrspace(1)*> %vec
|
ret <2 x i64 addrspace(1)*> %vec
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @do_safepoint()
|
declare void @do_safepoint()
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
|
@ -16,7 +16,7 @@ taken:
|
|||||||
; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
||||||
; CHECK-NEXT: bitcast
|
; CHECK-NEXT: bitcast
|
||||||
; CHECK-NEXT: br label %merge
|
; CHECK-NEXT: br label %merge
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
br label %merge
|
br label %merge
|
||||||
|
|
||||||
untaken:
|
untaken:
|
||||||
@ -25,7 +25,7 @@ untaken:
|
|||||||
; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
|
; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
|
||||||
; CHECK-NEXT: bitcast
|
; CHECK-NEXT: bitcast
|
||||||
; CHECK-NEXT: br label %merge
|
; CHECK-NEXT: br label %merge
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
br label %merge
|
br label %merge
|
||||||
|
|
||||||
merge:
|
merge:
|
||||||
@ -42,7 +42,7 @@ entry:
|
|||||||
; CHECK-LABEL: entry:
|
; CHECK-LABEL: entry:
|
||||||
; CHECK-NEXT: gc.statepoint
|
; CHECK-NEXT: gc.statepoint
|
||||||
; CHECK-NEXT: br
|
; CHECK-NEXT: br
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
br i1 %cmp, label %taken, label %untaken
|
br i1 %cmp, label %taken, label %untaken
|
||||||
|
|
||||||
taken:
|
taken:
|
||||||
@ -54,7 +54,7 @@ taken:
|
|||||||
; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated.casted
|
; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated.casted
|
||||||
|
|
||||||
%obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
|
%obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
ret i64 addrspace(1)* %obj
|
ret i64 addrspace(1)* %obj
|
||||||
|
|
||||||
untaken:
|
untaken:
|
||||||
@ -76,16 +76,16 @@ taken:
|
|||||||
; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
||||||
; CHECK-NEXT: bitcast
|
; CHECK-NEXT: bitcast
|
||||||
; CHECK-NEXT: br label %merge
|
; CHECK-NEXT: br label %merge
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
%obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
|
%obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
br label %merge
|
br label %merge
|
||||||
|
|
||||||
untaken:
|
untaken:
|
||||||
; CHECK-LABEL: taken:
|
; CHECK-LABEL: taken:
|
||||||
; CHECK-NEXT: gc.statepoint
|
; CHECK-NEXT: gc.statepoint
|
||||||
; CHECK-NEXT: br label %merge
|
; CHECK-NEXT: br label %merge
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
br label %merge
|
br label %merge
|
||||||
|
|
||||||
merge:
|
merge:
|
||||||
@ -114,9 +114,9 @@ entry:
|
|||||||
; CHECK-NEXT: ret i64 addrspace(1)* %derived.relocated1.casted
|
; CHECK-NEXT: ret i64 addrspace(1)* %derived.relocated1.casted
|
||||||
;
|
;
|
||||||
%derived = getelementptr i64, i64 addrspace(1)* %obj, i64 8
|
%derived = getelementptr i64, i64 addrspace(1)* %obj, i64 8
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
|
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
ret i64 addrspace(1)* %derived
|
ret i64 addrspace(1)* %derived
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ taken:
|
|||||||
; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
||||||
; CHECK-NEXT: bitcast
|
; CHECK-NEXT: bitcast
|
||||||
; CHECK-NEXT: br label %merge
|
; CHECK-NEXT: br label %merge
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
br label %merge
|
br label %merge
|
||||||
|
|
||||||
untaken:
|
untaken:
|
||||||
@ -163,5 +163,4 @@ final:
|
|||||||
|
|
||||||
declare void @foo()
|
declare void @foo()
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ next:
|
|||||||
; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated.casted)
|
; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated.casted)
|
||||||
; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated.casted)
|
; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated.casted)
|
||||||
%obj2 = phi i64 addrspace(1)* [ %obj, %entry ]
|
%obj2 = phi i64 addrspace(1)* [ %obj, %entry ]
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
call void (...) @consume(i64 addrspace(1)* %obj2)
|
call void (...) @consume(i64 addrspace(1)* %obj2)
|
||||||
call void (...) @consume(i64 addrspace(1)* %obj)
|
call void (...) @consume(i64 addrspace(1)* %obj)
|
||||||
ret void
|
ret void
|
||||||
@ -33,7 +33,7 @@ define void @test7() gc "statepoint-example" {
|
|||||||
|
|
||||||
unreached:
|
unreached:
|
||||||
%obj = phi i64 addrspace(1)* [null, %unreached]
|
%obj = phi i64 addrspace(1)* [null, %unreached]
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
call void (...) @consume(i64 addrspace(1)* %obj)
|
call void (...) @consume(i64 addrspace(1)* %obj)
|
||||||
br label %unreached
|
br label %unreached
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ define void @test8() gc "statepoint-example" {
|
|||||||
ret void
|
ret void
|
||||||
|
|
||||||
unreached:
|
unreached:
|
||||||
invoke i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
invoke i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
to label %normal_return unwind label %exceptional_return
|
to label %normal_return unwind label %exceptional_return
|
||||||
|
|
||||||
normal_return: ; preds = %entry
|
normal_return: ; preds = %entry
|
||||||
@ -62,5 +62,4 @@ declare void @foo()
|
|||||||
; Bound the last check-not
|
; Bound the last check-not
|
||||||
; CHECK-LABEL: @foo
|
; CHECK-LABEL: @foo
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
|
|
||||||
|
@ -25,10 +25,9 @@ normal_dest:
|
|||||||
;; CHECK-NEXT: gc.statepoint
|
;; CHECK-NEXT: gc.statepoint
|
||||||
;; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
;; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
|
||||||
;; CHECK-NEXT: bitcast
|
;; CHECK-NEXT: bitcast
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @gc_call, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @gc_call, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
ret i64* addrspace(1)* %obj
|
ret i64* addrspace(1)* %obj
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ entry:
|
|||||||
; CHECK-LABEL: @test1
|
; CHECK-LABEL: @test1
|
||||||
; CHECK-DAG: %obj.relocated
|
; CHECK-DAG: %obj.relocated
|
||||||
; CHECK-DAG: %obj2.relocated
|
; CHECK-DAG: %obj2.relocated
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
br label %joint
|
br label %joint
|
||||||
|
|
||||||
joint:
|
joint:
|
||||||
@ -61,7 +61,7 @@ loop_x:
|
|||||||
br label %loop.backedge
|
br label %loop.backedge
|
||||||
|
|
||||||
loop.backedge:
|
loop.backedge:
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
||||||
br label %loop
|
br label %loop
|
||||||
|
|
||||||
loop_y:
|
loop_y:
|
||||||
@ -79,14 +79,14 @@ if_branch:
|
|||||||
; CHECK-LABEL: if_branch:
|
; CHECK-LABEL: if_branch:
|
||||||
; CHECK: gc.statepoint
|
; CHECK: gc.statepoint
|
||||||
; CHECK: gc.relocate
|
; CHECK: gc.relocate
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
br label %join
|
br label %join
|
||||||
|
|
||||||
else_branch:
|
else_branch:
|
||||||
; CHECK-LABEL: else_branch:
|
; CHECK-LABEL: else_branch:
|
||||||
; CHECK: gc.statepoint
|
; CHECK: gc.statepoint
|
||||||
; CHECK: gc.relocate
|
; CHECK: gc.relocate
|
||||||
%safepoint_token1 = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token1 = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||||
br label %join
|
br label %join
|
||||||
|
|
||||||
join:
|
join:
|
||||||
@ -110,8 +110,8 @@ entry:
|
|||||||
; CHECK-NEXT: gc.relocate
|
; CHECK-NEXT: gc.relocate
|
||||||
; CHECK-NEXT: bitcast
|
; CHECK-NEXT: bitcast
|
||||||
; CHECK-NEXT: gc.statepoint
|
; CHECK-NEXT: gc.statepoint
|
||||||
%safepoint_token = call i32 (void (i64)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi64f(void (i64)* undef, i32 1, i32 0, i64 undef, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void (i64)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi64f(i64 0, i32 0, void (i64)* undef, i32 1, i32 0, i64 undef, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
%safepoint_token1 = call i32 (i32 (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32p1i64f(i32 (i64 addrspace(1)*)* undef, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token1 = call i32 (i64, i32, i32 (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32p1i64f(i64 0, i32 0, i32 (i64 addrspace(1)*)* undef, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,9 +124,9 @@ define void @test4() gc "statepoint-example" {
|
|||||||
; CHECK: gc.statepoint
|
; CHECK: gc.statepoint
|
||||||
; CHECK: gc.relocate
|
; CHECK: gc.relocate
|
||||||
; CHECK: @use(i8 addrspace(1)* %res.relocated)
|
; CHECK: @use(i8 addrspace(1)* %res.relocated)
|
||||||
%safepoint_token2 = tail call i32 (i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
|
%safepoint_token2 = tail call i32 (i64, i32, i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i64 0, i32 0, i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
|
||||||
%res = call i8 addrspace(1)* @llvm.experimental.gc.result.ptr.p1i8(i32 %safepoint_token2)
|
%res = call i8 addrspace(1)* @llvm.experimental.gc.result.ptr.p1i8(i32 %safepoint_token2)
|
||||||
call i32 (i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i64 0, i32 0, i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
|
||||||
call void (...) @use(i8 addrspace(1)* %res)
|
call void (...) @use(i8 addrspace(1)* %res)
|
||||||
unreachable
|
unreachable
|
||||||
}
|
}
|
||||||
@ -136,7 +136,7 @@ define void @test4() gc "statepoint-example" {
|
|||||||
define void @test5(i8 addrspace(1)* %arg) gc "statepoint-example" {
|
define void @test5(i8 addrspace(1)* %arg) gc "statepoint-example" {
|
||||||
; CHECK-LABEL: test5
|
; CHECK-LABEL: test5
|
||||||
entry:
|
entry:
|
||||||
call i32 (i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
|
call i32 (i64, i32, i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i64 0, i32 0, i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
|
||||||
switch i32 undef, label %kill [
|
switch i32 undef, label %kill [
|
||||||
i32 10, label %merge
|
i32 10, label %merge
|
||||||
i32 13, label %merge
|
i32 13, label %merge
|
||||||
@ -170,7 +170,7 @@ do_safepoint:
|
|||||||
; CHECK: arg1.relocated =
|
; CHECK: arg1.relocated =
|
||||||
; CHECK: arg2.relocated =
|
; CHECK: arg2.relocated =
|
||||||
; CHECK: arg3.relocated =
|
; CHECK: arg3.relocated =
|
||||||
call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 3, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2, i8 addrspace(1)* %arg3)
|
call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 3, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2, i8 addrspace(1)* %arg3)
|
||||||
br label %gc.safepoint_poll.exit2
|
br label %gc.safepoint_poll.exit2
|
||||||
|
|
||||||
gc.safepoint_poll.exit2:
|
gc.safepoint_poll.exit2:
|
||||||
@ -209,7 +209,7 @@ outer-inc:
|
|||||||
; CHECK-LABEL: outer-inc:
|
; CHECK-LABEL: outer-inc:
|
||||||
; CHECK: %arg1.relocated
|
; CHECK: %arg1.relocated
|
||||||
; CHECK: %arg2.relocated
|
; CHECK: %arg2.relocated
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 2, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 2, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2)
|
||||||
br label %outer-loop
|
br label %outer-loop
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ inner-loop:
|
|||||||
; CHECK: gc.statepoint
|
; CHECK: gc.statepoint
|
||||||
; CHECK: %arg1.relocated
|
; CHECK: %arg1.relocated
|
||||||
; CHECK: %arg2.relocated
|
; CHECK: %arg2.relocated
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 2, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 2, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2)
|
||||||
br i1 %cmp, label %inner-loop, label %outer-inc
|
br i1 %cmp, label %inner-loop, label %outer-inc
|
||||||
|
|
||||||
outer-inc:
|
outer-inc:
|
||||||
@ -258,7 +258,7 @@ branch2:
|
|||||||
br i1 %condition, label %callbb, label %join2
|
br i1 %condition, label %callbb, label %join2
|
||||||
|
|
||||||
callbb:
|
callbb:
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||||
br label %join
|
br label %join
|
||||||
|
|
||||||
join:
|
join:
|
||||||
@ -285,12 +285,11 @@ join2:
|
|||||||
|
|
||||||
declare void @do_safepoint()
|
declare void @do_safepoint()
|
||||||
|
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_p1i8f(i8 addrspace(1)* ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_p1i8f(i64, i32, i8 addrspace(1)* ()*, i32, i32, ...)
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi64f(void (i64)*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi64f(i64, i32, void (i64)*, i32, i32, ...)
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_i32p1i64f(i32 (i64 addrspace(1)*)*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i32p1i64f(i64, i32, i32 (i64 addrspace(1)*)*, i32, i32, ...)
|
||||||
declare i8 addrspace(1)* @llvm.experimental.gc.result.ptr.p1i8(i32) #3
|
declare i8 addrspace(1)* @llvm.experimental.gc.result.ptr.p1i8(i32) #3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
14
test/Verifier/invalid-patchable-statepoint.ll
Normal file
14
test/Verifier/invalid-patchable-statepoint.ll
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
; RUN: not opt -verify 2>&1 < %s | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK: gc.statepoint must have null as call target if number of patchable bytes is non zero
|
||||||
|
|
||||||
|
define i1 @invalid_patchable_statepoint() gc "statepoint-example" {
|
||||||
|
entry:
|
||||||
|
%safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 3, i1 ()* @func, i32 0, i32 0, i32 0, i32 0)
|
||||||
|
%call1 = call i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
|
||||||
|
ret i1 %call1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
|
||||||
|
declare i1 @llvm.experimental.gc.result.i1(i32)
|
||||||
|
declare i1 @func()
|
@ -5,15 +5,15 @@
|
|||||||
declare zeroext i1 @return0i1()
|
declare zeroext i1 @return0i1()
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f0i1f(i1 ()*, i32, i32, ...) #0
|
declare i32 @llvm.experimental.gc.statepoint.p0f0i1f(i64, i32, i1 ()*, i32, i32, ...) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #0
|
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #0
|
||||||
|
|
||||||
define i32 addrspace(1)* @0(i32 addrspace(1)* %dparam) {
|
define i32 addrspace(1)* @0(i32 addrspace(1)* %dparam) {
|
||||||
%a00 = load i32, i32 addrspace(1)* %dparam
|
%a00 = load i32, i32 addrspace(1)* %dparam
|
||||||
%to0 = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f0i1f(i1 ()* @return0i1, i32 9, i32 0, i2 0, i32 addrspace(1)* %dparam)
|
%to0 = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f0i1f(i64 0, i32 0, i1 ()* @return0i1, i32 9, i32 0, i2 0, i32 addrspace(1)* %dparam)
|
||||||
%relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %to0, i32 0, i32 4)
|
%relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %to0, i32 2, i32 6)
|
||||||
ret i32 addrspace(1)* %relocate
|
ret i32 addrspace(1)* %relocate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,15 +5,14 @@
|
|||||||
declare void @use(...)
|
declare void @use(...)
|
||||||
declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32, i32, i32)
|
declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32, i32, i32)
|
||||||
declare i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32, i32, i32)
|
declare i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32, i32, i32)
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
declare i32 @"personality_function"()
|
declare i32 @"personality_function"()
|
||||||
|
|
||||||
;; Basic usage
|
;; Basic usage
|
||||||
define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg, i32 %val) gc "statepoint-example" {
|
define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg, i32 %val) gc "statepoint-example" {
|
||||||
entry:
|
entry:
|
||||||
%cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)*
|
%cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)*
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 %val, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 %val, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
|
||||||
%reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11)
|
%reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13)
|
||||||
ret i64 addrspace(1)* %reloc
|
ret i64 addrspace(1)* %reloc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,18 +3,18 @@
|
|||||||
declare void @use(...)
|
declare void @use(...)
|
||||||
declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32, i32, i32)
|
declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32, i32, i32)
|
||||||
declare i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32, i32, i32)
|
declare i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32, i32, i32)
|
||||||
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
declare i32 @"personality_function"()
|
declare i32 @"personality_function"()
|
||||||
|
|
||||||
;; Basic usage
|
;; Basic usage
|
||||||
define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg) gc "statepoint-example" {
|
define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg) gc "statepoint-example" {
|
||||||
entry:
|
entry:
|
||||||
%cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)*
|
%cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)*
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
|
||||||
%reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11)
|
%reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13)
|
||||||
;; It is perfectly legal to relocate the same value multiple times...
|
;; It is perfectly legal to relocate the same value multiple times...
|
||||||
%reloc2 = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11)
|
%reloc2 = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13)
|
||||||
%reloc3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 11, i32 10)
|
%reloc3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 13, i32 12)
|
||||||
ret i64 addrspace(1)* %reloc
|
ret i64 addrspace(1)* %reloc
|
||||||
; CHECK-LABEL: test1
|
; CHECK-LABEL: test1
|
||||||
; CHECK: statepoint
|
; CHECK: statepoint
|
||||||
@ -39,8 +39,8 @@ notequal:
|
|||||||
ret void
|
ret void
|
||||||
|
|
||||||
equal:
|
equal:
|
||||||
%safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
|
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
|
||||||
%reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11)
|
%reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13)
|
||||||
call void undef(i64 addrspace(1)* %reloc)
|
call void undef(i64 addrspace(1)* %reloc)
|
||||||
ret void
|
ret void
|
||||||
; CHECK-LABEL: test2
|
; CHECK-LABEL: test2
|
||||||
@ -57,7 +57,7 @@ define i8 addrspace(1)* @test3(i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1) gc
|
|||||||
entry:
|
entry:
|
||||||
; CHECK-LABEL: entry
|
; CHECK-LABEL: entry
|
||||||
; CHECK: statepoint
|
; CHECK: statepoint
|
||||||
%0 = invoke i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1)
|
%0 = invoke i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1)
|
||||||
to label %normal_dest unwind label %exceptional_return
|
to label %normal_dest unwind label %exceptional_return
|
||||||
|
|
||||||
normal_dest:
|
normal_dest:
|
||||||
@ -65,8 +65,8 @@ normal_dest:
|
|||||||
; CHECK: gc.relocate
|
; CHECK: gc.relocate
|
||||||
; CHECK: gc.relocate
|
; CHECK: gc.relocate
|
||||||
; CHECK: ret
|
; CHECK: ret
|
||||||
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 10, i32 10)
|
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 12, i32 12)
|
||||||
%obj1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 10, i32 10)
|
%obj1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 12, i32 12)
|
||||||
ret i8 addrspace(1)* %obj.relocated
|
ret i8 addrspace(1)* %obj.relocated
|
||||||
|
|
||||||
exceptional_return:
|
exceptional_return:
|
||||||
@ -76,8 +76,7 @@ exceptional_return:
|
|||||||
%landing_pad = landingpad { i8*, i32 } personality i32 ()* @"personality_function"
|
%landing_pad = landingpad { i8*, i32 } personality i32 ()* @"personality_function"
|
||||||
cleanup
|
cleanup
|
||||||
%relocate_token = extractvalue { i8*, i32 } %landing_pad, 1
|
%relocate_token = extractvalue { i8*, i32 } %landing_pad, 1
|
||||||
%obj.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 10, i32 10)
|
%obj.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 12, i32 12)
|
||||||
%obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 10, i32 10)
|
%obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 12, i32 12)
|
||||||
ret i8 addrspace(1)* %obj1.relocated1
|
ret i8 addrspace(1)* %obj1.relocated1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user