]> granicus.if.org Git - clang/commitdiff
Experimental TBAA support.
authorDan Gohman <gohman@apple.com>
Thu, 14 Oct 2010 23:06:10 +0000 (23:06 +0000)
committerDan Gohman <gohman@apple.com>
Thu, 14 Oct 2010 23:06:10 +0000 (23:06 +0000)
This enables metadata generation by default, however the TBAA pass
in the optimizer is still disabled for now.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116536 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGValue.h
lib/CodeGen/CodeGenFunction.h
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
lib/CodeGen/CodeGenTBAA.cpp [new file with mode: 0644]
lib/CodeGen/CodeGenTBAA.h [new file with mode: 0644]

index 186c5ff4281148f60c3ba3da81aefd58997b166e..5b695cd52c3335914d11ac72a229d75789843464 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "CodeGenTBAA.h"
 #include "CGCall.h"
 #include "CGCXXABI.h"
 #include "CGRecordLayout.h"
@@ -580,12 +581,15 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
 }
 
 llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
-                                              unsigned Alignment, QualType Ty) {
+                                              unsigned Alignment, QualType Ty,
+                                              llvm::MDNode *TBAAInfo) {
   llvm::LoadInst *Load = Builder.CreateLoad(Addr, "tmp");
   if (Volatile)
     Load->setVolatile(true);
   if (Alignment)
     Load->setAlignment(Alignment);
+  if (TBAAInfo)
+    CGM.DecorateInstruction(Load, TBAAInfo);
 
   // Bool can have different representation in memory than in registers.
   llvm::Value *V = Load;
@@ -604,7 +608,8 @@ static bool isBooleanUnderlyingType(QualType Ty) {
 
 void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
                                         bool Volatile, unsigned Alignment,
-                                        QualType Ty) {
+                                        QualType Ty,
+                                        llvm::MDNode *TBAAInfo) {
 
   if (Ty->isBooleanType() || isBooleanUnderlyingType(Ty)) {
     // Bool can have different representation in memory than in registers.
@@ -615,6 +620,8 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
   llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile);
   if (Alignment)
     Store->setAlignment(Alignment);
+  if (TBAAInfo)
+    CGM.DecorateInstruction(Store, TBAAInfo);
 }
 
 /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
@@ -637,7 +644,8 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
 
     // Everything needs a load.
     return RValue::get(EmitLoadOfScalar(Ptr, LV.isVolatileQualified(),
-                                        LV.getAlignment(), ExprType));
+                                        LV.getAlignment(), ExprType,
+                                        LV.getTBAAInfo()));
 
   }
 
@@ -846,7 +854,8 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
 
   assert(Src.isScalar() && "Can't emit an agg store with this method");
   EmitStoreOfScalar(Src.getScalarVal(), Dst.getAddress(),
-                    Dst.isVolatileQualified(), Dst.getAlignment(), Ty);
+                    Dst.isVolatileQualified(), Dst.getAlignment(), Ty,
+                    Dst.getTBAAInfo());
 }
 
 void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
index ff19179db00170455f0ab3f35fef6f5f84a1ca16..a000b223311ea31f74a45f01285dfe2aeeb56eb4 100644 (file)
@@ -157,8 +157,13 @@ class LValue {
   bool ThreadLocalRef : 1;
 
   Expr *BaseIvarExp;
+
+  /// TBAAInfo - TBAA information to attach to dereferences of this LValue.
+  llvm::MDNode *TBAAInfo;
+
 private:
-  void Initialize(Qualifiers Quals, unsigned Alignment = 0) {
+  void Initialize(Qualifiers Quals, unsigned Alignment = 0,
+                  llvm::MDNode *TBAAInfo = 0) {
     this->Quals = Quals;
     this->Alignment = Alignment;
     assert(this->Alignment == Alignment && "Alignment exceeds allowed max!");
@@ -167,6 +172,7 @@ private:
     this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
     this->ThreadLocalRef = false;
     this->BaseIvarExp = 0;
+    this->TBAAInfo = TBAAInfo;
   }
 
 public:
@@ -208,6 +214,9 @@ public:
   Expr *getBaseIvarExp() const { return BaseIvarExp; }
   void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
 
+  llvm::MDNode *getTBAAInfo() const { return TBAAInfo; }
+  void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; }
+
   const Qualifiers &getQuals() const { return Quals; }
   Qualifiers &getQuals() { return Quals; }
 
@@ -252,14 +261,15 @@ public:
   }
 
   static LValue MakeAddr(llvm::Value *V, QualType T, unsigned Alignment,
-                         ASTContext &Context) {
+                         ASTContext &Context,
+                         llvm::MDNode *TBAAInfo = 0) {
     Qualifiers Quals = Context.getCanonicalType(T).getQualifiers();
     Quals.setObjCGCAttr(Context.getObjCGCAttrKind(T));
 
     LValue R;
     R.LVType = Simple;
     R.V = V;
-    R.Initialize(Quals, Alignment);
+    R.Initialize(Quals, Alignment, TBAAInfo);
     return R;
   }
 
