Re: [PATCH] D11859: Generating vptr assume loads

2015-08-17 Thread Richard Smith via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

LGTM



Comment at: test/CodeGenCXX/vtable-assume-load.cpp:24
@@ +23,3 @@
+// CHECK1-LABEL: define void @_ZN5test14fooAEv()
+// CHECK1: call void @_ZN5test11AC1Ev(%struct.test1::A*
+// CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}

While you're here, maybe also remove the `%struct.test1::A*` (and likewise 
for the tests below).


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-17 Thread Piotr Padlewski via cfe-commits
Prazek updated this revision to Diff 32363.
Prazek added a comment.

Fix for the PR24479


http://reviews.llvm.org/D11859

Files:
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGen/available-externally-hidden.cpp
  test/CodeGenCXX/ctor-globalopt.cpp
  test/CodeGenCXX/template-instantiation.cpp
  test/CodeGenCXX/thunks.cpp
  test/CodeGenCXX/virtual-base-ctor.cpp
  test/CodeGenCXX/vtable-assume-load.cpp
  test/CodeGenCXX/vtable-available-externally.cpp

Index: test/CodeGenCXX/vtable-available-externally.cpp
===
--- test/CodeGenCXX/vtable-available-externally.cpp
+++ test/CodeGenCXX/vtable-available-externally.cpp
@@ -182,8 +182,8 @@
 namespace Test9 {
 // all virtual functions are outline, so we can assume that it will
 // be generated in translation unit where foo is defined
-// CHECK-TEST9: @_ZTVN5Test91AE = available_externally unnamed_addr constant
-// CHECK-TEST9: @_ZTVN5Test91BE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
@@ -206,39 +206,39 @@
 namespace Test10 {
 
 // because A's key function is defined here, vtable is generated in this TU
-// CHECK-TEST10: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr
-// CHECK-TEST10: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
 inline void D::bar() {}
 
 // because B has outline key function then we can refer to
-// CHECK-TEST10: @_ZTVN6Test101BE = available_externally unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
   void bar();
 };
 
 // C's key function (car) is outline, but C has inline virtual function so we
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally
-// CHECK-TEST10: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
-// CHECK-TEST10: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
 struct E : A {};
 
 void g(A a) {
Index: test/CodeGenCXX/vtable-assume-load.cpp
===
--- /dev/null
+++ test/CodeGenCXX/vtable-assume-load.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions
+
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
+
+namespace test1 {
+
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B : A {
+  virtual void foo();
+};
+
+void g(A *a) { a-foo(); }
+
+// CHECK1-LABEL: define void @_ZN5test14fooAEv()
+// CHECK1: call void @_ZN5test11AC1Ev(%struct.test1::A*
+// CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
+// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %[[CMP]])
+// CHECK1-LABEL: }
+
+void fooA() {
+  A a;
+  g(a);
+}
+
+// CHECK1-LABEL: define void @_ZN5test14fooBEv()
+// CHECK1: call void @_ZN5test11BC1Ev(%struct.test1::B* %{{.*}})
+// CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
+// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %[[CMP]])
+// CHECK1-LABEL: }
+
+void fooB() {
+  B b;
+  g(b);
+}
+// there should not be any assumes in the ctor that calls base ctor
+// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%struct.test1::B*
+// CHECK1-NOT: @llvm.assume(
+// CHECK1-LABEL: }
+}
+namespace test2 {
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B 

Re: [PATCH] D11859: Generating vptr assume loads

2015-08-17 Thread John McCall via cfe-commits
rjmccall added a comment.

Just a couple tweaks and then LGTM.



Comment at: lib/CodeGen/CGClass.cpp:1833
@@ +1832,3 @@
+  // unless we are calling base constructor - we don't want to generating
+  // assumption loads for not completed because vptr may still change.
+  if (CGM.getCodeGenOpts().OptimizationLevel  0 

Please use this comment:

  // Generate vtable assumptions if we're constructing a complete object
  // with a vtable.  We don't do this for base subobjects for two reasons:
  // first, it's incorrect for classes with virtual bases, and second, we're
  // about to overwrite the vptrs anyway.


Comment at: lib/CodeGen/CGClass.cpp:2155
@@ -2122,1 +2154,3 @@
+for (const VPtr Vptr : Vptrs)
+  InitializeVTablePointer(Vptr);
 

Please also skip the call to getVTablePointers when doStructorsInitializeVPtrs, 
thanks.


Comment at: lib/CodeGen/ItaniumCXXABI.cpp:196
@@ +195,3 @@
+
+  bool doStructorsInitilizeVPtrs(const CXXRecordDecl *VTableClass) override {
+return true;

Typo: Initialize.


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-17 Thread Piotr Padlewski via cfe-commits
Prazek updated this revision to Diff 32343.
Prazek marked an inline comment as done.

http://reviews.llvm.org/D11859

Files:
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGen/available-externally-hidden.cpp
  test/CodeGenCXX/ctor-globalopt.cpp
  test/CodeGenCXX/template-instantiation.cpp
  test/CodeGenCXX/thunks.cpp
  test/CodeGenCXX/virtual-base-ctor.cpp
  test/CodeGenCXX/vtable-assume-load.cpp
  test/CodeGenCXX/vtable-available-externally.cpp

Index: test/CodeGenCXX/vtable-available-externally.cpp
===
--- test/CodeGenCXX/vtable-available-externally.cpp
+++ test/CodeGenCXX/vtable-available-externally.cpp
@@ -182,8 +182,8 @@
 namespace Test9 {
 // all virtual functions are outline, so we can assume that it will
 // be generated in translation unit where foo is defined
-// CHECK-TEST9: @_ZTVN5Test91AE = available_externally unnamed_addr constant
-// CHECK-TEST9: @_ZTVN5Test91BE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
@@ -206,39 +206,39 @@
 namespace Test10 {
 
 // because A's key function is defined here, vtable is generated in this TU
-// CHECK-TEST10: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr
-// CHECK-TEST10: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
 inline void D::bar() {}
 
 // because B has outline key function then we can refer to
-// CHECK-TEST10: @_ZTVN6Test101BE = available_externally unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
   void bar();
 };
 
 // C's key function (car) is outline, but C has inline virtual function so we
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally
-// CHECK-TEST10: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
-// CHECK-TEST10: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
 struct E : A {};
 
 void g(A a) {
Index: test/CodeGenCXX/vtable-assume-load.cpp
===
--- /dev/null
+++ test/CodeGenCXX/vtable-assume-load.cpp
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions
+
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
+
+namespace test1 {
+
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B : A {
+  virtual void foo();
+};
+
+void g(A *a) { a-foo(); }
+
+// CHECK1-LABEL: define void @_ZN5test14fooAEv()
+// CHECK1: call void @_ZN5test11AC1Ev(%struct.test1::A* %a)
+// CHECK1: %vtable = load i8**, i8*** %1
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABEL: }
+
+void fooA() {
+  A a;
+  g(a);
+}
+
+// CHECK1-LABEL: define void @_ZN5test14fooBEv()
+// CHECK1: call void @_ZN5test11BC1Ev(%struct.test1::B* %b)
+// CHECK1: %vtable = load i8**, i8*** %1
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABEL: }
+
+void fooB() {
+  B b;
+  g(b);
+}
+// there should not be any assumes in the ctor that calls base ctor
+// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%struct.test1::B* %this)
+// CHECK1-NOT: @llvm.assume(
+// CHECK1-LABEL: }
+}
+namespace test2 {
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B {
+  B();
+  virtual void bar();
+};
+

Re: [PATCH] D11859: Generating vptr assume loads

2015-08-17 Thread Piotr Padlewski via cfe-commits
Prazek marked 3 inline comments as done.
Prazek added a comment.

http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-17 Thread John McCall via cfe-commits
rjmccall added inline comments.


Comment at: lib/CodeGen/CGClass.cpp:1862
@@ +1861,3 @@
+  for (const VPtr Vptr : getVTablePointers(ClassDecl))
+if (CGM.getCXXABI().requiresVPtrInitialization(Vptr))
+  EmitVTableAssumptionLoad(Vptr, This);

No, it only checks whether VTableClass has novtable.  VTableClass is the 
derived class for which we're initializing subobject v-tables, and it's 
invariant during getVTablePointers; that's why it's passed separately from 
BaseSubobject.

And if you think about how novtable works as a language feature, you'll see 
that it has to be that way.  The purpose of novtable is to avoid emitting 
v-tables just for the short-term purposes of construction and destruction.  
It's not supposed to apply when initializing derived classes: eventually, the 
complete object does need all the v-tables to be initialized, or else you'll 
never be able to call virtual methods on it, meaning that it might as well not 
have any.


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-17 Thread Piotr Padlewski via cfe-commits
Prazek marked 3 inline comments as done.


Comment at: lib/CodeGen/CGClass.cpp:1862
@@ +1861,3 @@
+  for (const VPtr Vptr : getVTablePointers(ClassDecl))
+if (CGM.getCXXABI().requiresVPtrInitialization(Vptr))
+  EmitVTableAssumptionLoad(Vptr, This);

rjmccall wrote:
 No, it only checks whether VTableClass has novtable.  VTableClass is the 
 derived class for which we're initializing subobject v-tables, and it's 
 invariant during getVTablePointers; that's why it's passed separately from 
 BaseSubobject.
 
 And if you think about how novtable works as a language feature, you'll see 
 that it has to be that way.  The purpose of novtable is to avoid emitting 
 v-tables just for the short-term purposes of construction and destruction.  
 It's not supposed to apply when initializing derived classes: eventually, the 
 complete object does need all the v-tables to be initialized, or else you'll 
 never be able to call virtual methods on it, meaning that it might as well 
 not have any.
You are right. I changed things like You said - I only named it 
doStructorsInitilizeVPtrs


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-16 Thread Piotr Padlewski via cfe-commits
Prazek added a comment.

In http://reviews.llvm.org/D11859#225025, @rjmccall wrote:

 Mostly LGTM.  Are you going to emit assumptions for vbptrs in a separate 
 patch?


I wasn't planning to. I am focusing now on upgrading GVN for using new 
invariant.barrier metadata.


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-16 Thread John McCall via cfe-commits
rjmccall added a comment.

In http://reviews.llvm.org/D11859#225384, @Prazek wrote:

 In http://reviews.llvm.org/D11859#225025, @rjmccall wrote:

  Mostly LGTM.  Are you going to emit assumptions for vbptrs in a separate 
  patch?


 I wasn't planning to. I am focusing now on upgrading GVN for using new 
 invariant.barrier metadata.


I won't argue with prioritizing Itanium over MS work, if that's your 
motivation, because that's obviously your call to make, and certainly that's 
how I would weigh things if I were doing this work.  If you're interested in 
both, though, I would guess that vbptr assumptions would be particularly 
valuable — constructing objects and immediately converting them to a base class 
is pretty common in a lot of idioms.


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-16 Thread Piotr Padlewski via cfe-commits
Prazek marked an inline comment as done.


Comment at: lib/CodeGen/CGCXXABI.h:352
@@ +351,3 @@
+  isVirtualOffsetNeededForVTableField(CodeGenFunction CGF,
+  const CXXRecordDecl *NearestVBase) = 0;
+

rjmccall wrote:
 This method does not need to be passed a CodeGenFunction, but it should take 
 a complete CodeGenFunction::VPtr, not just this one random field from it.
yep, I thought that there will be problem with placing VPtr class, but I 
haven't noticed that CGCXXAABI includes CodeGenFunction.

CodeGenFunction is required for ItaniumABI 
return NeedsVTTParameter(CGF.CurGD);


Comment at: lib/CodeGen/CGClass.cpp:1862
@@ +1861,3 @@
+  for (const VPtr vptr : getVTablePointers(ClassDecl))
+if (CGM.getCXXABI().canInitializeVPtr(vptr.VTableClass, 
vptr.Base.getBase(),
+  vptr.NearestVBase))

rjmccall wrote:
 As mentioned elsewhere, you can skip this entire loop if 
 doStructorsInitializeVTables returns false.
hmm, I think it is not true. This code checks if each base that we are 
initilizing/generating vptr assumption don't have novtable specifier. If one 
base has it, it doesn't mean that we don't have to do it for other base


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-16 Thread Piotr Padlewski via cfe-commits
Prazek updated this revision to Diff 32262.

http://reviews.llvm.org/D11859

Files:
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGen/available-externally-hidden.cpp
  test/CodeGenCXX/ctor-globalopt.cpp
  test/CodeGenCXX/template-instantiation.cpp
  test/CodeGenCXX/thunks.cpp
  test/CodeGenCXX/virtual-base-ctor.cpp
  test/CodeGenCXX/vtable-assume-load.cpp
  test/CodeGenCXX/vtable-available-externally.cpp

Index: test/CodeGenCXX/vtable-available-externally.cpp
===
--- test/CodeGenCXX/vtable-available-externally.cpp
+++ test/CodeGenCXX/vtable-available-externally.cpp
@@ -182,8 +182,8 @@
 namespace Test9 {
 // all virtual functions are outline, so we can assume that it will
 // be generated in translation unit where foo is defined
-// CHECK-TEST9: @_ZTVN5Test91AE = available_externally unnamed_addr constant
-// CHECK-TEST9: @_ZTVN5Test91BE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
@@ -206,39 +206,39 @@
 namespace Test10 {
 
 // because A's key function is defined here, vtable is generated in this TU
-// CHECK-TEST10: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr
-// CHECK-TEST10: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
 inline void D::bar() {}
 
 // because B has outline key function then we can refer to
-// CHECK-TEST10: @_ZTVN6Test101BE = available_externally unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
   void bar();
 };
 
 // C's key function (car) is outline, but C has inline virtual function so we
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally
-// CHECK-TEST10: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
-// CHECK-TEST10: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
 struct E : A {};
 
 void g(A a) {
Index: test/CodeGenCXX/vtable-assume-load.cpp
===
--- /dev/null
+++ test/CodeGenCXX/vtable-assume-load.cpp
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions
+
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
+
+namespace test1 {
+
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B : A {
+  virtual void foo();
+};
+
+void g(A *a) { a-foo(); }
+
+// CHECK1-LABEL: define void @_ZN5test14fooAEv()
+// CHECK1: call void @_ZN5test11AC1Ev(%struct.test1::A* %a)
+// CHECK1: %vtable = load i8**, i8*** %1
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABEL: }
+
+void fooA() {
+  A a;
+  g(a);
+}
+
+// CHECK1-LABEL: define void @_ZN5test14fooBEv()
+// CHECK1: call void @_ZN5test11BC1Ev(%struct.test1::B* %b)
+// CHECK1: %vtable = load i8**, i8*** %1
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABEL: }
+
+void fooB() {
+  B b;
+  g(b);
+}
+// there should not be any assumes in the ctor that calls base ctor
+// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%struct.test1::B* %this)
+// CHECK1-NOT: @llvm.assume(
+// CHECK1-LABEL: }
+}
+namespace test2 {
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B {
+  B();
+  virtual void bar();
+};
+
+struct C : A, B {
+  C();
+  virtual void 

Re: [PATCH] D11859: Generating vptr assume loads

2015-08-16 Thread Piotr Padlewski via cfe-commits
Prazek updated this revision to Diff 32263.

http://reviews.llvm.org/D11859

Files:
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGen/available-externally-hidden.cpp
  test/CodeGenCXX/ctor-globalopt.cpp
  test/CodeGenCXX/template-instantiation.cpp
  test/CodeGenCXX/thunks.cpp
  test/CodeGenCXX/virtual-base-ctor.cpp
  test/CodeGenCXX/vtable-assume-load.cpp
  test/CodeGenCXX/vtable-available-externally.cpp

Index: test/CodeGenCXX/vtable-available-externally.cpp
===
--- test/CodeGenCXX/vtable-available-externally.cpp
+++ test/CodeGenCXX/vtable-available-externally.cpp
@@ -182,8 +182,8 @@
 namespace Test9 {
 // all virtual functions are outline, so we can assume that it will
 // be generated in translation unit where foo is defined
-// CHECK-TEST9: @_ZTVN5Test91AE = available_externally unnamed_addr constant
-// CHECK-TEST9: @_ZTVN5Test91BE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
@@ -206,39 +206,39 @@
 namespace Test10 {
 
 // because A's key function is defined here, vtable is generated in this TU
-// CHECK-TEST10: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr
-// CHECK-TEST10: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
 inline void D::bar() {}
 
 // because B has outline key function then we can refer to
-// CHECK-TEST10: @_ZTVN6Test101BE = available_externally unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
   void bar();
 };
 
 // C's key function (car) is outline, but C has inline virtual function so we
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally
-// CHECK-TEST10: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
-// CHECK-TEST10: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
 struct E : A {};
 
 void g(A a) {
Index: test/CodeGenCXX/vtable-assume-load.cpp
===
--- /dev/null
+++ test/CodeGenCXX/vtable-assume-load.cpp
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions
+
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
+
+namespace test1 {
+
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B : A {
+  virtual void foo();
+};
+
+void g(A *a) { a-foo(); }
+
+// CHECK1-LABEL: define void @_ZN5test14fooAEv()
+// CHECK1: call void @_ZN5test11AC1Ev(%struct.test1::A* %a)
+// CHECK1: %vtable = load i8**, i8*** %1
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABEL: }
+
+void fooA() {
+  A a;
+  g(a);
+}
+
+// CHECK1-LABEL: define void @_ZN5test14fooBEv()
+// CHECK1: call void @_ZN5test11BC1Ev(%struct.test1::B* %b)
+// CHECK1: %vtable = load i8**, i8*** %1
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABEL: }
+
+void fooB() {
+  B b;
+  g(b);
+}
+// there should not be any assumes in the ctor that calls base ctor
+// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%struct.test1::B* %this)
+// CHECK1-NOT: @llvm.assume(
+// CHECK1-LABEL: }
+}
+namespace test2 {
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B {
+  B();
+  virtual void bar();
+};
+
+struct C : A, B {
+  C();
+  virtual void 

Re: [PATCH] D11859: Generating vptr assume loads

2015-08-15 Thread John McCall via cfe-commits
rjmccall added a comment.

Mostly LGTM.  Are you going to emit assumptions for vbptrs in a separate patch?



Comment at: lib/CodeGen/CGCXXABI.h:349-357
@@ -348,1 +348,11 @@
 
+  /// Checks if ABI requires extra virtual offset for vtable field.
+  virtual bool
+  isVirtualOffsetNeededForVTableField(CodeGenFunction CGF,
+  const CXXRecordDecl *NearestVBase) = 0;
+
+  /// Checks if ABI allows to initilize vptr for given class.
+  virtual bool canInitializeVPtr(const CXXRecordDecl *VTableClass,
+ const CXXRecordDecl *Base,
+ const CXXRecordDecl *NearestVBase) = 0;
+

In contrast, this does not need to be as general as it is, and making it this 
general is actively harmful; just pass the vtable class.

Also, I suggest calling it doStructorsInitializeVTables.


Comment at: lib/CodeGen/CGCXXABI.h:352
@@ +351,3 @@
+  isVirtualOffsetNeededForVTableField(CodeGenFunction CGF,
+  const CXXRecordDecl *NearestVBase) = 0;
+

This method does not need to be passed a CodeGenFunction, but it should take a 
complete CodeGenFunction::VPtr, not just this one random field from it.


Comment at: lib/CodeGen/CGClass.cpp:1862
@@ +1861,3 @@
+  for (const VPtr vptr : getVTablePointers(ClassDecl))
+if (CGM.getCXXABI().canInitializeVPtr(vptr.VTableClass, 
vptr.Base.getBase(),
+  vptr.NearestVBase))

As mentioned elsewhere, you can skip this entire loop if 
doStructorsInitializeVTables returns false.


Comment at: lib/CodeGen/CGClass.cpp:2157
@@ +2156,3 @@
+if (CGM.getCXXABI().canInitializeVPtr(Vptr.VTableClass, 
Vptr.Base.getBase(),
+  Vptr.NearestVBase))
+  InitializeVTablePointer(Vptr);

Please call doStructorsInitializeVTables for RD above the call to 
getVTablePointers and then just skip the rest of the function if it returns 
false.


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-15 Thread David Majnemer via cfe-commits
majnemer added inline comments.


Comment at: test/CodeGenCXX/vtable-assume-load.cpp:40
@@ +39,3 @@
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABLE: }
+

This check line looks misspelled.


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-13 Thread Piotr Padlewski via cfe-commits
Prazek added inline comments.


Comment at: lib/CodeGen/CGClass.cpp:1832
@@ +1831,3 @@
+  // Generate vtable assumptions if we are calling dynamic class ctor
+  // and we are not in another ctor.
+  if (CGM.getCodeGenOpts().OptimizationLevel  0 

hfinkel wrote:
 I think this comment should be a little more verbose. How about this:
 
   // Generate vtable assumptions if we are calling dynamic-class's ctor, 
 except when doing so as part of a derived class's ctor's base-class 
 initialization. Doing so in this latter case would be useless, because the 
 vtable is about to be overwritten by the derived class's vtable.
 
The main point of not calling this function, is because it is useless to have 
assumption loads inside constructor, when they are generated also outside of 
ctor. I guess You could have case when You are not overriding base vptr, and 
You are calling base ctor from dynamic class


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-13 Thread Piotr Padlewski via cfe-commits
Prazek marked 5 inline comments as done.
Prazek added a comment.

http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-13 Thread Piotr Padlewski via cfe-commits
Prazek updated this revision to Diff 32122.
Prazek marked an inline comment as done.

http://reviews.llvm.org/D11859

Files:
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGen/available-externally-hidden.cpp
  test/CodeGenCXX/ctor-globalopt.cpp
  test/CodeGenCXX/template-instantiation.cpp
  test/CodeGenCXX/thunks.cpp
  test/CodeGenCXX/virtual-base-ctor.cpp
  test/CodeGenCXX/vtable-assume-load.cpp
  test/CodeGenCXX/vtable-available-externally.cpp

Index: test/CodeGenCXX/vtable-available-externally.cpp
===
--- test/CodeGenCXX/vtable-available-externally.cpp
+++ test/CodeGenCXX/vtable-available-externally.cpp
@@ -182,8 +182,8 @@
 namespace Test9 {
 // all virtual functions are outline, so we can assume that it will
 // be generated in translation unit where foo is defined
-// CHECK-TEST9: @_ZTVN5Test91AE = available_externally unnamed_addr constant
-// CHECK-TEST9: @_ZTVN5Test91BE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
@@ -206,39 +206,39 @@
 namespace Test10 {
 
 // because A's key function is defined here, vtable is generated in this TU
-// CHECK-TEST10: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr
-// CHECK-TEST10: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
 inline void D::bar() {}
 
 // because B has outline key function then we can refer to
-// CHECK-TEST10: @_ZTVN6Test101BE = available_externally unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
   void bar();
 };
 
 // C's key function (car) is outline, but C has inline virtual function so we
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally
-// CHECK-TEST10: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
-// CHECK-TEST10: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
 struct E : A {};
 
 void g(A a) {
Index: test/CodeGenCXX/vtable-assume-load.cpp
===
--- /dev/null
+++ test/CodeGenCXX/vtable-assume-load.cpp
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions
+
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
+
+namespace test1 {
+
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B : A {
+  virtual void foo();
+};
+
+void g(A *a) { a-foo(); }
+
+// CHECK1-LABEL: define void @_ZN5test14fooAEv()
+// CHECK1: call void @_ZN5test11AC1Ev(%struct.test1::A* %a)
+// CHECK1: %vtable = load i8**, i8*** %1
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABEL: }
+
+void fooA() {
+  A a;
+  g(a);
+}
+
+// CHECK1-LABEL: define void @_ZN5test14fooBEv()
+// CHECK1: call void @_ZN5test11BC1Ev(%struct.test1::B* %b)
+// CHECK1: %vtable = load i8**, i8*** %1
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABLE: }
+
+void fooB() {
+  B b;
+  g(b);
+}
+// there should not be any assumes in the ctor that calls base ctor
+// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%struct.test1::B* %this)
+// CHECK1-NOT: @llvm.assume(
+// CHECK1-LABEL: }
+}
+namespace test2 {
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B {
+  B();
+  virtual void bar();
+};
+

Re: [PATCH] D11859: Generating vptr assume loads

2015-08-13 Thread Piotr Padlewski via cfe-commits
Prazek marked an inline comment as done.


Comment at: lib/CodeGen/CGClass.cpp:1832
@@ +1831,3 @@
+  // Generate vtable assumptions if we are calling dynamic class ctor
+  // and we are not in another ctor.
+  if (CGM.getCodeGenOpts().OptimizationLevel  0 

rsmith wrote:
 Prazek wrote:
  hfinkel wrote:
   I think this comment should be a little more verbose. How about this:
   
 // Generate vtable assumptions if we are calling dynamic-class's ctor, 
   except when doing so as part of a derived class's ctor's base-class 
   initialization. Doing so in this latter case would be useless, because 
   the vtable is about to be overwritten by the derived class's vtable.
   
  The main point of not calling this function, is because it is useless to 
  have assumption loads inside constructor, when they are generated also 
  outside of ctor. I guess You could have case when You are not overriding 
  base vptr, and You are calling base ctor from dynamic class
 It might also be worth including in the comment that it is not correct to 
 call `EmitVTableAssumptionLoads` here, because it assumes the object's vptr 
 points to the complete object vtable; during a constructor call it will 
 probably have a construction vtable instead.
Well,  it would be correct, but it would be useless. Just after calling base 
constructor, assume loads would appear, and after there would be new store to 
vptr.


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-11 Thread Piotr Padlewski via cfe-commits
Prazek updated this revision to Diff 31846.

http://reviews.llvm.org/D11859

Files:
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGen/available-externally-hidden.cpp
  test/CodeGenCXX/ctor-globalopt.cpp
  test/CodeGenCXX/template-instantiation.cpp
  test/CodeGenCXX/thunks.cpp
  test/CodeGenCXX/virtual-base-ctor.cpp
  test/CodeGenCXX/vtable-assume-load.cpp
  test/CodeGenCXX/vtable-available-externally.cpp

Index: test/CodeGenCXX/vtable-available-externally.cpp
===
--- test/CodeGenCXX/vtable-available-externally.cpp
+++ test/CodeGenCXX/vtable-available-externally.cpp
@@ -182,8 +182,8 @@
 namespace Test9 {
 // all virtual functions are outline, so we can assume that it will
 // be generated in translation unit where foo is defined
-// CHECK-TEST9: @_ZTVN5Test91AE = available_externally unnamed_addr constant
-// CHECK-TEST9: @_ZTVN5Test91BE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
@@ -206,39 +206,39 @@
 namespace Test10 {
 
 // because A's key function is defined here, vtable is generated in this TU
-// CHECK-TEST10: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr
-// CHECK-TEST10: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
 inline void D::bar() {}
 
 // because B has outline key function then we can refer to
-// CHECK-TEST10: @_ZTVN6Test101BE = available_externally unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
   void bar();
 };
 
 // C's key function (car) is outline, but C has inline virtual function so we
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally
-// CHECK-TEST10: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
-// CHECK-TEST10: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
 struct E : A {};
 
 void g(A a) {
Index: test/CodeGenCXX/vtable-assume-load.cpp
===
--- /dev/null
+++ test/CodeGenCXX/vtable-assume-load.cpp
@@ -0,0 +1,170 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions
+
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
+
+namespace test1 {
+
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B : A {
+  virtual void foo();
+};
+
+void g(A *a) { a-foo(); }
+
+void fooA() {
+  A a;
+  g(a);
+}
+void fooB() {
+  B b;
+  g(b);
+}
+// CHECK1-LABEL: define void @_ZN5test14fooAEv()
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABEL: }
+
+// CHECK1-LABEL: define void @_ZN5test14fooBEv()
+// CHECK1: call void @_ZN5test11BC1Ev(%struct.test1::B* %b)
+// CHECK1: %vtable = load i8**, i8*** %1, !tbaa !5
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABLE: }
+
+// there should not be any assumes in the ctor that calls base ctor
+// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%struct.test1::B* %this)
+// CHECK1-NOT: @llvm.assume(
+// CHECK1-LABEL: }
+}
+namespace test2 {
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B {
+  B();
+  virtual void bar();
+};
+
+struct C : A, B {
+  C();
+  virtual void foo();
+};
+void g(A *a) { a-foo(); }
+void h(B *b) { b-bar(); }
+
+// CHECK2-LABEL: define void 

Re: [PATCH] D11859: Generating vptr assume loads

2015-08-10 Thread Piotr Padlewski via cfe-commits
Prazek updated this revision to Diff 31768.

http://reviews.llvm.org/D11859

Files:
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGen/available-externally-hidden.cpp
  test/CodeGenCXX/ctor-globalopt.cpp
  test/CodeGenCXX/template-instantiation.cpp
  test/CodeGenCXX/thunks.cpp
  test/CodeGenCXX/virtual-base-ctor.cpp
  test/CodeGenCXX/vtable-assume-load.cpp
  test/CodeGenCXX/vtable-available-externally.cpp

Index: test/CodeGenCXX/vtable-available-externally.cpp
===
--- test/CodeGenCXX/vtable-available-externally.cpp
+++ test/CodeGenCXX/vtable-available-externally.cpp
@@ -182,8 +182,8 @@
 namespace Test9 {
 // all virtual functions are outline, so we can assume that it will
 // be generated in translation unit where foo is defined
-// CHECK-TEST9: @_ZTVN5Test91AE = available_externally unnamed_addr constant
-// CHECK-TEST9: @_ZTVN5Test91BE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
@@ -206,39 +206,39 @@
 namespace Test10 {
 
 // because A's key function is defined here, vtable is generated in this TU
-// CHECK-TEST10: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr
-// CHECK-TEST10: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
 inline void D::bar() {}
 
 // because B has outline key function then we can refer to
-// CHECK-TEST10: @_ZTVN6Test101BE = available_externally unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
   void bar();
 };
 
 // C's key function (car) is outline, but C has inline virtual function so we
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally
-// CHECK-TEST10: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
-// CHECK-TEST10: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
 struct E : A {};
 
 void g(A a) {
Index: test/CodeGenCXX/vtable-assume-load.cpp
===
--- /dev/null
+++ test/CodeGenCXX/vtable-assume-load.cpp
@@ -0,0 +1,170 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions
+
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
+
+namespace test1 {
+
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B : A {
+  virtual void foo();
+};
+
+void g(A* a) { a-foo(); }
+
+void fooA() {
+  A a;
+  g(a);
+}
+void fooB() {
+  B b;
+  g(b);
+}
+// CHECK1-LABEL: define void @_ZN5test14fooAEv()
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABEL: }
+
+// CHECK1-LABEL: define void @_ZN5test14fooBEv()
+// CHECK1: call void @_ZN5test11BC1Ev(%struct.test1::B* %b)
+// CHECK1: %vtable = load i8**, i8*** %1, !tbaa !5
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABLE: }
+
+// there should not be any assumes in the ctor that calls base ctor
+// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%struct.test1::B* %this)
+// CHECK1-NOT: @llvm.assume(
+// CHECK1-LABEL: }
+}
+namespace test2 {
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B {
+  B();
+  virtual void bar();
+};
+
+struct C : A, B {
+  C();
+  virtual void foo();
+};
+void g(A* a) { a-foo(); }
+void h(B* b) { b-bar(); }
+
+// CHECK2-LABEL: define void 

Re: [PATCH] D11859: Generating vptr assume loads

2015-08-10 Thread Nathan Wilson via cfe-commits
nwilson added a subscriber: nwilson.


Comment at: lib/CodeGen/CGClass.cpp:1862
@@ +1861,3 @@
+if (CGM.getCXXABI().canInitializeVPtr(vptr.VTableClass, 
vptr.Base.getBase(),
+ vptr.NearestVBase))
+  EmitVTableAssumptionLoad(vptr, This);

Looks like another formatting/tab issue here.


Comment at: lib/CodeGen/CGClass.cpp:2155
@@ +2154,3 @@
+if (CGM.getCXXABI().canInitializeVPtr(Vptr.VTableClass, 
Vptr.Base.getBase(),
+ Vptr.NearestVBase))
+  InitializeVTablePointer(Vptr);

Looks like the same formatting/tab as above.

This is what I've done when using clang-format, maybe it will fix the issues 
you've had:
./clang-format -style=llvm -lines=N:M FileToFormat  tmp  cp tmp 
FileToFormat

(Just don't include the less than and greater around the FileToFormat.)



http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-10 Thread Daniel Jasper via cfe-commits
djasper added inline comments.


Comment at: lib/CodeGen/CGClass.cpp:2155
@@ +2154,3 @@
+if (CGM.getCXXABI().canInitializeVPtr(Vptr.VTableClass, 
Vptr.Base.getBase(),
+ Vptr.NearestVBase))
+  InitializeVTablePointer(Vptr);

nwilson wrote:
 Looks like the same formatting/tab as above.
 
 This is what I've done when using clang-format, maybe it will fix the issues 
 you've had:
 ./clang-format -style=llvm -lines=N:M FileToFormat  tmp  cp tmp 
 FileToFormat
 
 (Just don't include the less than and greater around the FileToFormat.)
 
You shouldn't need to do this by hand. There is clang-format-diff.py / 
git-clang-format for that.


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-10 Thread Nathan Wilson via cfe-commits
nwilson added inline comments.


Comment at: lib/CodeGen/CGClass.cpp:2155
@@ +2154,3 @@
+if (CGM.getCXXABI().canInitializeVPtr(Vptr.VTableClass, 
Vptr.Base.getBase(),
+ Vptr.NearestVBase))
+  InitializeVTablePointer(Vptr);

djasper wrote:
 nwilson wrote:
  Looks like the same formatting/tab as above.
  
  This is what I've done when using clang-format, maybe it will fix the 
  issues you've had:
  ./clang-format -style=llvm -lines=N:M FileToFormat  tmp  cp tmp 
  FileToFormat
  
  (Just don't include the less than and greater around the FileToFormat.)
  
 You shouldn't need to do this by hand. There is clang-format-diff.py / 
 git-clang-format for that.
Good to know. Thanks!


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-10 Thread Piotr Padlewski via cfe-commits
Prazek added inline comments.


Comment at: lib/CodeGen/CodeGenFunction.h:1328-1334
@@ -1320,8 +1327,9 @@
   typedef llvm::SmallPtrSetconst CXXRecordDecl *, 4 VisitedVirtualBasesSetTy;
-  void InitializeVTablePointers(BaseSubobject Base,
-const CXXRecordDecl *NearestVBase,
-CharUnits OffsetFromNearestVBase,
-bool BaseIsNonVirtualPrimaryBase,
-const CXXRecordDecl *VTableClass,
-VisitedVirtualBasesSetTy VBases);
+  VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass);
+
+  void getVTablePointers(BaseSubobject Base, const CXXRecordDecl *NearestVBase,
+ CharUnits OffsetFromNearestVBase,
+ bool BaseIsNonVirtualPrimaryBase,
+ const CXXRecordDecl *VTableClass,
+ VisitedVirtualBasesSetTy VBases, VPtrsVector vptrs);
 

majnemer wrote:
 Would it make more sense for these to live in `CGClass` ?
What do You mean? These functions are defined in CGClass.cpp 


Comment at: lib/CodeGen/MicrosoftCXXABI.cpp:223-228
@@ +222,8 @@
+  // with the 'novtable' attribute.
+  bool canInitilizeVPtr(const CXXRecordDecl *VTableClass,
+const CXXRecordDecl *Base,
+const CXXRecordDecl *NearestVBase) override {
+return !VTableClass-hasAttrMSNoVTableAttr() ||
+   (Base != VTableClass  Base != NearestVBase);
+  }
+

Prazek wrote:
 majnemer wrote:
  In the MS ABI, derived classes never share vtables with bases.  Why do you 
  need to do anything other than check that the most derived class doesn't 
  have the `__declspec(novtable)` ?
 I don't know, I just took previous code assuming it is correct.
ok, I see. I just took code that suposed to work with microsoft and itanium 
abi. You are right


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-10 Thread Piotr Padlewski via cfe-commits
Prazek updated this revision to Diff 31766.

http://reviews.llvm.org/D11859

Files:
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGen/available-externally-hidden.cpp
  test/CodeGenCXX/ctor-globalopt.cpp
  test/CodeGenCXX/template-instantiation.cpp
  test/CodeGenCXX/thunks.cpp
  test/CodeGenCXX/virtual-base-ctor.cpp
  test/CodeGenCXX/vtable-assume-load.cpp
  test/CodeGenCXX/vtable-available-externally.cpp

Index: test/CodeGenCXX/vtable-available-externally.cpp
===
--- test/CodeGenCXX/vtable-available-externally.cpp
+++ test/CodeGenCXX/vtable-available-externally.cpp
@@ -182,8 +182,8 @@
 namespace Test9 {
 // all virtual functions are outline, so we can assume that it will
 // be generated in translation unit where foo is defined
-// CHECK-TEST9: @_ZTVN5Test91AE = available_externally unnamed_addr constant
-// CHECK-TEST9: @_ZTVN5Test91BE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
@@ -206,39 +206,39 @@
 namespace Test10 {
 
 // because A's key function is defined here, vtable is generated in this TU
-// CHECK-TEST10: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr
-// CHECK-TEST10: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
 inline void D::bar() {}
 
 // because B has outline key function then we can refer to
-// CHECK-TEST10: @_ZTVN6Test101BE = available_externally unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
   void bar();
 };
 
 // C's key function (car) is outline, but C has inline virtual function so we
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally
-// CHECK-TEST10: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
-// CHECK-TEST10: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
 struct E : A {};
 
 void g(A a) {
Index: test/CodeGenCXX/vtable-assume-load.cpp
===
--- /dev/null
+++ test/CodeGenCXX/vtable-assume-load.cpp
@@ -0,0 +1,170 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions
+
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
+
+namespace test1 {
+
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B : A {
+  virtual void foo();
+};
+
+void g(A* a) { a-foo(); }
+
+void fooA() {
+  A a;
+  g(a);
+}
+void fooB() {
+  B b;
+  g(b);
+}
+// CHECK1-LABEL: define void @_ZN5test14fooAEv()
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABEL: }
+
+// CHECK1-LABEL: define void @_ZN5test14fooBEv()
+// CHECK1: call void @_ZN5test11BC1Ev(%struct.test1::B* %b)
+// CHECK1: %vtable = load i8**, i8*** %1, !tbaa !5
+// CHECK1: %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)
+// CHECK1: call void @llvm.assume(i1 %cmp.vtables)
+// CHECK1-LABLE: }
+
+// there should not be any assumes in the ctor that calls base ctor
+// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%struct.test1::B* %this)
+// CHECK1-NOT: @llvm.assume(
+// CHECK1-LABEL: }
+}
+namespace test2 {
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B {
+  B();
+  virtual void bar();
+};
+
+struct C : A, B {
+  C();
+  virtual void foo();
+};
+void g(A* a) { a-foo(); }
+void h(B* b) { b-bar(); }
+
+// CHECK2-LABEL: define void 

Re: [PATCH] D11859: Generating vptr assume loads

2015-08-10 Thread Piotr Padlewski via cfe-commits
Prazek marked 9 inline comments as done.
Prazek added a comment.

http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11859: Generating vptr assume loads

2015-08-10 Thread Piotr Padlewski via cfe-commits
Prazek added inline comments.


Comment at: lib/CodeGen/CGClass.cpp:1842
@@ +1841,3 @@
+  CGM.getCXXABI().getVTableAddressPoint(vptr.Base, vptr.VTableClass);
+  if (!VTableGlobal) return;
+

djasper wrote:
 Prazek wrote:
  majnemer wrote:
   The return should be on it's own line, please clang-format this.
   Also, under which conditions is this case possible?
  Unfortunatelly clang-format puts short instructions in the same line
 Not, it doesn't. At least not if you properly configure LLVM style.
So mb I am doing something wrong, but I am using git-clang-format and get 
things like this


http://reviews.llvm.org/D11859



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits