From 947c9af77497a67a6ee079e3afd1ec82059b5186 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 14 Oct 2010 23:06:10 +0000 Subject: [PATCH] Experimental TBAA support. This enables metadata generation by default, however the TBAA pass in the optimizer is still disabled for now. llvm-svn: 116536 --- clang/lib/CodeGen/CGExpr.cpp | 17 ++++++-- clang/lib/CodeGen/CGValue.h | 16 +++++-- clang/lib/CodeGen/CodeGenFunction.h | 9 ++-- clang/lib/CodeGen/CodeGenModule.cpp | 17 ++++++++ clang/lib/CodeGen/CodeGenModule.h | 7 +++ clang/lib/CodeGen/CodeGenTBAA.cpp | 68 +++++++++++++++++++++++++++++ clang/lib/CodeGen/CodeGenTBAA.h | 67 ++++++++++++++++++++++++++++ 7 files changed, 191 insertions(+), 10 deletions(-) create mode 100644 clang/lib/CodeGen/CodeGenTBAA.cpp create mode 100644 clang/lib/CodeGen/CodeGenTBAA.h diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 186c5ff42811..5b695cd52c33 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -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, diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h index ff19179db001..a000b223311e 100644 --- a/clang/lib/CodeGen/CGValue.h +++ b/clang/lib/CodeGen/CGValue.h @@ -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; } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 4e64319ae53e..6061b8fee8f8 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -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 diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 805a82747da7..660564d6fcbb 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -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; } diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 898f9c3668f8..236b5b73e68d 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -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/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp new file mode 100644 index 000000000000..0039db81b466 --- /dev/null +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -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(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/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h new file mode 100644 index 000000000000..8cfad3b6175a --- /dev/null +++ b/clang/lib/CodeGen/CodeGenTBAA.h @@ -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 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