[PATCH] D56509: [AST] Remove ASTContext from getThisType (NFC)
mikael accepted this revision. mikael added a comment. This revision is now accepted and ready to land. The changes looks good to me. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D56509/new/ https://reviews.llvm.org/D56509 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D55656: [OpenCL] Address space for default class members
mikael marked an inline comment as done. mikael added inline comments. Comment at: lib/Sema/SemaInit.cpp:4539 + if (InitCategory.isPRValue() || InitCategory.isXValue()) +T1Quals.removeAddressSpace(); + This is probably not the correct way to solve this. But it fixes the issues that i get. The code that triggers this issue is found in test/CodeGenOpenCLCXX/addrspace-of-this.cl:47 ``` C c3 = c1 + c2; ``` So the original (InitializedEntity) Entity.getType() looks like: ``` RValueReferenceType 0x717470 '__generic class C &&' `-QualType 0x717458 '__generic class C' __generic `-RecordType 0x717160 'class C' `-CXXRecord 0x7170d0 'C' ``` It might be so that we actually want to qualify the RValueReferenceType rather than the RecordType here. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D55656/new/ https://reviews.llvm.org/D55656 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D55656: [OpenCL] Address space for default class members
mikael created this revision. mikael added reviewers: Anastasia, rjmccall. Herald added subscribers: cfe-commits, yaxunl. - Implicity and explicity defaulted class members - Resolved the FIXMEs in addrspace-of-this.cl Repository: rC Clang https://reviews.llvm.org/D55656 Files: include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaInit.cpp test/CodeGenOpenCLCXX/addrspace-of-this.cl test/CodeGenOpenCLCXX/explicitly-defaulted-methods.cl test/CodeGenOpenCLCXX/implicitly-defaulted-methods.cl Index: test/CodeGenOpenCLCXX/implicitly-defaulted-methods.cl === --- /dev/null +++ test/CodeGenOpenCLCXX/implicitly-defaulted-methods.cl @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 +// expected-no-diagnostics + +// Test implicitly defaulted special member functions and their invocation. +// The 'this' address space is expected to be generic. + +// CHECK-LABEL: _Z3foov +// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %0) + +// CHECK-LABEL: _ZNU3AS41CC1Ev(%class.C addrspace(4)* %this) +// CHECK: %this.addr = alloca %class.C addrspace(4)*, align 4 +// CHECK: store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: call void @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this1) #4 +// CHECK: ret void + +class C { +public: + int a = 0; +}; + +extern C&& bar(); + +__kernel void foo() { + C c; + C c2(c); + C c3(bar()); + C c5 = bar(); + C c6 = c; + // To force constructors to be CodeGen:ed + int x = c6.a + c.a; +} + Index: test/CodeGenOpenCLCXX/explicitly-defaulted-methods.cl === --- /dev/null +++ test/CodeGenOpenCLCXX/explicitly-defaulted-methods.cl @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s +// expected-no-diagnostics + +// Test explicitly defaulted special member functions and their invocation. +// The 'this' address space is expected to be generic. + +// FIXME: Other address spaces? + +// CHECK-LABEL: _Z3foov +// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %0) + +// CHECK-LABEL: @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this) +// CHECK: %this.addr = alloca %class.C addrspace(4)*, align 4 +// CHECK: store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: ret void + +class C { +public: + C() {} + C(const C &) = default; + C(C &&) = default; + C =(const C &) = default; + C =(C&&) & = default; +}; + +extern C&& bar(); + +__kernel void foo() { + C c; + C c2(c); + C c3(bar()); + C c5 = bar(); + C c6 = c; +} Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl === --- test/CodeGenOpenCLCXX/addrspace-of-this.cl +++ test/CodeGenOpenCLCXX/addrspace-of-this.cl @@ -9,18 +9,21 @@ public: int v; C() { v = 2; } - // FIXME: Does not work yet. - // C(C &) { v = c.v; } + C(C &) { v = c.v; } C(const C ) { v = c.v; } C =(const C ) { v = c.v; return *this; } - // FIXME: Does not work yet. - //C =(C&& c) & { - // v = c.v; - // return *this; - //} + C =(C &) & { +v = c.v; +return *this; + } + + C operator+(const C& c) { +v += c.v; +return *this; + } int get() { return v; } @@ -41,15 +44,13 @@ C c1(c); C c2; c2 = c1; - // FIXME: Does not work yet. - // C c3 = c1 + c2; - // C c4(foo()); - // C c5 = foo(); - + C c3 = c1 + c2; + C c4(foo()); + C c5 = foo(); } // CHECK-LABEL: @__cxx_global_var_init() -// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4 +// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) // Test that the address space is __generic for the constructor // CHECK-LABEL: @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %this) @@ -57,7 +58,7 @@ // CHECK: %this.addr = alloca %class.C addrspace(4)*, align 4 // CHECK: store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4 // CHECK: %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4 -// CHECK: call void @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this1) #4 +// CHECK: call void @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this1) // CHECK: ret void // CHECK-LABEL: @_Z12test__globalv() @@ -74,13 +75,29 @@ // Test the address space of 'this' when invoking a constructor. // CHECK: %1 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* -// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %1)
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael added a comment. Seems like my this commit broke: http://lab.llvm.org:8011/builders/lldb-x86_64-ubuntu-14.04-buildserver/builds/33176 But since I don't really know what anything about lldb, I probably won't be able to fix it fast enough. /lldb-buildbot/buildServerSlave/lldb-android-buildserver/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp:2208:24: error: no viable overloaded '=' proto_info.TypeQuals = type_quals; ^ ~~ /lldb-buildbot/buildServerSlave/lldb-android-buildserver/llvm/tools/clang/include/clang/AST/Type.h:141:7: note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'unsigned int' to 'const clang::Qualifiers' for 1st argument class Qualifiers { ^ /lldb-buildbot/buildServerSlave/lldb-android-buildserver/llvm/tools/clang/include/clang/AST/Type.h:141:7: note: candidate function (the implicit move assignment operator) not viable: no known conversion from 'unsigned int' to 'clang::Qualifiers' for 1st argument 1 error generated. I think it can be easily solved by Qualifiers::fromFastMask(type_quals); also updating the variable name since it changed. But I know nothing about lldb, so I better revert this patch for now. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
This revision was automatically updated to reflect the committed changes. Closed by commit rC348927: [OpenCL] Add generic AS to this pointer (authored by mikael, committed by ). Changed prior to commit: https://reviews.llvm.org/D54862?vs=177477=177846#toc Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 Files: include/clang/AST/CanonicalType.h include/clang/AST/DeclCXX.h include/clang/AST/Type.h include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/ASTDumper.cpp lib/AST/DeclCXX.cpp lib/AST/ItaniumMangle.cpp lib/AST/MicrosoftMangle.cpp lib/AST/Type.cpp lib/AST/TypePrinter.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGValue.h lib/Index/USRGeneration.cpp lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseOpenMP.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaLambda.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/SemaType.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/CodeGenOpenCLCXX/addrspace-of-this.cl test/CodeGenOpenCLCXX/template-address-spaces.cl test/SemaOpenCLCXX/address-space-templates.cl tools/libclang/CIndex.cpp Index: lib/Index/USRGeneration.cpp === --- lib/Index/USRGeneration.cpp +++ lib/Index/USRGeneration.cpp @@ -270,7 +270,8 @@ if (const CXXMethodDecl *MD = dyn_cast(D)) { if (MD->isStatic()) Out << 'S'; -if (unsigned quals = MD->getTypeQualifiers()) +// FIXME: OpenCL: Need to consider address spaces +if (unsigned quals = MD->getTypeQualifiers().getCVRUQualifiers()) Out << (char)('0' + quals); switch (MD->getRefQualifier()) { case RQ_None: break; Index: lib/CodeGen/CGClass.cpp === --- lib/CodeGen/CGClass.cpp +++ lib/CodeGen/CGClass.cpp @@ -16,6 +16,7 @@ #include "CGDebugInfo.h" #include "CGRecordLayout.h" #include "CodeGenFunction.h" +#include "TargetInfo.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/EvaluatedExprVisitor.h" @@ -2012,8 +2013,19 @@ bool NewPointerIsChecked) { CallArgList Args; + LangAS SlotAS = E->getType().getAddressSpace(); + QualType ThisType = D->getThisType(getContext()); + LangAS ThisAS = ThisType.getTypePtr()->getPointeeType().getAddressSpace(); + llvm::Value *ThisPtr = This.getPointer(); + if (SlotAS != ThisAS) { +unsigned TargetThisAS = getContext().getTargetAddressSpace(ThisAS); +llvm::Type *NewType = +ThisPtr->getType()->getPointerElementType()->getPointerTo(TargetThisAS); +ThisPtr = getTargetHooks().performAddrSpaceCast(*this, This.getPointer(), +ThisAS, SlotAS, NewType); + } // Push the this ptr. - Args.add(RValue::get(This.getPointer()), D->getThisType(getContext())); + Args.add(RValue::get(ThisPtr), D->getThisType(getContext())); // If this is a trivial constructor, emit a memcpy now before we lose // the alignment information on the argument. Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2617,9 +2617,9 @@ const FunctionProtoType *FPT = Ty->getPointeeType()->getAs(); return DBuilder.createMemberPointerType( - getOrCreateInstanceMethodType(CGM.getContext().getPointerType(QualType( -Ty->getClass(), FPT->getTypeQuals())), -FPT, U), + getOrCreateInstanceMethodType( + CXXMethodDecl::getThisType(FPT, Ty->getMostRecentCXXRecordDecl()), + FPT, U), ClassType, Size, /*Align=*/0, Flags); } Index: lib/CodeGen/CGDeclCXX.cpp === --- lib/CodeGen/CGDeclCXX.cpp +++ lib/CodeGen/CGDeclCXX.cpp @@ -26,7 +26,10 @@ static void EmitDeclInit(CodeGenFunction , const VarDecl , ConstantAddress DeclPtr) { - assert(D.hasGlobalStorage() && "VarDecl must have global storage!"); + assert( + (D.hasGlobalStorage() || + (D.hasLocalStorage() && CGF.getContext().getLangOpts().OpenCLCPlusPlus)) && + "VarDecl must have global or local (in the case of OpenCL) storage!"); assert(!D.getType()->isReferenceType() && "Should not call EmitDeclInit on a reference!"); Index: lib/CodeGen/CGValue.h
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael marked an inline comment as done. mikael added inline comments. Comment at: lib/Sema/SemaType.cpp:5169 +TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator , Scope *S, + const DeclContext *DC) { // Determine the type of the declarator. Not all forms of declarator Anastasia wrote: > Rather than passing `DeclContext` you can get it from the `Declarator` using > `getContext()` method. Declarator::getContext() returns an enumeration DeclaratorContext which is not enough in this case. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael marked an inline comment as done. mikael added inline comments. Comment at: test/SemaOpenCLCXX/address-space-templates.cl:7 T f1(); // expected-error{{function type may not be qualified with an address space}} - void f2(T); // expected-error{{parameter may not be qualified with an address space}} + // FIXME: Should only get the error message once. + void f2(T); // expected-error{{parameter may not be qualified with an address space}} expected-error{{parameter may not be qualified with an address space}} Anastasia wrote: > mikael wrote: > > This was the remaining issue that I have not solved yet. It looked like > > this issue was not so trivial so I think it makes sense to postpone it. > Do you know why it appears twice? I believe the main issue is that we have some code that does the following in SemaTemplateInstantiateDecl.cpp: ``` OldTL.getAs() ``` But the implementation of getAs returns nullptr if you have local modifiers. So since this code will always return nullptr we end up taking a different paths. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael marked 4 inline comments as done. mikael added inline comments. Comment at: lib/Sema/SemaDecl.cpp:3196 + +QualType AdjustedQT = QualType(AdjustedType, 0); +LangAS AS = Old->getType().getAddressSpace(); When merging the class function and the file context function the address space was lost here. Comment at: lib/Sema/SemaType.cpp:4831 +if (state.getSema().getLangOpts().OpenCLCPlusPlus && +((DC && DC->isRecord()) || + state.getDeclarator().getContext() == The first issue was that if a function is declared outside of a class this code did not deduce it. Now it does. Comment at: lib/Sema/TreeTransform.h:4277 // cv-qualifiers are ignored. - if (T->isFunctionType()) + // OpenCL: The address space should not be ignored. + if (T->isFunctionType()) { Another place where the address space was removed. Comment at: test/SemaOpenCLCXX/address-space-templates.cl:7 T f1(); // expected-error{{function type may not be qualified with an address space}} - void f2(T); // expected-error{{parameter may not be qualified with an address space}} + // FIXME: Should only get the error message once. + void f2(T); // expected-error{{parameter may not be qualified with an address space}} expected-error{{parameter may not be qualified with an address space}} This was the remaining issue that I have not solved yet. It looked like this issue was not so trivial so I think it makes sense to postpone it. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael added a comment. I rebased on Friday, and noticed that I broke two tests: Failing Tests (2): Clang :: CodeGenOpenCLCXX/template-address-spaces.cl Clang :: SemaOpenCLCXX/address-space-templates.cl This upload contains a few extra fixes. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael updated this revision to Diff 177477. mikael marked an inline comment as not done. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 Files: include/clang/AST/CanonicalType.h include/clang/AST/DeclCXX.h include/clang/AST/Type.h include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/ASTDumper.cpp lib/AST/DeclCXX.cpp lib/AST/ItaniumMangle.cpp lib/AST/MicrosoftMangle.cpp lib/AST/Type.cpp lib/AST/TypePrinter.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGValue.h lib/Index/USRGeneration.cpp lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseOpenMP.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaLambda.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/SemaType.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/CodeGenOpenCLCXX/addrspace-of-this.cl test/CodeGenOpenCLCXX/template-address-spaces.cl test/SemaOpenCLCXX/address-space-templates.cl tools/libclang/CIndex.cpp Index: tools/libclang/CIndex.cpp === --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -8370,7 +8370,7 @@ const Decl *D = cxcursor::getCursorDecl(C); const CXXMethodDecl *Method = D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; - return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0; + return (Method && Method->getTypeQualifiers().hasConst()) ? 1 : 0; } unsigned clang_CXXMethod_isDefaulted(CXCursor C) { Index: test/SemaOpenCLCXX/address-space-templates.cl === --- test/SemaOpenCLCXX/address-space-templates.cl +++ test/SemaOpenCLCXX/address-space-templates.cl @@ -4,7 +4,9 @@ struct S { T a;// expected-error{{field may not be qualified with an address space}} T f1(); // expected-error{{function type may not be qualified with an address space}} - void f2(T); // expected-error{{parameter may not be qualified with an address space}} + // FIXME: Should only get the error message once. + void f2(T); // expected-error{{parameter may not be qualified with an address space}} expected-error{{parameter may not be qualified with an address space}} + }; template Index: test/CodeGenOpenCLCXX/template-address-spaces.cl === --- test/CodeGenOpenCLCXX/template-address-spaces.cl +++ test/CodeGenOpenCLCXX/template-address-spaces.cl @@ -9,13 +9,16 @@ template T S::foo() { return a;} -//CHECK: %struct.S = type { i32 } -//CHECK: %struct.S.0 = type { i32 addrspace(4)* } -//CHECK: %struct.S.1 = type { i32 addrspace(1)* } +// CHECK: %struct.S = type { i32 } +// CHECK: %struct.S.0 = type { i32 addrspace(4)* } +// CHECK: %struct.S.1 = type { i32 addrspace(1)* } -//CHECK: i32 @_ZN1SIiE3fooEv(%struct.S* %this) -//CHECK: i32 addrspace(4)* @_ZN1SIPU3AS4iE3fooEv(%struct.S.0* %this) -//CHECK: i32 addrspace(1)* @_ZN1SIPU3AS1iE3fooEv(%struct.S.1* %this) +// CHECK: %0 = addrspacecast %struct.S* %sint to %struct.S addrspace(4)* +// CHECK: %call = call i32 @_ZNU3AS41SIiE3fooEv(%struct.S addrspace(4)* %0) #1 +// CHECK: %1 = addrspacecast %struct.S.0* %sintptr to %struct.S.0 addrspace(4)* +// CHECK: %call1 = call i32 addrspace(4)* @_ZNU3AS41SIPU3AS4iE3fooEv(%struct.S.0 addrspace(4)* %1) #1 +// CHECK: %2 = addrspacecast %struct.S.1* %sintptrgl to %struct.S.1 addrspace(4)* +// CHECK: %call2 = call i32 addrspace(1)* @_ZNU3AS41SIPU3AS1iE3fooEv(%struct.S.1 addrspace(4)* %2) #1 void bar(){ S sint; Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl === --- /dev/null +++ test/CodeGenOpenCLCXX/addrspace-of-this.cl @@ -0,0 +1,154 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s +// expected-no-diagnostics + +// Test that the 'this' pointer is in the __generic address space. + +// FIXME: Add support for __constant address space. + +class C { +public: + int v; + C() { v = 2; } + // FIXME: Does not work yet. + // C(C &) { v = c.v; } + C(const C ) { v = c.v; } + C =(const C ) { +v = c.v; +return *this; + } + // FIXME: Does not work yet. + //C =(C&& c) & { + // v = c.v; + // return *this; + //} + + int get() { return v; } + + int outside(); +}; + +int C::outside() { + return v; +} + +extern C&& foo(); + +__global C c; + +__kernel void test__global() { + int i = c.get(); + int i2 = c.outside(); + C c1(c); + C c2; + c2 = c1; + // FIXME:
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael marked an inline comment as done and an inline comment as not done. mikael added inline comments. Comment at: lib/AST/Type.cpp:2950 + FunctionTypeBits.HasExtQuals = 0; + } } mikael wrote: > rjmccall wrote: > > The indentation here is messed up. > > > > You seem to be mixing up "fast qualifiers" with "CVR qualifiers" in a few > > places. That's currently correct, in the sense that the fast qualifiers > > are currently defined to be the CVR qualifiers, but the point of the > > distinction is that we might want to change that (and we have in fact > > explored that in the past). I think you should make `FunctionTypeBits` > > only claim to store the fast qualifiers, which mostly just means updating a > > few field / accessor names and changing things like the > > `getCVRQualifiers()` call right above this to be `getFastQualifiers()`. > > > > If there are places where it's convenient to assume that the CVR qualifiers > > are exactly the fast qualifiers, it's okay to static_assert that, but you > > should make sure to static_assert it in each place you assume it. > I'll change it, but I do have a question related to this: > > Can we make any assumptions with the "fast qualifiers"? I'd like it if we can > assume that they fit in 3 bits. Otherwise I think I also need an assertion > here. I solved it like this in the end: * I defined the FastTypeQuals to get the size of Qualifiers::FastWidth to make it dependent on possible changes to the fast flags. * Then I put a static_assertion to guard the hastConst(), hasVolatile() and hasRestrict() methods. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael updated this revision to Diff 176943. mikael added a comment. - Added FIXME's. - Fixed the latest comments. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 Files: include/clang/AST/CanonicalType.h include/clang/AST/DeclCXX.h include/clang/AST/Type.h include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/ASTDumper.cpp lib/AST/DeclCXX.cpp lib/AST/ItaniumMangle.cpp lib/AST/MicrosoftMangle.cpp lib/AST/Type.cpp lib/AST/TypePrinter.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGValue.h lib/Index/USRGeneration.cpp lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseOpenMP.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaLambda.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/SemaType.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/CodeGenOpenCLCXX/addrspace-of-this.cl tools/libclang/CIndex.cpp Index: tools/libclang/CIndex.cpp === --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -8370,7 +8370,7 @@ const Decl *D = cxcursor::getCursorDecl(C); const CXXMethodDecl *Method = D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; - return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0; + return (Method && Method->getTypeQualifiers().hasConst()) ? 1 : 0; } unsigned clang_CXXMethod_isDefaulted(CXCursor C) { Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl === --- /dev/null +++ test/CodeGenOpenCLCXX/addrspace-of-this.cl @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s +// expected-no-diagnostics + +// Test that the 'this' pointer is in the __generic address space. + +// FIXME: Add support for __constant address space. + +class C { +public: + int v; + C() { v = 2; } + C(const C ) { v = c.v; } + C =(const C ) { +v = c.v; +return *this; + } + int get() { return v; } +}; + +__global C c; + +__kernel void test__global() { + int i = c.get(); + C c1(c); + C c2; + c2 = c1; +} + +// CHECK-LABEL: @__cxx_global_var_init() +// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4 + +// Test that the address space is __generic for the constructor +// CHECK-LABEL: @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %this) +// CHECK: entry: +// CHECK: %this.addr = alloca %class.C addrspace(4)*, align 4 +// CHECK: store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: call void @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this1) #4 +// CHECK: ret void + +// CHECK-LABEL: @_Z12test__globalv() + +// Test the address space of 'this' when invoking a method. +// CHECK: %call = call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking copy-constructor. +// CHECK: %0 = addrspacecast %class.C* %c1 to %class.C addrspace(4)* +// CHECK: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* %0, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking a constructor. +// CHECK: %1 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %1) #4 + +// Test the address space of 'this' when invoking assignment operator. +// CHECK: %2 = addrspacecast %class.C* %c1 to %class.C addrspace(4)* +// CHECK: %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) %2) + +#define TEST(AS) \ + __kernel void test##AS() { \ +AS C c; \ +int i = c.get(); \ +C c1(c); \ +C c2;\ +c2 = c1; \ + } + +TEST(__local) + +// CHECK-LABEL: _Z11test__localv +// CHECK: @__cxa_guard_acquire + +// Test the address space of 'this' when invoking a method. +// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael marked 3 inline comments as done. mikael added inline comments. Comment at: lib/AST/Type.cpp:2950 + FunctionTypeBits.HasExtQuals = 0; + } } rjmccall wrote: > The indentation here is messed up. > > You seem to be mixing up "fast qualifiers" with "CVR qualifiers" in a few > places. That's currently correct, in the sense that the fast qualifiers are > currently defined to be the CVR qualifiers, but the point of the distinction > is that we might want to change that (and we have in fact explored that in > the past). I think you should make `FunctionTypeBits` only claim to store > the fast qualifiers, which mostly just means updating a few field / accessor > names and changing things like the `getCVRQualifiers()` call right above this > to be `getFastQualifiers()`. > > If there are places where it's convenient to assume that the CVR qualifiers > are exactly the fast qualifiers, it's okay to static_assert that, but you > should make sure to static_assert it in each place you assume it. I'll change it, but I do have a question related to this: Can we make any assumptions with the "fast qualifiers"? I'd like it if we can assume that they fit in 3 bits. Otherwise I think I also need an assertion here. Comment at: lib/CodeGen/CGDebugInfo.cpp:2593 + getOrCreateInstanceMethodType( + CXXMethodDecl::getThisType(FPT, Ty->getMostRecentCXXRecordDecl()), + FPT, U), rjmccall wrote: > Why is this `getMostRecentCXXRecordDecl` instead of `getClass`? Your initial comment suggested to send in a record rather than a type. But I see now that it may make more sense to use the type directly instead. Will update it. Comment at: lib/CodeGen/CGDeclCXX.cpp:32 + (D.hasLocalStorage() && CGF.getContext().getLangOpts().OpenCLCPlusPlus)) && + "VarDecl must have global or local (in the case of OpenCL) storage!"); assert(!D.getType()->isReferenceType() && rjmccall wrote: > What causes OpenCL C++ declarations to go down this path? It goes there when we defined an object in __local address space. From the spec "The constructors of a objects in local memory should only be initialized once". This is the same case as with C++ 11 static local variables. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael marked an inline comment as done. mikael added inline comments. Comment at: lib/AST/ItaniumMangle.cpp:1507 +Qualifiers MethodQuals = Qualifiers::fromCVRUMask( +Method->getTypeQualifiers().getCVRUQualifiers()); // We do not consider restrict a distinguishing attribute for overloading rjmccall wrote: > Anastasia wrote: > > rjmccall wrote: > > > You can overload based on the address space, right? I think it needs to > > > be mangled. > > Does this refer to our earlier discussion > > https://reviews.llvm.org/D54862#inline-484509 > > > > We don't have a way to qualify methods with an address space yet? I was > > going to send an RFC to `cfe-dev` for this but if you think it would be ok > > to go ahead with an implementation, I am happy with it. Either way would it > > be better to do this in a separate patch? > I'm fine with delaying implementation on these two issues until a later patch > since, as you say, they can't be tested well until we support arbitrary > address-space qualifiers. Please at least leave FIXMEs for them. I actually did update this, since we can test the mangling of __generic in the test. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael updated this revision to Diff 176831. mikael added a comment. I uploaded a new patch for most of the comments. I did leave some things out since they need clarification. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 Files: include/clang/AST/CanonicalType.h include/clang/AST/DeclCXX.h include/clang/AST/Type.h include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/ASTDumper.cpp lib/AST/DeclCXX.cpp lib/AST/ItaniumMangle.cpp lib/AST/MicrosoftMangle.cpp lib/AST/Type.cpp lib/AST/TypePrinter.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGValue.h lib/Index/USRGeneration.cpp lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseOpenMP.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaLambda.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/SemaType.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/CodeGenOpenCLCXX/addrspace-of-this.cl tools/libclang/CIndex.cpp Index: tools/libclang/CIndex.cpp === --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -8370,7 +8370,7 @@ const Decl *D = cxcursor::getCursorDecl(C); const CXXMethodDecl *Method = D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; - return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0; + return (Method && Method->getTypeQualifiers().hasConst()) ? 1 : 0; } unsigned clang_CXXMethod_isDefaulted(CXCursor C) { Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl === --- /dev/null +++ test/CodeGenOpenCLCXX/addrspace-of-this.cl @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s +// expected-no-diagnostics + +// Test that the 'this' pointer is in the __generic address space. + +// FIXME: Add support for __constant address space. + +class C { +public: + int v; + C() { v = 2; } + C(const C ) { v = c.v; } + C =(const C ) { +v = c.v; +return *this; + } + int get() { return v; } +}; + +__global C c; + +__kernel void test__global() { + int i = c.get(); + C c1(c); + C c2; + c2 = c1; +} + +// CHECK-LABEL: @__cxx_global_var_init() +// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4 + +// Test that the address space is __generic for the constructor +// CHECK-LABEL: @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %this) +// CHECK: entry: +// CHECK: %this.addr = alloca %class.C addrspace(4)*, align 4 +// CHECK: store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: call void @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this1) #4 +// CHECK: ret void + +// CHECK-LABEL: @_Z12test__globalv() + +// Test the address space of 'this' when invoking a method. +// CHECK: %call = call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking copy-constructor. +// CHECK: %0 = addrspacecast %class.C* %c1 to %class.C addrspace(4)* +// CHECK: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* %0, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking a constructor. +// CHECK: %1 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %1) #4 + +// Test the address space of 'this' when invoking assignment operator. +// CHECK: %2 = addrspacecast %class.C* %c1 to %class.C addrspace(4)* +// CHECK: %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) %2) + +#define TEST(AS) \ + __kernel void test##AS() { \ +AS C c; \ +int i = c.get(); \ +C c1(c); \ +C c2;\ +c2 = c1; \ + } + +TEST(__local) + +// CHECK-LABEL: _Z11test__localv +// CHECK: @__cxa_guard_acquire + +// Test the address space of 'this' when invoking a method. +// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael marked an inline comment as done and an inline comment as not done. mikael added a comment. Thanks for the feedback, I'll work on fixing the issues! Comment at: lib/Sema/SemaOverload.cpp:1146 +unsigned OldQuals = OldMethod->getTypeQualifiers().getCVRUQualifiers(); +unsigned NewQuals = NewMethod->getTypeQualifiers().getCVRUQualifiers(); if (!getLangOpts().CPlusPlus14 && NewMethod->isConstexpr() && rjmccall wrote: > This is an algorithm that I think you need to get right and which shouldn't > drop address spaces. But with this patch we can only have __generic address space for methods. So if I try to implement something here I can't really test it? Or am I missing something? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael marked an inline comment as done. mikael added inline comments. Comment at: lib/Sema/SemaType.cpp:4816 +// OpenCLCPlusPlus: A class member function has an address space. +if (state.getSema().getLangOpts().OpenCLCPlusPlus && +state.getDeclarator().getContext() == Anastasia wrote: > Can this be moved into `deduceOpenCLImplicitAddrSpace`? deduceOpenCLImplicitAddrSpace is only wrapping a type with an address space. I also need to make sure the FunctionProtoType gets generated with the address space. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael updated this revision to Diff 176596. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 Files: include/clang/AST/CanonicalType.h include/clang/AST/DeclCXX.h include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/ASTDumper.cpp lib/AST/DeclCXX.cpp lib/AST/ItaniumMangle.cpp lib/AST/MicrosoftMangle.cpp lib/AST/Type.cpp lib/AST/TypePrinter.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGValue.h lib/Index/USRGeneration.cpp lib/Parse/ParseCXXInlineMethods.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaLambda.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/SemaType.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/CodeGenOpenCLCXX/addrspace-of-this.cl tools/libclang/CIndex.cpp Index: tools/libclang/CIndex.cpp === --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -8370,7 +8370,7 @@ const Decl *D = cxcursor::getCursorDecl(C); const CXXMethodDecl *Method = D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; - return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0; + return (Method && Method->getTypeQualifiers().hasConst()) ? 1 : 0; } unsigned clang_CXXMethod_isDefaulted(CXCursor C) { Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl === --- /dev/null +++ test/CodeGenOpenCLCXX/addrspace-of-this.cl @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s +// expected-no-diagnostics + +// Test that the 'this' pointer is in the __generic address space. + +// FIXME: Add support for __constant address space. + +class C { +public: + int v; + C() { v = 2; } + C(const C ) { v = c.v; } + C =(const C ) { +v = c.v; +return *this; + } + int get() { return v; } +}; + +__global C c; + +__kernel void test__global() { + int i = c.get(); + C c1(c); + C c2; + c2 = c1; +} + +// CHECK-LABEL: @__cxx_global_var_init() +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4 + +// Test that the address space is __generic for the constructor +// CHECK-LABEL: @_ZN1CC1Ev(%class.C addrspace(4)* %this) +// CHECK: entry: +// CHECK: %this.addr = alloca %class.C addrspace(4)*, align 4 +// CHECK: store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: call void @_ZN1CC2Ev(%class.C addrspace(4)* %this1) #4 +// CHECK: ret void + +// CHECK-LABEL: @_Z12test__globalv() + +// Test the address space of 'this' when invoking a method. +// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking copy-constructor. +// CHECK: %0 = addrspacecast %class.C* %c1 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %0, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking a constructor. +// CHECK: %1 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* %1) #4 + +// Test the address space of 'this' when invoking assignment operator. +// CHECK: %2 = addrspacecast %class.C* %c1 to %class.C addrspace(4)* +// CHECK: %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZN1CaSERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) %2) + +#define TEST(AS) \ + __kernel void test##AS() { \ +AS C c; \ +int i = c.get(); \ +C c1(c); \ +C c2;\ +c2 = c1; \ + } + +TEST(__local) + +// CHECK-LABEL: _Z11test__localv +// CHECK: @__cxa_guard_acquire + +// Test the address space of 'this' when invoking a method. +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking copy-constructor. +// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking a constructor. +// CHECK: %3 = addrspacecast %class.C*
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael marked an inline comment as done. mikael added inline comments. Comment at: lib/Sema/SemaOverload.cpp:5254 + if (!Context.hasSameType(From->getType(), DestType)) { +if (From->getType().getAddressSpace() != DestType.getAddressSpace()) + From = ImpCastExprToType(From, DestType, CK_AddressSpaceConversion, Note that this change allowed me to revert some of the CG changes. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael updated this revision to Diff 176063. Herald added subscribers: arphaman, eraman. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 Files: include/clang/AST/DeclCXX.h include/clang/AST/Type.h lib/AST/DeclCXX.cpp lib/AST/ItaniumMangle.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGDeclCXX.cpp lib/Index/USRGeneration.cpp lib/Parse/ParseCXXInlineMethods.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/SemaType.cpp test/CodeGenOpenCLCXX/addrspace-of-this.cl tools/libclang/CIndex.cpp Index: tools/libclang/CIndex.cpp === --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -8370,7 +8370,7 @@ const Decl *D = cxcursor::getCursorDecl(C); const CXXMethodDecl *Method = D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; - return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0; + return (Method && Method->getTypeQualifiers().hasConst()) ? 1 : 0; } unsigned clang_CXXMethod_isDefaulted(CXCursor C) { Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl === --- /dev/null +++ test/CodeGenOpenCLCXX/addrspace-of-this.cl @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s +// expected-no-diagnostics + +// Test that the 'this' pointer is in the __generic address space. + +// FIXME: Add support for __constant address space. + +class C { +public: + int v; + C() { v = 2; } + C(const C ) { v = c.v; } + C =(const C ) { +v = c.v; +return *this; + } + int get() { return v; } +}; + +__global C c; + +__kernel void test__global() { + int i = c.get(); + C c1(c); + C c2; + c2 = c1; +} + +// CHECK-LABEL: @__cxx_global_var_init() +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4 + +// Test that the address space is __generic for the constructor +// CHECK-LABEL: @_ZN1CC1Ev(%class.C addrspace(4)* %this) +// CHECK: entry: +// CHECK: %this.addr = alloca %class.C addrspace(4)*, align 4 +// CHECK: store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: call void @_ZN1CC2Ev(%class.C addrspace(4)* %this1) #4 +// CHECK: ret void + +// CHECK-LABEL: @_Z12test__globalv() + +// Test the address space of 'this' when invoking a method. +// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking copy-constructor. +// CHECK: %0 = addrspacecast %class.C* %c1 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %0, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking a constructor. +// CHECK: %1 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* %1) #4 + +// Test the address space of 'this' when invoking assignment operator. +// CHECK: %2 = addrspacecast %class.C* %c1 to %class.C addrspace(4)* +// CHECK: %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZN1CaSERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) %2) + +#define TEST(AS) \ + __kernel void test##AS() { \ +AS C c; \ +int i = c.get(); \ +C c1(c); \ +C c2;\ +c2 = c1; \ + } + +TEST(__local) + +// CHECK-LABEL: _Z11test__localv +// CHECK: @__cxa_guard_acquire + +// Test the address space of 'this' when invoking a method. +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking copy-constructor. +// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking a constructor. +// CHECK: %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* %3) + +// Test the address space of 'this' when invoking assignment operator. +// CHECK: %4 = addrspacecast %class.C* %c1 to %class.C addrspace(4)* +// CHECK: %5 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: %call1 = call
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael updated this revision to Diff 175646. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 Files: lib/AST/DeclCXX.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CGExprCXX.cpp lib/Sema/SemaType.cpp test/CodeGenOpenCLCXX/addrspace-of-this.cl Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl === --- /dev/null +++ test/CodeGenOpenCLCXX/addrspace-of-this.cl @@ -0,0 +1,140 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s +// expected-no-diagnostics + +// Test that the 'this' pointer is in the __generic address space. + +// FIXME: Add support for __constant address space. + +class C { +public: + int v; + C() { v = 2; } + C(const C ) { v = c.v; } + C =(const C ) { +v = c.v; +return *this; + } + int get() { return v; } +}; + +__global C c; + +__kernel void test__global() { + int i = c.get(); + C c1(c); + C c2; + c2 = c1; +} + +// CHECK-LABEL: @__cxx_global_var_init() +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4 + +// Test that the address space is __generic for the constructor +// CHECK-LABEL: @_ZN1CC1Ev(%class.C addrspace(4)* %this) +// CHECK: entry: +// CHECK: %this.addr = alloca %class.C addrspace(4)*, align 4 +// CHECK: store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: call void @_ZN1CC2Ev(%class.C addrspace(4)* %this1) #4 +// CHECK: ret void + +// CHECK-LABEL: @_Z12test__globalv() + +// Test the address space of 'this' when invoking a method. +// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking copy-constructor. +// CHECK: %0 = addrspacecast %class.C* %c1 to %class.C* addrspace(4)* +// CHECK: %1 = bitcast %class.C* addrspace(4)* %0 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %1, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking a constructor. +// CHECK: %2 = addrspacecast %class.C* %c2 to %class.C* addrspace(4)* +// CHECK: %3 = bitcast %class.C* addrspace(4)* %2 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* %3) #4 + +// Test the address space of 'this' when invoking assignment operator. +// CHECK: %4 = addrspacecast %class.C* %c1 to %class.C addrspace(4)* +// CHECK: %5 = addrspacecast %class.C* %c2 to %class.C* addrspace(4)* +// CHECK: %6 = bitcast %class.C* addrspace(4)* %5 to %class.C addrspace(4)* +// CHECK: %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZN1CaSERU3AS4KS_(%class.C addrspace(4)* %6, %class.C addrspace(4)* dereferenceable(4) %4) + +#define TEST(AS) \ + __kernel void test##AS() { \ +AS C c; \ +int i = c.get(); \ +C c1(c); \ +C c2;\ +c2 = c1; \ + } + +TEST(__local) + +// CHECK-LABEL: _Z11test__localv +// CHECK: @__cxa_guard_acquire + +// Test the address space of 'this' when invoking a method. +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking copy-constructor. +// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking a constructor. +// CHECK: %4 = addrspacecast %class.C* %c2 to %class.C* addrspace(4)* +// CHECK: %5 = bitcast %class.C* addrspace(4)* %4 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* %5) + +// Test the address space of 'this' when invoking assignment operator. +// CHECK: %6 = addrspacecast %class.C* %c1 to %class.C addrspace(4)* +// CHECK: %7 = addrspacecast %class.C* %c2 to %class.C* addrspace(4)* +// CHECK: %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZN1CaSERU3AS4KS_(%class.C addrspace(4)* %8, %class.C addrspace(4)* dereferenceable(4) %6) + +TEST(__private) + +// CHECK-LABEL: @_Z13test__privatev + +// Test the address space of 'this' when invoking a method. +// CHECK: %2 = addrspacecast %class.C* %c to %class.C* addrspace(4)* +// CHECK: %3 = bitcast %class.C* addrspace(4)* %2 to %class.C addrspace(4)* +// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* %3) + +// Test the address space of 'this' when invoking a copy-constructor. +// CHECK: %5 = addrspacecast %class.C* %c to %class.C
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael marked an inline comment as done. mikael added inline comments. Comment at: lib/CodeGen/CGCall.cpp:4035 + V = Builder.CreatePointerBitCastOrAddrSpaceCast(V, DestTy); +} rjmccall wrote: > Always use the `performAddrSpaceConversion` target hook if there's a semantic > address-space conversion required. But really, this doesn't seem like the > right place to be doing this; it ought to happen higher up when we're adding > the `this` argument to the call, either explicitly in IRGen or implicitly by > expecting the object expression to already yield a value in the right address > space. > > I could definitely believe that we don't currently create `CastExpr`s for > simple qualification conversions of the object argument of a C++ method call, > since (ignoring these address-space conversions) they're always trivial. Thanks for the input! It seems like the name `performAddrSpaceConversion` does not exist in the code-base though. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D54862/new/ https://reviews.llvm.org/D54862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer
mikael created this revision. mikael added a reviewer: Anastasia. Herald added subscribers: cfe-commits, yaxunl. Address spaces are cast into generic before invoking the constructor. Repository: rC Clang https://reviews.llvm.org/D54862 Files: lib/AST/DeclCXX.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGDeclCXX.cpp test/CodeGenOpenCLCXX/addrspace-of-this.cl Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl === --- /dev/null +++ test/CodeGenOpenCLCXX/addrspace-of-this.cl @@ -0,0 +1,102 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s +// expected-no-diagnostics + +// Test that the 'this' pointer is in the __generic address space. + +// FIXME: Add support for __constant address space. + +class C { +public: + int v; + C() { v = 2; } + C(const C ) { v = c.v; } + C =(const C ) { +v = c.v; +return *this; + } + int get() { return v; } +}; + +__global C c; + +__kernel void test__global() { + int i = c.get(); + C c2 = c; + C c3(c); +} + +// CHECK-LABEL: @__cxx_global_var_init() +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4 + +// Test that the address space is __generic for the constructor +// CHECK-LABEL: @_ZN1CC1Ev(%class.C addrspace(4)* %this) +// CHECK: entry: +// CHECK: %this.addr = alloca %class.C addrspace(4)*, align 4 +// CHECK: store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4 +// CHECK: call void @_ZN1CC2Ev(%class.C addrspace(4)* %this1) #4 +// CHECK: ret void + +// CHECK-LABEL: @_Z12test__globalv() + +// Test the address space of 'this' when accessing a method. +// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking copy-constructor. +// CHECK: %0 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %0, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +// Test the address space of 'this' when invoking assignment operator. +// CHECK: %1 = addrspacecast %class.C* %c3 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %1, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) + +The following checkers are testing similar things like the __global test but for other address spaces. + +#define TEST(AS) \ + __kernel void test##AS() { \ +AS C c; \ +int i = c.get(); \ +C c2 = c;\ +C c3(c); \ + } + +TEST(__local) + +// CHECK-LABEL: _Z11test__localv +// CHECK: @__cxa_guard_acquire +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*)) +// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*)) +// CHECK: %2 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %2, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*)) +// CHECK: %3 = addrspacecast %class.C* %c3 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*)) + +TEST(__private) + +// CHECK-LABEL: @_Z13test__privatev +// CHECK-NOT: @__cxa_guard_acquire +// CHECK: %0 = addrspacecast %class.C* %c to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* %0) +// CHECK: %1 = addrspacecast %class.C* %c to %class.C addrspace(4)* +// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* %1) +// CHECK: %2 = addrspacecast %class.C* %c to %class.C addrspace(4)* +// CHECK: %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) %2) +// CHECK: %4 = addrspacecast %class.C* %c to %class.C addrspace(4)* +// CHECK: %5 = addrspacecast %class.C* %c3 to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %5, %class.C addrspace(4)* dereferenceable(4) %4) + +TEST() + +// CHECK-LABEL: @_Z4testv() +// CHECK: %0 = addrspacecast %class.C* %c to %class.C addrspace(4)* +// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* %0) +// CHECK: %1 = addrspacecast %class.C* %c to %class.C addrspace(4)* +// CHECK: %call = call i32