[PATCH] D69938: [OpenCL] Use __generic addr space when generating internal representation of lambda
Anastasia Stulova via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 19 07:06:42 PST 2019
Anastasia added a comment.
In D69938#1747735 <https://reviews.llvm.org/D69938#1747735>, @rjmccall wrote:
> > I was already planning to add this. I could look into it next and maybe just a add FIXME in the test for now.
>
> Sure.
>
> > Btw global lambda objects are in `__global` address space in OpenCL.
>
> Just based on being written outside of a function body or in a static-local initializer? I guess it's supportable; you can reasonably allocate global memory for those temporaries.
If I compile this kernel:
auto glambda = [](auto a) { return 1; };
__kernel void foo() {
glambda(1);
}
I will get the following IR:
%class.anon = type { i8 }
@glambda = internal addrspace(1) global %class.anon undef, align 1
; Function Attrs: convergent noinline nounwind optnone
define spir_kernel void @foo() #0 !kernel_arg_addr_space !3 !kernel_arg_access_qual !3 !kernel_arg_type !3 !kernel_arg_base_type !3 !kernel_arg_type_qual !3 {
entry:
%call = call spir_func i32 @"_ZNU3AS43$_0clIiEEDaT_"(%class.anon addrspace(4)* addrspacecast (%class.anon addrspace(1)* @glambda to %class.anon addrspace(4)*), i32 1) #2
ret void
}
; Function Attrs: convergent noinline nounwind optnone
define internal spir_func i32 @"_ZNU3AS43$_0clIiEEDaT_"(%class.anon addrspace(4)* %this, i32 %a) #1 align 2 {
entry:
%this.addr = alloca %class.anon addrspace(4)*, align 4
%a.addr = alloca i32, align 4
store %class.anon addrspace(4)* %this, %class.anon addrspace(4)** %this.addr, align 4
store i32 %a, i32* %a.addr, align 4
%this1 = load %class.anon addrspace(4)*, %class.anon addrspace(4)** %this.addr, align 4
ret i32 1
}
and the AST is:
|-VarDecl 0x55e8d2789500 <test.cl:1:1, col:39> col:6 used glambda '__global (lambda at test.cl:1:16)':'__global (lambda at test.cl:1:16)' cinit
| `-ImplicitCastExpr 0x55e8d278a1f0 <col:16, col:39> '__global (lambda at test.cl:1:16)':'__global (lambda at test.cl:1:16)' <NoOp>
| `-LambdaExpr 0x55e8d2789f90 <col:16, col:39> '(lambda at test.cl:1:16)'
| |-CXXRecordDecl 0x55e8d2789808 <col:16> col:16 implicit class definition
| | |-DefinitionData generic lambda pass_in_registers empty standard_layout trivially_copyable literal can_const_default_init
| | | |-DefaultConstructor defaulted_is_constexpr
| | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
| | | |-MoveConstructor exists simple trivial needs_implicit
| | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
| | | |-MoveAssignment
| | | `-Destructor simple irrelevant trivial
| | |-FunctionTemplateDecl 0x55e8d2789aa8 <<invalid sloc>, col:39> col:16 operator()
| | | |-TemplateTypeParmDecl 0x55e8d27895d8 <col:19> col:19 implicit class depth 0 index 0
| | | |-CXXMethodDecl 0x55e8d27899f8 <col:25, col:39> col:16 constexpr operator() 'auto (auto) const __generic' inline
| | | | |-ParmVarDecl 0x55e8d27896a8 <col:19, col:24> col:24 a 'auto'
| | | | `-CompoundStmt 0x55e8d2789b48 <col:27, col:39>
| | | | `-ReturnStmt 0x55e8d2789b38 <col:29, col:36>
| | | | `-IntegerLiteral 0x55e8d2789b18 <col:36> 'int' 1
| | | `-CXXMethodDecl 0x55e8d27b9750 <col:25, col:39> col:16 used constexpr operator() 'int (int) const __generic' inline
| | | |-TemplateArgument type 'int'
| | | |-ParmVarDecl 0x55e8d27b9608 <col:19, col:24> col:24 a 'int':'int'
| | | `-CompoundStmt 0x55e8d27b9978 <col:27, col:39>
| | | `-ReturnStmt 0x55e8d27b9968 <col:29, col:36>
| | | `-IntegerLiteral 0x55e8d2789b18 <col:36> 'int' 1
| | |-FunctionTemplateDecl 0x55e8d2789e18 <<invalid sloc>, col:39> col:16 implicit operator auto (*)(type-parameter-0-0)
| | | |-TemplateTypeParmDecl 0x55e8d27895d8 <col:19> col:19 implicit class depth 0 index 0
| | | `-CXXConversionDecl 0x55e8d2789d70 <col:16, col:39> col:16 implicit constexpr operator auto (*)(type-parameter-0-0) 'auto (*() const noexcept)(auto)' inline
| | |-FunctionTemplateDecl 0x55e8d2789f20 <<invalid sloc>, col:39> col:16 implicit __invoke
| | | |-TemplateTypeParmDecl 0x55e8d27895d8 <col:19> col:19 implicit class depth 0 index 0
| | | `-CXXMethodDecl 0x55e8d2789e78 <col:16, col:39> col:16 implicit __invoke 'auto (auto)' static inline
| | | `-ParmVarDecl 0x55e8d2789d08 <col:19, col:24> col:24 a 'auto'
| | `-CXXDestructorDecl 0x55e8d2789fc0 <col:16> col:16 implicit referenced ~ 'void () __generic noexcept' inline default trivial
| `-CompoundStmt 0x55e8d2789b48 <col:27, col:39>
| `-ReturnStmt 0x55e8d2789b38 <col:29, col:36>
| `-IntegerLiteral 0x55e8d2789b18 <col:36> 'int' 1
|-CXXRecordDecl 0x55e8d2789808 <col:16> col:16 implicit class definition
| |-DefinitionData generic lambda pass_in_registers empty standard_layout trivially_copyable literal can_const_default_init
| | |-DefaultConstructor defaulted_is_constexpr
| | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
| | |-MoveConstructor exists simple trivial needs_implicit
| | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
| | |-MoveAssignment
| | `-Destructor simple irrelevant trivial
| |-FunctionTemplateDecl 0x55e8d2789aa8 <<invalid sloc>, col:39> col:16 operator()
| | |-TemplateTypeParmDecl 0x55e8d27895d8 <col:19> col:19 implicit class depth 0 index 0
| | |-CXXMethodDecl 0x55e8d27899f8 <col:25, col:39> col:16 constexpr operator() 'auto (auto) const __generic' inline
| | | |-ParmVarDecl 0x55e8d27896a8 <col:19, col:24> col:24 a 'auto'
| | | `-CompoundStmt 0x55e8d2789b48 <col:27, col:39>
| | | `-ReturnStmt 0x55e8d2789b38 <col:29, col:36>
| | | `-IntegerLiteral 0x55e8d2789b18 <col:36> 'int' 1
| | `-CXXMethodDecl 0x55e8d27b9750 <col:25, col:39> col:16 used constexpr operator() 'int (int) const __generic' inline
| | |-TemplateArgument type 'int'
| | |-ParmVarDecl 0x55e8d27b9608 <col:19, col:24> col:24 a 'int':'int'
| | `-CompoundStmt 0x55e8d27b9978 <col:27, col:39>
| | `-ReturnStmt 0x55e8d27b9968 <col:29, col:36>
| | `-IntegerLiteral 0x55e8d2789b18 <col:36> 'int' 1
| |-FunctionTemplateDecl 0x55e8d2789e18 <<invalid sloc>, col:39> col:16 implicit operator auto (*)(type-parameter-0-0)
| | |-TemplateTypeParmDecl 0x55e8d27895d8 <col:19> col:19 implicit class depth 0 index 0
| | `-CXXConversionDecl 0x55e8d2789d70 <col:16, col:39> col:16 implicit constexpr operator auto (*)(type-parameter-0-0) 'auto (*() const noexcept)(auto)' inline
| |-FunctionTemplateDecl 0x55e8d2789f20 <<invalid sloc>, col:39> col:16 implicit __invoke
| | |-TemplateTypeParmDecl 0x55e8d27895d8 <col:19> col:19 implicit class depth 0 index 0
| | `-CXXMethodDecl 0x55e8d2789e78 <col:16, col:39> col:16 implicit __invoke 'auto (auto)' static inline
| | `-ParmVarDecl 0x55e8d2789d08 <col:19, col:24> col:24 a 'auto'
| `-CXXDestructorDecl 0x55e8d2789fc0 <col:16> col:16 implicit referenced ~ 'void () __generic noexcept' inline default trivial
`-FunctionDecl 0x55e8d278a258 <line:2:1, line:11:1> line:2:15 foo 'void ()'
|-CompoundStmt 0x55e8d27b9a98 <col:21, line:11:1>
| `-CXXOperatorCallExpr 0x55e8d27b9a60 <line:4:3, col:12> 'int':'int'
| |-ImplicitCastExpr 0x55e8d27b9a08 <col:10, col:12> 'int (*)(int) const __generic' <FunctionToPointerDecay>
| | `-DeclRefExpr 0x55e8d27b9990 <col:10, col:12> 'int (int) const __generic' lvalue CXXMethod 0x55e8d27b9750 'operator()' 'int (int) const __generic'
| |-ImplicitCastExpr 0x55e8d27b9a48 <col:3> 'const __generic (lambda at test.cl:1:16)' lvalue <AddressSpaceConversion>
| | `-DeclRefExpr 0x55e8d278a338 <col:3> '__global (lambda at test.cl:1:16)':'__global (lambda at test.cl:1:16)' lvalue Var 0x55e8d2789500 'glambda' '__global (lambda at test.cl:1:16)':'__global (lambda at test.cl:1:16)'
| `-IntegerLiteral 0x55e8d278a358 <col:11> 'int' 1
`-OpenCLKernelAttr 0x55e8d278a2f8 <line:2:1>
It seems we don't actually have temporaries.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D69938/new/
https://reviews.llvm.org/D69938
More information about the cfe-commits
mailing list