Skip to content

Commit

Permalink
Merged master:1621c004da7b into amd-gfx:573483bc2f35
Browse files Browse the repository at this point in the history
Local branch amd-gfx 573483b Merged master:43a38dc25173 into amd-gfx:bd3fdd8bf9e9
Remote branch master 1621c00 [Tests] Be consistent w/definition of statepoint-example
  • Loading branch information
Sw authored and Sw committed Aug 15, 2020
2 parents 573483b + 1621c00 commit 5f789c6
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 269 deletions.
12 changes: 1 addition & 11 deletions llvm/docs/Statepoints.rst
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,7 @@ Syntax:
func_type <target>,
i64 <#call args>, i64 <flags>,
... (call parameters),
i64 0, i64 0,
... (gc parameters))
i64 0, i64 0)

Overview:
"""""""""
Expand Down Expand Up @@ -520,15 +519,6 @@ These were originally the length prefixes for 'gc transition parameter' and
entirely replaced with the corresponding operand bundles. In a future
revision, these now redundant arguments will be removed.

The 'gc parameters' arguments contain every pointer to a garbage
collector object which potentially needs to be updated by the garbage
collector. Note that the argument list must explicitly contain a base
pointer for every derived pointer listed. The order of arguments is
unimportant. Unlike the other variable length parameter sets, this
list is not length prefixed. Use of the 'gc parameters' list is
deprecated and will eventually be replaced entirely with the
:ref:`gc-live <ob_gc_live>` operand bundle.

Semantics:
""""""""""