index 4e64319ae53ec4cc7a607da84e8b593b7f9461df..6061b8fee8f84a54ab199ef2baaf06d4b8fef791 100644 (file)
@@ -1011,7 +1011,8 @@ public:
   //===--------------------------------------------------------------------===//
 
   LValue MakeAddrLValue(llvm::Value *V, QualType T, unsigned Alignment = 0) {
-    return LValue::MakeAddr(V, T, Alignment, getContext());
+    return LValue::MakeAddr(V, T, Alignment, getContext(),
+                            CGM.getTBAAInfo(T));
   }
 
   /// CreateTempAlloca - This creates a alloca and inserts it into the entry
@@ -1349,13 +1350,15 @@ public:
   /// care to appropriately convert from the memory representation to
   /// the LLVM value representation.
   llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
-                                unsigned Alignment, QualType Ty);
+                                unsigned Alignment, QualType Ty,
+                                llvm::MDNode *TBAAInfo = 0);
 
   /// EmitStoreOfScalar - Store a scalar value to an address, taking
   /// care to appropriately convert from the memory representation to
   /// the LLVM value representation.
   void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
-                         bool Volatile, unsigned Alignment, QualType Ty);
+                         bool Volatile, unsigned Alignment, QualType Ty,
+                         llvm::MDNode *TBAAInfo = 0);
 
   /// EmitLoadOfLValue - Given an expression that represents a value lvalue,
   /// this method emits the address of the lvalue, then loads the result as an
index 805a82747da7873015a088b4504adb121a5ee310..660564d6fcbb50e103fa34ec348556549c71c63c 100644 (file)
@@ -14,6 +14,7 @@
 #include "CodeGenModule.h"
 #include "CGDebugInfo.h"
 #include "CodeGenFunction.h"
+#include "CodeGenTBAA.h"
 #include "CGCall.h"
 #include "CGCXXABI.h"
 #include "CGObjCRuntime.h"
@@ -62,6 +63,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
     TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags),
     ABI(createCXXABI(*this)), 
     Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI),
+    TBAA(0),
     VTables(*this), Runtime(0),
     CFConstantStringClassRef(0), NSConstantStringClassRef(0),
     VMContext(M.getContext()),
@@ -79,6 +81,10 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
   else
     Runtime = CreateMacObjCRuntime(*this);
 
+  // Enable TBAA unless it's suppressed.
+  if (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)
+    TBAA = new CodeGenTBAA(Context, VMContext, getLangOptions());
+
   // If debug info generation is enabled, create the CGDebugInfo object.
   DebugInfo = CodeGenOpts.DebugInfo ? new CGDebugInfo(*this) : 0;
 }
@@ -116,6 +122,17 @@ void CodeGenModule::Release() {
     EmitDeclMetadata();
 }
 
+llvm::MDNode *CodeGenModule::getTBAAInfo(QualType QTy) {
+  if (!TBAA)
+    return 0;
+  return TBAA->getTBAAInfo(QTy);
+}
+
+void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst,
+                                        llvm::MDNode *TBAAInfo) {
+  Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo);
+}
+
 bool CodeGenModule::isTargetDarwin() const {
   return getContext().Target.getTriple().getOS() == llvm::Triple::Darwin;
 }
