r205101 - CodeGen: Allow different RTTI emission strategies

Tim Northover t.p.northover at gmail.com
Sun Mar 30 05:12:58 PDT 2014


Hi,

Thanks very much for the suggestions. I've attached a refactoring
patch (with the other consistency fixes); does it look more
reasonable?

Cheers.

Tim.
-------------- next part --------------
commit 7b8b9a3d5013b8b1caf773a4833cdd7b5051391c
Author: Tim Northover <T.P.Northover at gmail.com>
Date:   Sun Mar 30 13:06:35 2014 +0100

    RTTI: refactor the uniqueness question into CGCXXABI.
    
    This also brings the code into closer conformance with usual LLVM
    coding style and other surrounding conventions.

diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp
index 3d0eaa0..2bb3907 100644
--- a/lib/CodeGen/CGCXXABI.cpp
+++ b/lib/CodeGen/CGCXXABI.cpp
@@ -290,3 +290,31 @@ LValue CGCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
 bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
   return false;
 }
+
+/// What sort of uniqueness rules should we use for the RTTI for the
+/// given type?
+CGCXXABI::RTTIUniquenessKind
+CGCXXABI::classifyRTTIUniqueness(QualType CanTy,
+                                 llvm::GlobalValue::LinkageTypes Linkage) {
+  if (shouldRTTIBeUnique())
+    return RUK_Unique;
+
+  // It's only necessary for linkonce_odr or weak_odr linkage.
+  if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
+      Linkage != llvm::GlobalValue::WeakODRLinkage)
+    return RUK_Unique;
+
+  // It's only necessary with default visibility.
+  if (CanTy->getVisibility() != DefaultVisibility)
+    return RUK_Unique;
+
+  // If we're not required to publish this symbol, hide it.
+  if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
+    return RUK_NonUniqueHidden;
+
+  // If we're required to publish this symbol, as we might be under an
+  // explicit instantiation, leave it with default visibility but
+  // enable string-comparisons.
+  assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
+  return RUK_NonUniqueVisible;
+}
diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h
index 783cc59..beaec2c 100644
--- a/lib/CodeGen/CGCXXABI.h
+++ b/lib/CodeGen/CGCXXABI.h
@@ -484,6 +484,36 @@ public:
   virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
                                               const VarDecl *VD,
                                               QualType LValType);
+
+  /**************************** RTTI Uniqueness ******************************/
+
+protected:
+  /// Returns true if the ABI requires RTTI type_info objects to be unique
+  /// across a program.
+  virtual bool shouldRTTIBeUnique() { return true; }
+
+public:
+  /// What sort of unique-RTTI behavior should we use?
+  enum RTTIUniquenessKind {
+    /// We are guaranteeing, or need to guarantee, that the RTTI string
+    /// is unique.
+    RUK_Unique,
+
+    /// We are not guaranteeing uniqueness for the RTTI string, so we
+    /// can demote to hidden visibility but must use string comparisons.
+    RUK_NonUniqueHidden,
+
+    /// We are not guaranteeing uniqueness for the RTTI string, so we
+    /// have to use string comparisons, but we also have to emit it with
+    /// non-hidden visibility.
+    RUK_NonUniqueVisible
+  };
+
+  /// Return the required visibility status for the given type and linkage in
+  /// the current ABI.
+  RTTIUniquenessKind
+  classifyRTTIUniqueness(QualType CanTy,
+                         llvm::GlobalValue::LinkageTypes Linkage);
 };
 
 // Create an instance of a C++ ABI class:
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
index c33f088..7049df7 100644
--- a/lib/CodeGen/CGRTTI.cpp
+++ b/lib/CodeGen/CGRTTI.cpp
@@ -508,52 +508,6 @@ void RTTIBuilder::BuildVTablePointer(const Type *Ty) {
   Fields.push_back(VTable);
 }
 
-/// What sort of unique-RTTI behavior should we use?
-enum UniqueRTTIKind {
-  /// We are guaranteeing, or need to guarantee, that the RTTI string
-  /// is unique.
-  UniqueRTTI,
-
-  /// We are not guaranteeing uniqueness for the RTTI string, so we
-  /// can demote to hidden visibility and use string comparisons.
-  NonUniqueHiddenRTTI,
-
-  /// We are not guaranteeing uniqueness for the RTTI string, so we
-  /// have to use string comparisons, but we also have to emit it with
-  /// non-hidden visibility.
-  NonUniqueVisibleRTTI
-};
-
-/// What sort of uniqueness rules should we use for the RTTI for the
-/// given type?
-static UniqueRTTIKind
-classifyUniqueRTTI(CodeGenModule &CGM, QualType canTy,
-                   llvm::GlobalValue::LinkageTypes linkage) {
-  // We only support non-unique RTTI on iOS64.
-  // FIXME: abstract this into CGCXXABI after this code moves to trunk.
-  if (CGM.getTarget().getCXXABI().getKind() != TargetCXXABI::iOS64)
-    return UniqueRTTI;
-
-  // It's only necessary for linkonce_odr or weak_odr linkage.
-  if (linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
-      linkage != llvm::GlobalValue::WeakODRLinkage)
-    return UniqueRTTI;
-
-  // It's only necessary with default visibility.
-  if (canTy->getVisibility() != DefaultVisibility)
-    return UniqueRTTI;
-
-  // If we're not required to publish this symbol, hide it.
-  if (linkage == llvm::GlobalValue::LinkOnceODRLinkage)
-    return NonUniqueHiddenRTTI;
-
-  // If we're required to publish this symbol, as we might be under an
-  // explicit instantiation, leave it with default visibility but
-  // enable string-comparisons.
-  assert(linkage == llvm::GlobalValue::WeakODRLinkage);
-  return NonUniqueVisibleRTTI;
-}
-
 llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
   // We want to operate on the canonical type.
   Ty = CGM.getContext().getCanonicalType(Ty);
@@ -590,24 +544,25 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
   
   // And the name.
   llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
-  llvm::Constant *typeNameField;
+  llvm::Constant *TypeNameField;
 
   // If we're supposed to demote the visibility, be sure to set a flag
   // to use a string comparison for type_info comparisons.
-  UniqueRTTIKind uniqueRTTI = classifyUniqueRTTI(CGM, Ty, Linkage);
-  if (uniqueRTTI != UniqueRTTI) {
+  CGCXXABI::RTTIUniquenessKind RTTIUniqueness =
+      CGM.getCXXABI().classifyRTTIUniqueness(Ty, Linkage);
+  if (RTTIUniqueness != CGCXXABI::RUK_Unique) {
     // The flag is the sign bit, which on ARM64 is defined to be clear
     // for global pointers.  This is very ARM64-specific.
-    typeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.Int64Ty);
+    TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.Int64Ty);
     llvm::Constant *flag =
         llvm::ConstantInt::get(CGM.Int64Ty, ((uint64_t)1) << 63);
-    typeNameField = llvm::ConstantExpr::getAdd(typeNameField, flag);
-    typeNameField =
-        llvm::ConstantExpr::getIntToPtr(typeNameField, CGM.Int8PtrTy);
+    TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
+    TypeNameField =
+        llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.Int8PtrTy);
   } else {
-    typeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy);
+    TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy);
   }
-  Fields.push_back(typeNameField);
+  Fields.push_back(TypeNameField);
 
   switch (Ty->getTypeClass()) {
 #define TYPE(Class, Base)
@@ -730,7 +685,7 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
   GV->setVisibility(llvmVisibility);
 
   // FIXME: integrate this better into the above when we move to trunk
-  if (uniqueRTTI == NonUniqueHiddenRTTI) {
+  if (RTTIUniqueness == CGCXXABI::RUK_NonUniqueHidden) {
     TypeName->setVisibility(llvm::GlobalValue::HiddenVisibility);
     GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
   }
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index 1648c3b..27825ab 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -248,6 +248,9 @@ public:
 class iOS64CXXABI : public ARMCXXABI {
 public:
   iOS64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {}
+
+  // ARM64 libraries are prepared for non-unique RTTI.
+  bool shouldRTTIBeUnique() override { return false; }
 };
 }
 


More information about the cfe-commits mailing list