Expand Down
50 changes: 6 additions & 44 deletions llvm/include/llvm/IR/Statepoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class GCStatepointInst : public CallBase {
/// Return an end iterator of the arguments to the underlying call
const_op_iterator actual_arg_end() const {
auto I = actual_arg_begin() + actual_arg_size();
assert((arg_end() - I) >= 0);
assert((arg_end() - I) == 2);
return I;
}
/// range adapter for actual call arguments
Expand All @@ -147,16 +147,12 @@ class GCStatepointInst : public CallBase {
const_op_iterator gc_transition_args_begin() const {
if (auto Opt = getOperandBundle(LLVMContext::OB_gc_transition))
return Opt->Inputs.begin();
auto I = actual_arg_end() + 1;
assert((arg_end() - I) >= 0);
return I;
return arg_end();
}
const_op_iterator gc_transition_args_end() const {
if (auto Opt = getOperandBundle(LLVMContext::OB_gc_transition))
return Opt->Inputs.end();
auto I = gc_transition_args_begin() + getNumDeoptArgs();
assert((arg_end() - I) >= 0);
return I;
return arg_end();
}

/// range adapter for GC transition arguments
Expand All @@ -167,19 +163,12 @@ class GCStatepointInst : public CallBase {
const_op_iterator deopt_begin() const {
if (auto Opt = getOperandBundle(LLVMContext::OB_deopt))
return Opt->Inputs.begin();
// The current format has two length prefix bundles between call args and
// start of gc args. This will be removed in the near future.
uint64_t NumTrans = getNumGCTransitionArgs();
const_op_iterator I = actual_arg_end() + 2 + NumTrans;
assert((arg_end() - I) >= 0);
return I;
return arg_end();
}
const_op_iterator deopt_end() const {
if (auto Opt = getOperandBundle(LLVMContext::OB_deopt))
return Opt->Inputs.end();
auto I = deopt_begin() + getNumDeoptArgs();
assert((arg_end() - I) >= 0);
return I;
return arg_end();
}

/// range adapter for vm state arguments
Expand All @@ -192,30 +181,16 @@ class GCStatepointInst : public CallBase {
const_op_iterator gc_args_begin() const {
if (auto Opt = getOperandBundle(LLVMContext::OB_gc_live))
return Opt->Inputs.begin();

// The current format has two length prefix bundles between call args and
// start of gc args. This will be removed in the near future.
uint64_t NumTrans = getNumGCTransitionArgs();
uint64_t NumDeopt = getNumDeoptArgs();
auto I = actual_arg_end() + 2 + NumTrans + NumDeopt;
assert((arg_end() - I) >= 0);
return I;
return arg_end();
}

/// Return an end iterator for the gc argument range
const_op_iterator gc_args_end() const {
if (auto Opt = getOperandBundle(LLVMContext::OB_gc_live))
return Opt->Inputs.end();

return arg_end();
}

/// Return the operand index at which the gc args begin
unsigned gcArgsStartIdx() const {
assert(!getOperandBundle(LLVMContext::OB_gc_live));
return gc_args_begin() - op_begin();
}

/// range adapter for gc arguments
iterator_range<const_op_iterator> gc_args() const {
return make_range(gc_args_begin(), gc_args_end());
Expand All @@ -236,19 +211,6 @@ class GCStatepointInst : public CallBase {
return GRI;
return nullptr;
}

private:
int getNumGCTransitionArgs() const {
const Value *NumGCTransitionArgs = *actual_arg_end();
return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue();
}

int getNumDeoptArgs() const {
uint64_t NumTrans = getNumGCTransitionArgs();
const_op_iterator trans_end = actual_arg_end() + 1 + NumTrans;
const Value *NumDeoptArgs = *trans_end;
return cast<ConstantInt>(NumDeoptArgs)->getZExtValue();
}
};

/// Common base class for representing values projected from a statepoint.
Expand Down
46 changes: 3 additions & 43 deletions llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2136,10 +2136,9 @@ void Verifier::verifyStatepoint(const CallBase &Call) {
Assert(NumDeoptArgs == 0,
"gc.statepoint w/inline deopt operands is deprecated", Call);

const int ExpectedNumArgs =
7 + NumCallArgs + NumTransitionArgs + NumDeoptArgs;
Assert(ExpectedNumArgs <= (int)Call.arg_size(),
"gc.statepoint too few arguments according to length fields", Call);
const int ExpectedNumArgs = 7 + NumCallArgs;
Assert(ExpectedNumArgs == (int)Call.arg_size(),
"gc.statepoint too many arguments", Call);

// Check that the only uses of this gc.statepoint are gc.result or
// gc.relocate calls which are tied to this statepoint and thus part
Expand Down Expand Up @@ -4803,45 +4802,6 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"gc.relocate: statepoint base index out of bounds", Call);
Assert(DerivedIndex < Opt->Inputs.size(),
"gc.relocate: statepoint derived index out of bounds", Call);
} else {
Assert(BaseIndex < StatepointCall.arg_size(),
"gc.relocate: statepoint base index out of bounds", Call);
Assert(DerivedIndex < StatepointCall.arg_size(),
"gc.relocate: statepoint derived index out of bounds", Call);

// Check that BaseIndex and DerivedIndex fall within the 'gc parameters'
// section of the statepoint's argument.
Assert(StatepointCall.arg_size() > 0,
"gc.statepoint: insufficient arguments");
Assert(isa<ConstantInt>(StatepointCall.getArgOperand(3)),
"gc.statement: number of call arguments must be constant integer");
const uint64_t NumCallArgs =
cast<ConstantInt>(StatepointCall.getArgOperand(3))->getZExtValue();
Assert(StatepointCall.arg_size() > NumCallArgs + 5,
"gc.statepoint: mismatch in number of call arguments");
Assert(isa<ConstantInt>(StatepointCall.getArgOperand(NumCallArgs + 5)),
"gc.statepoint: number of transition arguments must be "
"a constant integer");
const uint64_t NumTransitionArgs =
cast<ConstantInt>(StatepointCall.getArgOperand(NumCallArgs + 5))
->getZExtValue();
const uint64_t DeoptArgsStart = 4 + NumCallArgs + 1 + NumTransitionArgs + 1;
Assert(isa<ConstantInt>(StatepointCall.getArgOperand(DeoptArgsStart)),
"gc.statepoint: number of deoptimization arguments must be "
"a constant integer");
const uint64_t NumDeoptArgs =
cast<ConstantInt>(StatepointCall.getArgOperand(DeoptArgsStart))
->getZExtValue();
const uint64_t GCParamArgsStart = DeoptArgsStart + 1 + NumDeoptArgs;
const uint64_t GCParamArgsEnd = StatepointCall.arg_size();
Assert(GCParamArgsStart <= BaseIndex && BaseIndex < GCParamArgsEnd,
"gc.relocate: statepoint base index doesn't fall within the "
"'gc parameters' section of the statepoint call",
Call);
Assert(GCParamArgsStart <= DerivedIndex && DerivedIndex < GCParamArgsEnd,
"gc.relocate: statepoint derived index doesn't fall within the "
"'gc parameters' section of the statepoint call",
Call);
}

// Relocated value must be either a pointer type or vector-of-pointer type,
Expand Down
80 changes: 40 additions & 40 deletions llvm/test/CodeGen/Generic/overloaded-intrinsic-name.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,75 +12,75 @@
; will serve the purpose.

; function and integer
define i32* @test_iAny(i32* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"(i32* %v)]
%v-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 0)
ret i32* %v-new
define i32 addrspace(1)* @test_iAny(i32 addrspace(1)* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"(i32 addrspace(1)* %v)]
%v-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0)
ret i32 addrspace(1)* %v-new
}

; float
define float* @test_fAny(float* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"(float* %v)]
%v-new = call float* @llvm.experimental.gc.relocate.p0f32(token %tok, i32 0, i32 0)
ret float* %v-new
define float addrspace(1)* @test_fAny(float addrspace(1)* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"(float addrspace(1)* %v)]
%v-new = call float addrspace(1)* @llvm.experimental.gc.relocate.p1f32(token %tok, i32 0, i32 0)
ret float addrspace(1)* %v-new
}

; array of integers
define [3 x i32]* @test_aAny([3 x i32]* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"([3 x i32]* %v)]
%v-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token %tok, i32 0, i32 0)
ret [3 x i32]* %v-new
define [3 x i32] addrspace(1)* @test_aAny([3 x i32] addrspace(1)* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"([3 x i32] addrspace(1)* %v)]
%v-new = call [3 x i32] addrspace(1)* @llvm.experimental.gc.relocate.p1a3i32(token %tok, i32 0, i32 0)
ret [3 x i32] addrspace(1)* %v-new
}

; vector of integers
define <3 x i32>* @test_vAny(<3 x i32>* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"(<3 x i32>* %v)]
%v-new = call <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(token %tok, i32 0, i32 0)
ret <3 x i32>* %v-new
define <3 x i32> addrspace(1)* @test_vAny(<3 x i32> addrspace(1)* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"(<3 x i32> addrspace(1)* %v)]
%v-new = call <3 x i32> addrspace(1)* @llvm.experimental.gc.relocate.p1v3i32(token %tok, i32 0, i32 0)
ret <3 x i32> addrspace(1)* %v-new
}

%struct.test = type { i32, i1 }

; struct
define %struct.test* @test_struct(%struct.test* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"(%struct.test* %v)]
%v-new = call %struct.test* @llvm.experimental.gc.relocate.p0s_struct.tests(token %tok, i32 0, i32 0)
ret %struct.test* %v-new
define %struct.test addrspace(1)* @test_struct(%struct.test addrspace(1)* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"(%struct.test addrspace(1)* %v)]
%v-new = call %struct.test addrspace(1)* @llvm.experimental.gc.relocate.p1s_struct.tests(token %tok, i32 0, i32 0)
ret %struct.test addrspace(1)* %v-new
}

; literal struct with nested literal struct
define {i64, i64, {i64} }* @test_literal_struct({i64, i64, {i64}}* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"({i64, i64, {i64}} *%v)]
%v-new = call {i64, i64, {i64}}* @llvm.experimental.gc.relocate.p0sl_i64i64sl_i64ss.test(token %tok, i32 0, i32 0)
ret {i64, i64, {i64}}* %v-new
define {i64, i64, {i64} } addrspace(1)* @test_literal_struct({i64, i64, {i64}} addrspace(1)* %v) gc "statepoint-example" {
%tok = call token (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) ["gc-live"({i64, i64, {i64}} addrspace(1)* %v)]
%v-new = call {i64, i64, {i64}} addrspace(1)* @llvm.experimental.gc.relocate.p1sl_i64i64sl_i64ss.test(token %tok, i32 0, i32 0)
ret {i64, i64, {i64}} addrspace(1)* %v-new
}
; struct with a horrible name, broken when structs were unprefixed
%i32 = type { i32 }

define %i32* @test_i32_struct(%i32* %v) gc "statepoint-example" {
define %i32 addrspace(1)* @test_i32_struct(%i32 addrspace(1)* %v) gc "statepoint-example" {
entry:
%tok = call token (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) ["gc-live"(%i32* %v)]
%v-new = call %i32* @llvm.experimental.gc.relocate.p0s_i32s(token %tok, i32 0, i32 0)
ret %i32* %v-new
%tok = call token (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) ["gc-live"(%i32 addrspace(1)* %v)]
%v-new = call %i32 addrspace(1)* @llvm.experimental.gc.relocate.p1s_i32s(token %tok, i32 0, i32 0)
ret %i32 addrspace(1)* %v-new
}
; completely broken intrinsic naming due to needing remangling. Just use random naming to test

define %i32* @test_broken_names(%i32* %v) gc "statepoint-example" {
define %i32 addrspace(1)* @test_broken_names(%i32 addrspace(1)* %v) gc "statepoint-example" {
entry:
%tok = call fastcc token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.deadbeef(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(%i32* %v)]
%tok = call fastcc token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.deadbeef(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(%i32 addrspace(1)* %v)]
; Make sure we do not destroy the calling convention when remangling
; CHECK: fastcc
%v-new = call %i32* @llvm.experimental.gc.relocate.beefdead(token %tok, i32 0, i32 0)
ret %i32* %v-new
%v-new = call %i32 addrspace(1)* @llvm.experimental.gc.relocate.beefdead(token %tok, i32 0, i32 0)
ret %i32 addrspace(1)* %v-new
}
declare zeroext i1 @return_i1()
declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
declare i32* @llvm.experimental.gc.relocate.p0i32(token, i32, i32)
declare float* @llvm.experimental.gc.relocate.p0f32(token, i32, i32)
declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token, i32, i32)
declare <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(token, i32, i32)
declare %struct.test* @llvm.experimental.gc.relocate.p0s_struct.tests(token, i32, i32)
declare {i64, i64, {i64}}* @llvm.experimental.gc.relocate.p0sl_i64i64sl_i64ss.test(token, i32, i32)
declare %i32* @llvm.experimental.gc.relocate.p0s_i32s(token, i32, i32)
declare %i32* @llvm.experimental.gc.relocate.beefdead(token, i32, i32)
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32)
declare float addrspace(1)* @llvm.experimental.gc.relocate.p1f32(token, i32, i32)
declare [3 x i32] addrspace(1)* @llvm.experimental.gc.relocate.p1a3i32(token, i32, i32)
declare <3 x i32> addrspace(1)* @llvm.experimental.gc.relocate.p1v3i32(token, i32, i32)
declare %struct.test addrspace(1)* @llvm.experimental.gc.relocate.p1s_struct.tests(token, i32, i32)
declare {i64, i64, {i64}} addrspace(1)* @llvm.experimental.gc.relocate.p1sl_i64i64sl_i64ss.test(token, i32, i32)
declare %i32 addrspace(1)* @llvm.experimental.gc.relocate.p1s_i32s(token, i32, i32)
declare %i32 addrspace(1)* @llvm.experimental.gc.relocate.beefdead(token, i32, i32)
declare token @llvm.experimental.gc.statepoint.deadbeef(i64, i32, i1 ()*, i32, i32, ...)
Loading

0 comments on commit 5f789c6

Please sign in to comment.