index 898f9c3668f830a87fab5312dcabe65b19df778e..236b5b73e68d016f925e05a24cb576ee795350e8 100644 (file)
@@ -70,6 +70,7 @@ namespace clang {
 namespace CodeGen {
 
   class CodeGenFunction;
+  class CodeGenTBAA;
   class CGCXXABI;
   class CGDebugInfo;
   class CGObjCRuntime;
@@ -111,6 +112,7 @@ class CodeGenModule : public BlockModule {
   Diagnostic &Diags;
   CGCXXABI &ABI;
   CodeGenTypes Types;
+  CodeGenTBAA *TBAA;
 
   /// VTables - Holds information about C++ vtables.
   CodeGenVTables VTables;
@@ -250,6 +252,11 @@ public:
   const TargetCodeGenInfo &getTargetCodeGenInfo();
   bool isTargetDarwin() const;
 
+  llvm::MDNode *getTBAAInfo(QualType QTy);
+
+  static void DecorateInstruction(llvm::Instruction *Inst,
+                                  llvm::MDNode *TBAAInfo);
+
   /// getDeclVisibilityMode - Compute the visibility of the decl \arg D.
   LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const;
 
diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp
new file mode 100644 (file)
index 0000000..0039db8
--- /dev/null
@@ -0,0 +1,68 @@
+//===--- CodeGenTypes.cpp - TBAA information for LLVM CodeGen -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the code that manages TBAA information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenTBAA.h"
+#include "clang/AST/ASTContext.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Metadata.h"
+using namespace clang;
+using namespace CodeGen;
+
+CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext& VMContext,
+                         const LangOptions &Features)
+  : Context(Ctx), VMContext(VMContext), Features(Features), Root(0), Char(0) {
+}
+
+CodeGenTBAA::~CodeGenTBAA() {
+}
+
+llvm::MDNode *CodeGenTBAA::getTBAAInfoForNamedType(const char *NameStr,
+                                                   llvm::MDNode *Parent) {
+  llvm::Value *Ops[] = {
+    llvm::MDString::get(VMContext, NameStr),
+    Parent
+  };
+
+  return llvm::MDNode::get(VMContext, Ops, llvm::array_lengthof(Ops));
+}
+
+llvm::MDNode *
+CodeGenTBAA::getTBAAInfo(QualType QTy) {
+  Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
+
+  if (llvm::MDNode *N = MetadataCache[Ty])
+    return N;
+
+  if (!Root) {
+    Root = getTBAAInfoForNamedType("Experimental TBAA", 0);
+    Char = getTBAAInfoForNamedType("omnipotent char", Root);
+  }
+
+  // For now, just emit a very minimal tree.
+  const Type *CanonicalTy = Context.getCanonicalType(Ty);
+  if (const BuiltinType *BTy = dyn_cast<BuiltinType>(CanonicalTy)) {
+    switch (BTy->getKind()) {
+    case BuiltinType::Char_U:
+    case BuiltinType::Char_S:
+    case BuiltinType::UChar:
+    case BuiltinType::SChar:
+      // Charactar types are special.
+      return Char;
+    default:
+      return MetadataCache[Ty] =
+               getTBAAInfoForNamedType(BTy->getName(Features), Char);
+    }
+  }
+
+  return MetadataCache[Ty] = getTBAAInfoForNamedType("TBAA.other", Char);
+}
diff --git a/lib/CodeGen/CodeGenTBAA.h b/lib/CodeGen/CodeGenTBAA.h
new file mode 100644 (file)
index 0000000..8cfad3b
--- /dev/null
@@ -0,0 +1,67 @@
+//===--- CodeGenTBAA.h - TBAA information for LLVM CodeGen ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the code that manages TBAA information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CODEGENTBAA_H
+#define CLANG_CODEGEN_CODEGENTBAA_H
+
+#include "llvm/LLVMContext.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+  class LLVMContext;
+  class MDNode;
+}
+
+namespace clang {
+  class ASTContext;
+  class LangOptions;
+  class QualType;
+  class Type;
+
+namespace CodeGen {
+  class CGCXXABI;
+  class CGRecordLayout;
+
+/// CodeGenTBAA - This class organizes the cross-module state that is used
+/// while lowering AST types to LLVM types.
+class CodeGenTBAA {
+  ASTContext &Context;
+  llvm::LLVMContext& VMContext;
+  const LangOptions &Features;
+
+  /// MetadataCache - This maps clang::Types to llvm::MDNodes describing them.
+  llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache;
+
+  /// Root - This is the mdnode for the root of the metadata type graph
+  /// for this translation unit.
+  llvm::MDNode *Root;
+
+  /// Char - This is the mdnode for "char", which is special, and any types
+  /// considered to be equivalent to it.
+  llvm::MDNode *Char;
+
+  llvm::MDNode *getTBAAInfoForNamedType(const char *NameStr,
+                                        llvm::MDNode *Parent);
+
+public:
+  CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext,
+              const LangOptions &Features);
+  ~CodeGenTBAA();
+
+  llvm::MDNode *getTBAAInfo(QualType QTy);
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif