Experimental TBAA support.

This enables metadata generation by default, however the TBAA pass
in the optimizer is still disabled for now.

llvm-svn: 116536
This commit is contained in:
Dan Gohman 2010-10-14 23:06:10 +00:00
parent 0f58561907
commit 947c9af774
7 changed files with 191 additions and 10 deletions

View File

@ -13,6 +13,7 @@
#include "CodeGenFunction.h" #include "CodeGenFunction.h"
#include "CodeGenModule.h" #include "CodeGenModule.h"
#include "CodeGenTBAA.h"
#include "CGCall.h" #include "CGCall.h"
#include "CGCXXABI.h" #include "CGCXXABI.h"
#include "CGRecordLayout.h" #include "CGRecordLayout.h"
@ -580,12 +581,15 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
} }
llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, 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"); llvm::LoadInst *Load = Builder.CreateLoad(Addr, "tmp");
if (Volatile) if (Volatile)
Load->setVolatile(true); Load->setVolatile(true);
if (Alignment) if (Alignment)
Load->setAlignment(Alignment); Load->setAlignment(Alignment);
if (TBAAInfo)
CGM.DecorateInstruction(Load, TBAAInfo);
// Bool can have different representation in memory than in registers. // Bool can have different representation in memory than in registers.
llvm::Value *V = Load; llvm::Value *V = Load;
@ -604,7 +608,8 @@ static bool isBooleanUnderlyingType(QualType Ty) {
void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
bool Volatile, unsigned Alignment, bool Volatile, unsigned Alignment,
QualType Ty) { QualType Ty,
llvm::MDNode *TBAAInfo) {
if (Ty->isBooleanType() || isBooleanUnderlyingType(Ty)) { if (Ty->isBooleanType() || isBooleanUnderlyingType(Ty)) {
// Bool can have different representation in memory than in registers. // 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); llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile);
if (Alignment) if (Alignment)
Store->setAlignment(Alignment); Store->setAlignment(Alignment);
if (TBAAInfo)
CGM.DecorateInstruction(Store, TBAAInfo);
} }
/// EmitLoadOfLValue - Given an expression that represents a value lvalue, this /// 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. // Everything needs a load.
return RValue::get(EmitLoadOfScalar(Ptr, LV.isVolatileQualified(), 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"); assert(Src.isScalar() && "Can't emit an agg store with this method");
EmitStoreOfScalar(Src.getScalarVal(), Dst.getAddress(), EmitStoreOfScalar(Src.getScalarVal(), Dst.getAddress(),
Dst.isVolatileQualified(), Dst.getAlignment(), Ty); Dst.isVolatileQualified(), Dst.getAlignment(), Ty,
Dst.getTBAAInfo());
} }
void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,

View File

@ -157,8 +157,13 @@ class LValue {
bool ThreadLocalRef : 1; bool ThreadLocalRef : 1;
Expr *BaseIvarExp; Expr *BaseIvarExp;
/// TBAAInfo - TBAA information to attach to dereferences of this LValue.
llvm::MDNode *TBAAInfo;
private: private:
void Initialize(Qualifiers Quals, unsigned Alignment = 0) { void Initialize(Qualifiers Quals, unsigned Alignment = 0,
llvm::MDNode *TBAAInfo = 0) {
this->Quals = Quals; this->Quals = Quals;
this->Alignment = Alignment; this->Alignment = Alignment;
assert(this->Alignment == Alignment && "Alignment exceeds allowed max!"); assert(this->Alignment == Alignment && "Alignment exceeds allowed max!");
@ -167,6 +172,7 @@ private:
this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false; this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
this->ThreadLocalRef = false; this->ThreadLocalRef = false;
this->BaseIvarExp = 0; this->BaseIvarExp = 0;
this->TBAAInfo = TBAAInfo;
} }
public: public:
@ -208,6 +214,9 @@ public:
Expr *getBaseIvarExp() const { return BaseIvarExp; } Expr *getBaseIvarExp() const { return BaseIvarExp; }
void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } 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; } const Qualifiers &getQuals() const { return Quals; }
Qualifiers &getQuals() { return Quals; } Qualifiers &getQuals() { return Quals; }
@ -252,14 +261,15 @@ public:
} }
static LValue MakeAddr(llvm::Value *V, QualType T, unsigned Alignment, static LValue MakeAddr(llvm::Value *V, QualType T, unsigned Alignment,
ASTContext &Context) { ASTContext &Context,
llvm::MDNode *TBAAInfo = 0) {
Qualifiers Quals = Context.getCanonicalType(T).getQualifiers(); Qualifiers Quals = Context.getCanonicalType(T).getQualifiers();
Quals.setObjCGCAttr(Context.getObjCGCAttrKind(T)); Quals.setObjCGCAttr(Context.getObjCGCAttrKind(T));
LValue R; LValue R;
R.LVType = Simple; R.LVType = Simple;
R.V = V; R.V = V;
R.Initialize(Quals, Alignment); R.Initialize(Quals, Alignment, TBAAInfo);
return R; return R;
} }

