lvoufo updated this revision to Diff 39724.
lvoufo added a comment.

Fix patch (wrong one submitted initially).


http://reviews.llvm.org/D14419

Files:
  include/clang/AST/DeclCXX.h
  lib/AST/DeclCXX.cpp
  lib/AST/Type.cpp
  test/CodeGenCXX/const-invariant.cpp

Index: test/CodeGenCXX/const-invariant.cpp
===================================================================
--- test/CodeGenCXX/const-invariant.cpp
+++ test/CodeGenCXX/const-invariant.cpp
@@ -167,11 +167,11 @@
 // CHECK-NL-CO-OBJ: call void @_ZN1MC{{[0-9]+}}Ei({{.*}}* @_ZL3i_m, {{.*}})
 // CHECK-NL-CO-OBJ: call {{.*}}@llvm.invariant.start(i64 {{[0-9]+}}, i8* bitcast ({{.*}} @_ZL3i_m to i8*),
 // CHECK-NL-CO-OBJ: call void @_ZN1FC{{[0-9]+}}Ei({{.*}}* @_ZL3i_f, {{.*}})
-// CHECK-NL-CO-OBJ-NOT: call {{.*}}@llvm.invariant.start(i64 {{[0-9]+}}, i8* bitcast ({{.*}} @_ZL3i_f to i8*))
+// CHECK-NL-CO-OBJ: call {{.*}}@llvm.invariant.start(i64 {{[0-9]+}}, i8* bitcast ({{.*}} @_ZL3i_f to i8*))
 // CHECK-NL-CO-OBJ: call void @_ZN1IC{{[0-9]+}}Ei({{.*}}* @_ZL3i_i, {{.*}})
 // CHECK-NL-CO-OBJ: call {{.*}}@llvm.invariant.start(i64 {{[0-9]+}}, i8* bitcast ({{.*}} @_ZL3i_i to i8*))
 // CHECK-NL-CO-OBJ: call void @_ZN2IVC{{[0-9]+}}Ei({{.*}}* @_ZL4i_iv, {{.*}})
-// CHECK-NL-CO-OBJ-NOT: call {{.*}}@llvm.invariant.start(i64 {{[0-9]+}}, i8* bitcast ({{.*}} @_ZL4i_iv to i8*))
+// CHECK-NL-CO-OBJ: call {{.*}}@llvm.invariant.start(i64 {{[0-9]+}}, i8* bitcast ({{.*}} @_ZL4i_iv to i8*))
 // CHECK-NL-CO-OBJ: call void @_ZN3CIVC{{[0-9]+}}Ei({{.*}}* @_ZL5i_civ, {{.*}})
 // CHECK-NL-CO-OBJ: call {{.*}}@llvm.invariant.start(i64 {{[0-9]+}}, i8* bitcast ({{.*}} @_ZL5i_civ to i8*))
 
@@ -303,11 +303,11 @@
   // CHECK-L-CO-OBJ: %i_f = alloca {{.*}}
 
   // CHECK-L-CO-OBJ: call void @_ZN1FC{{[0-9]+}}Ei({{.*}}* %i_f,
-  // CHECK-L-CO-OBJ-NOT: call {{.*}}@llvm.invariant.start(
+  // CHECK-L-CO-OBJ: call {{.*}}@llvm.invariant.start(
   bar_f(i_f);
   foo_f(&i_f);  // May change i_f.
   bar_f(i_f);
-  // CHECK-L-CO-OBJ-NOT: call {{.*}}@llvm.invariant.end(
+  // CHECK-L-CO-OBJ: call {{.*}}@llvm.invariant.end(
 }
 
 // Example 1 with type inheriting non-virtual base:
@@ -337,11 +337,11 @@
   // CHECK-L-CO-OBJ: %i_iv = alloca {{.*}}
 
   // CHECK-L-CO-OBJ: call void @_ZN2IVC{{[0-9]+}}Ei({{.*}}* %i_iv,
-  // CHECK-L-CO-OBJ-NOT: call {{.*}}@llvm.invariant.start(
+  // CHECK-L-CO-OBJ: call {{.*}}@llvm.invariant.start(
   bar_iv(i_iv);
   foo_iv(&i_iv);  // Does not change i_iv.
   bar_iv(i_iv);
-  // CHECK-L-CO-OBJ-NOT: call {{.*}}@llvm.invariant.end(
+  // CHECK-L-CO-OBJ: call {{.*}}@llvm.invariant.end(
 }
 
 // Example 1 with type inheriting virtual writeonce base:
Index: lib/AST/Type.cpp
===================================================================
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -1937,15 +1937,8 @@
 }
 
 bool QualType::isWriteOnce(ASTContext &Context) {
-  // TODO: Include C objects as well?
-  if (Context.getLangOpts().CPlusPlus && isConstant(Context) &&
-      !getTypePtr()->isReferenceType()) {
-    if (const CXXRecordDecl *Record =
-            Context.getBaseElementType(*this)->getAsCXXRecordDecl())
-      return Record->computeWriteOnceCandidacy();
-    return true;
-  }
-  return false;
+  return (Context.getLangOpts().CPlusPlus && isConstant(Context) &&
+          !getTypePtr()->isReferenceType());
 }
 
 bool QualType::isPODType(ASTContext &Context) const {
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -58,8 +58,6 @@
       HasPrivateFields(false),
       HasProtectedFields(false),
       HasPublicFields(false),
-      IsWriteOnceChecked(false),
-      IsWriteOnceCandidate(false),
       HasMutableFields(false),
       HasVariantMembers(false),
       HasOnlyCMembers(true),
@@ -1350,73 +1348,6 @@
   return false;
 }
 
-/// \brief A class is a candidate for 'writeonce' semantics if
-/// none of its methods writes to memory.
-bool CXXRecordDecl::computeWriteOnceCandidacy() const {
-  // The class must be defined and concrete.
-  if (!isCompleteDefinition() || isDependentType()) return false;
-
-  // If this has already been checked, then return the stored value.
-  if (data().IsWriteOnceChecked) return data().IsWriteOnceCandidate;
-
-  // Otherwise, mark that this is checked.
-  data().IsWriteOnceChecked = true;
-  assert(!data().IsWriteOnceCandidate &&
-         "The candidacy should not have been set yet.");
-
-  // Check each method, excluding constructors and destructors.
-  // NOTE: The invariant intrinsic calls are generated right after the
-  //       construction of a given const object (which must be initialized)
-  //       and right before its destruction at the end of its lifetime.
-  //       Both constructors and destructors modify the allocated memory and
-  //       and will not be called in the middle of an invariant_start/end
-  //       pair, thus may not affect the reduction of loads. So, it does not
-  //       help to handle constructors here as well.
-  for (auto *M : methods()) {
-    if (isa<CXXConstructorDecl>(M) || isa<CXXDestructorDecl>(M)) continue;
-
-    // If we already know that this method does not write to memory, skip it.
-    // NOTE: CodeGenModule::ConstructAttributeList() marks declarations with
-    //       ConstAttr and PureAttr attributes, respectively, as 'readnone' and
-    //       'readonly' (for LLVM).
-    if (M->hasAttr<ConstAttr>() || M->hasAttr<PureAttr>()) continue;
-
-    const FunctionDecl *Def = nullptr;
-    bool IsDefined = M->isDefined(Def);
-
-    // If this is not defined and not virtual, then it may write to memory.
-    // So it's not a candidate for 'writeonce' semantics.
-    // If it is purely virtual then it must be overriden and its overriding
-    // method (in this context) must be a candidate for 'writeonce' semantics.
-    // Skip it.
-    if (!IsDefined) {
-      if (M->isPure()) {
-        assert(M->isVirtual() && "Not defined and pure implies virtual.");
-        continue;
-      }
-      return false;
-    }
-
-    // If this is trivial, skip it.
-    if (Def->hasTrivialBody()) continue;
-
-    // TODO: Any other case?
-  }
-
-  // Check bases
-  for (const auto &I : bases()) {
-    const RecordType *Ty = I.getType()->getAs<RecordType>();
-    assert(Ty && "No type?");
-    CXXRecordDecl *Base =
-        cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition());
-
-    if (!Base || !Base->computeWriteOnceCandidacy()) return false;
-  }
-
-  data().IsWriteOnceCandidate = true;
-  return true;
-}
-
 void CXXRecordDecl::completeDefinition() {
   completeDefinition(nullptr);
 }
Index: include/clang/AST/DeclCXX.h
===================================================================
--- include/clang/AST/DeclCXX.h
+++ include/clang/AST/DeclCXX.h
@@ -357,14 +357,6 @@
     /// \brief True when there are private non-static data members.
     bool HasPublicFields : 1;
 
-    /// \brief True is this class has already been checked as candidate
-    /// for writeonce semantics.
-    bool IsWriteOnceChecked : 1;
-
-    /// \brief True if instances of this class are candidates
-    /// for writeonce semantics.
-    bool IsWriteOnceCandidate : 1;
-
     /// \brief True if this class (or any subobject) has mutable fields.
     bool HasMutableFields : 1;
 
@@ -774,8 +766,6 @@
     return method_iterator(decls_end());
   }
 
-  bool computeWriteOnceCandidacy() const;
-
   /// Iterator access to constructor members.
   typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
   typedef llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>>
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to