View File

@ -1011,7 +1011,8 @@ public:
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
LValue MakeAddrLValue(llvm::Value *V, QualType T, unsigned Alignment = 0) { 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 /// 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 /// care to appropriately convert from the memory representation to
/// the LLVM value representation. /// the LLVM value representation.
llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, 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 /// EmitStoreOfScalar - Store a scalar value to an address, taking
/// care to appropriately convert from the memory representation to /// care to appropriately convert from the memory representation to
/// the LLVM value representation. /// the LLVM value representation.
void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, 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, /// EmitLoadOfLValue - Given an expression that represents a value lvalue,
/// this method emits the address of the lvalue, then loads the result as an /// this method emits the address of the lvalue, then loads the result as an

View File

@ -14,6 +14,7 @@
#include "CodeGenModule.h" #include "CodeGenModule.h"
#include "CGDebugInfo.h" #include "CGDebugInfo.h"
#include "CodeGenFunction.h" #include "CodeGenFunction.h"
#include "CodeGenTBAA.h"
#include "CGCall.h" #include "CGCall.h"
#include "CGCXXABI.h" #include "CGCXXABI.h"
#include "CGObjCRuntime.h" #include "CGObjCRuntime.h"
@ -62,6 +63,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags), TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags),
ABI(createCXXABI(*this)), ABI(createCXXABI(*this)),
Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI), Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI),
TBAA(0),
VTables(*this), Runtime(0), VTables(*this), Runtime(0),
CFConstantStringClassRef(0), NSConstantStringClassRef(0), CFConstantStringClassRef(0), NSConstantStringClassRef(0),
VMContext(M.getContext()), VMContext(M.getContext()),
@ -79,6 +81,10 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
else else
Runtime = CreateMacObjCRuntime(*this); 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. // If debug info generation is enabled, create the CGDebugInfo object.
DebugInfo = CodeGenOpts.DebugInfo ? new CGDebugInfo(*this) : 0; DebugInfo = CodeGenOpts.DebugInfo ? new CGDebugInfo(*this) : 0;
} }
@ -116,6 +122,17 @@ void CodeGenModule::Release() {
EmitDeclMetadata(); 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 { bool CodeGenModule::isTargetDarwin() const {
return getContext().Target.getTriple().getOS() == llvm::Triple::Darwin; return getContext().Target.getTriple().getOS() == llvm::Triple::Darwin;
} }

View File

@ -70,6 +70,7 @@ namespace clang {
namespace CodeGen { namespace CodeGen {
class CodeGenFunction; class CodeGenFunction;
class CodeGenTBAA;
class CGCXXABI; class CGCXXABI;
class CGDebugInfo; class CGDebugInfo;
class CGObjCRuntime; class CGObjCRuntime;
@ -111,6 +112,7 @@ class CodeGenModule : public BlockModule {
Diagnostic &Diags; Diagnostic &Diags;
CGCXXABI &ABI; CGCXXABI &ABI;
CodeGenTypes Types; CodeGenTypes Types;
CodeGenTBAA *TBAA;
/// VTables - Holds information about C++ vtables. /// VTables - Holds information about C++ vtables.
CodeGenVTables VTables; CodeGenVTables VTables;
@ -250,6 +252,11 @@ public:
const TargetCodeGenInfo &getTargetCodeGenInfo(); const TargetCodeGenInfo &getTargetCodeGenInfo();
bool isTargetDarwin() const; 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. /// getDeclVisibilityMode - Compute the visibility of the decl \arg D.
LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const; LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const;

View File

@ -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);
}

View File

@ -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