r178784 - Index: include/clang/Driver/CC1Options.td

Manman Ren mren at apple.com
Thu Apr 4 15:47:28 PDT 2013


I accidentally used the "xxx.patch" instead of "xxx.comm" as the commit message.
When you do "svn log", it is going to show a long commit message. Not sure whether there is anyway to remove this long commit message.

I reverted and re-committed.

Thanks,
Manman

On Apr 4, 2013, at 2:17 PM, Richard Smith <richard at metafoo.co.uk> wrote:

> In order to get the commit message into svn history, would you mind reverting and re-committing with the message? Thanks!
> 
> 
> On Thu, Apr 4, 2013 at 2:08 PM, Manman Ren <mren at apple.com> wrote:
> Looks like I forgot to add -F :[
> I am outside having a late lunch.
> Will handle it when I get back.
> 
> Thanks
> Manman
> 
> On Apr 4, 2013, at 1:29 PM, Jim Grosbach <grosbach at apple.com> wrote:
> 
>> Hi Manman,
>> 
>> Was this an inadvertent early commit or something? Normally, I would expect a fairly lengthy commit message explaining a patch like this.
>> 
>> -Jim
>> 
>> On Apr 4, 2013, at 1:14 PM, Manman Ren <mren at apple.com> wrote:
>> 
>>> Author: mren
>>> Date: Thu Apr  4 15:14:17 2013
>>> New Revision: 178784
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=178784&view=rev
>>> Log:
>>> Index: include/clang/Driver/CC1Options.td
>>> ===================================================================
>>> --- include/clang/Driver/CC1Options.td	(revision 178718)
>>> +++ include/clang/Driver/CC1Options.td	(working copy)
>>> @@ -161,6 +161,8 @@
>>>   HelpText<"Use register sized accesses to bit-fields, when possible.">;
>>> def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">,
>>>   HelpText<"Turn off Type Based Alias Analysis">;
>>> +def struct_path_tbaa : Flag<["-"], "struct-path-tbaa">,
>>> +  HelpText<"Turn on struct-path aware Type Based Alias Analysis">;
>>> def masm_verbose : Flag<["-"], "masm-verbose">,
>>>   HelpText<"Generate verbose assembly output">;
>>> def mcode_model : Separate<["-"], "mcode-model">,
>>> Index: include/clang/Driver/Options.td
>>> ===================================================================
>>> --- include/clang/Driver/Options.td	(revision 178718)
>>> +++ include/clang/Driver/Options.td	(working copy)
>>> @@ -587,6 +587,7 @@
>>>   Flags<[CC1Option]>, HelpText<"Disable spell-checking">;
>>> def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>;
>>> def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>;
>>> +def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
>>> def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
>>> def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>;
>>> def fno_threadsafe_statics : Flag<["-"], "fno-threadsafe-statics">, Group<f_Group>,
>>> Index: include/clang/Frontend/CodeGenOptions.def
>>> ===================================================================
>>> --- include/clang/Frontend/CodeGenOptions.def	(revision 178718)
>>> +++ include/clang/Frontend/CodeGenOptions.def	(working copy)
>>> @@ -85,6 +85,7 @@
>>> VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
>>> CODEGENOPT(RelaxAll          , 1, 0) ///< Relax all machine code instructions.
>>> CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is enabled.
>>> +CODEGENOPT(StructPathTBAA    , 1, 0) ///< Whether or not to use struct-path TBAA.
>>> CODEGENOPT(SaveTempLabels    , 1, 0) ///< Save temporary labels.
>>> CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
>>>                                                  ///< offset in AddressSanitizer.
>>> Index: lib/CodeGen/CGExpr.cpp
>>> ===================================================================
>>> --- lib/CodeGen/CGExpr.cpp	(revision 178718)
>>> +++ lib/CodeGen/CGExpr.cpp	(working copy)
>>> @@ -1044,7 +1044,8 @@
>>> llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue) {
>>>   return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
>>>                           lvalue.getAlignment().getQuantity(),
>>> -                          lvalue.getType(), lvalue.getTBAAInfo());
>>> +                          lvalue.getType(), lvalue.getTBAAInfo(),
>>> +                          lvalue.getTBAABaseType(), lvalue.getTBAAOffset());
>>> }
>>> 
>>> static bool hasBooleanRepresentation(QualType Ty) {
>>> @@ -1106,7 +1107,9 @@
>>> 
>>> llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
>>>                                               unsigned Alignment, QualType Ty,
>>> -                                              llvm::MDNode *TBAAInfo) {
>>> +                                              llvm::MDNode *TBAAInfo,
>>> +                                              QualType TBAABaseType,
>>> +                                              uint64_t TBAAOffset) {
>>>   // For better performance, handle vector loads differently.
>>>   if (Ty->isVectorType()) {
>>>     llvm::Value *V;
>>> @@ -1158,8 +1161,11 @@
>>>     Load->setVolatile(true);
>>>   if (Alignment)
>>>     Load->setAlignment(Alignment);
>>> -  if (TBAAInfo)
>>> -    CGM.DecorateInstruction(Load, TBAAInfo);
>>> +  if (TBAAInfo) {
>>> +    llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,
>>> +                                                      TBAAOffset);
>>> +    CGM.DecorateInstruction(Load, TBAAPath);
>>> +  }
>>> 
>>>   if ((SanOpts->Bool && hasBooleanRepresentation(Ty)) ||
>>>       (SanOpts->Enum && Ty->getAs<EnumType>())) {
>>> @@ -1217,7 +1223,8 @@
>>>                                         bool Volatile, unsigned Alignment,
>>>                                         QualType Ty,
>>>                                         llvm::MDNode *TBAAInfo,
>>> -                                        bool isInit) {
>>> +                                        bool isInit, QualType TBAABaseType,
>>> +                                        uint64_t TBAAOffset) {
>>> 
>>>   // Handle vectors differently to get better performance.
>>>   if (Ty->isVectorType()) {
>>> @@ -1268,15 +1275,19 @@
>>>   llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile);
>>>   if (Alignment)
>>>     Store->setAlignment(Alignment);
>>> -  if (TBAAInfo)
>>> -    CGM.DecorateInstruction(Store, TBAAInfo);
>>> +  if (TBAAInfo) {
>>> +    llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,
>>> +                                                      TBAAOffset);
>>> +    CGM.DecorateInstruction(Store, TBAAPath);
>>> +  }
>>> }
>>> 
>>> void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue,
>>>                                         bool isInit) {
>>>   EmitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
>>>                     lvalue.getAlignment().getQuantity(), lvalue.getType(),
>>> -                    lvalue.getTBAAInfo(), isInit);
>>> +                    lvalue.getTBAAInfo(), isInit, lvalue.getTBAABaseType(),
>>> +                    lvalue.getTBAAOffset());
>>> }
>>> 
>>> /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
>>> @@ -2494,9 +2505,12 @@
>>> 
>>>   llvm::Value *addr = base.getAddress();
>>>   unsigned cvr = base.getVRQualifiers();
>>> +  bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA;
>>>   if (rec->isUnion()) {
>>>     // For unions, there is no pointer adjustment.
>>>     assert(!type->isReferenceType() && "union has reference member");
>>> +    // TODO: handle path-aware TBAA for union.
>>> +    TBAAPath = false;
>>>   } else {
>>>     // For structs, we GEP to the field that the record layout suggests.
>>>     unsigned idx = CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
>>> @@ -2508,6 +2522,8 @@
>>>       if (cvr & Qualifiers::Volatile) load->setVolatile(true);
>>>       load->setAlignment(alignment.getQuantity());
>>> 
>>> +      // Loading the reference will disable path-aware TBAA.
>>> +      TBAAPath = false;
>>>       if (CGM.shouldUseTBAA()) {
>>>         llvm::MDNode *tbaa;
>>>         if (mayAlias)
>>> @@ -2541,6 +2557,16 @@
>>> 
>>>   LValue LV = MakeAddrLValue(addr, type, alignment);
>>>   LV.getQuals().addCVRQualifiers(cvr);
>>> +  if (TBAAPath) {
>>> +    const ASTRecordLayout &Layout =
>>> +        getContext().getASTRecordLayout(field->getParent());
>>> +    // Set the base type to be the base type of the base LValue and
>>> +    // update offset to be relative to the base type.
>>> +    LV.setTBAABaseType(base.getTBAABaseType());
>>> +    LV.setTBAAOffset(base.getTBAAOffset() +
>>> +                     Layout.getFieldOffset(field->getFieldIndex()) /
>>> +                                           getContext().getCharWidth());
>>> +  }
>>> 
>>>   // __weak attribute on a field is ignored.
>>>   if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak)
>>> Index: lib/CodeGen/CGValue.h
>>> ===================================================================
>>> --- lib/CodeGen/CGValue.h	(revision 178718)
>>> +++ lib/CodeGen/CGValue.h	(working copy)
>>> @@ -157,6 +157,11 @@
>>> 
>>>   Expr *BaseIvarExp;
>>> 
>>> +  /// Used by struct-path-aware TBAA.
>>> +  QualType TBAABaseType;
>>> +  /// Offset relative to the base type.
>>> +  uint64_t TBAAOffset;
>>> +
>>>   /// TBAAInfo - TBAA information to attach to dereferences of this LValue.
>>>   llvm::MDNode *TBAAInfo;
>>> 
>>> @@ -175,6 +180,10 @@
>>>     this->ImpreciseLifetime = false;
>>>     this->ThreadLocalRef = false;
>>>     this->BaseIvarExp = 0;
>>> +
>>> +    // Initialize fields for TBAA.
>>> +    this->TBAABaseType = Type;
>>> +    this->TBAAOffset = 0;
>>>     this->TBAAInfo = TBAAInfo;
>>>   }
>>> 
>>> @@ -232,6 +241,12 @@
>>>   Expr *getBaseIvarExp() const { return BaseIvarExp; }
>>>   void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
>>> 
>>> +  QualType getTBAABaseType() const { return TBAABaseType; }
>>> +  void setTBAABaseType(QualType T) { TBAABaseType = T; }
>>> +
>>> +  uint64_t getTBAAOffset() const { return TBAAOffset; }
>>> +  void setTBAAOffset(uint64_t O) { TBAAOffset = O; }
>>> +
>>>   llvm::MDNode *getTBAAInfo() const { return TBAAInfo; }
>>>   void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; }
>>> 
>>> Index: lib/CodeGen/CodeGenFunction.h
>>> ===================================================================
>>> --- lib/CodeGen/CodeGenFunction.h	(revision 178718)
>>> +++ lib/CodeGen/CodeGenFunction.h	(working copy)
>>> @@ -2211,7 +2211,9 @@
>>>   /// the LLVM value representation.
>>>   llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
>>>                                 unsigned Alignment, QualType Ty,
>>> -                                llvm::MDNode *TBAAInfo = 0);
>>> +                                llvm::MDNode *TBAAInfo = 0,
>>> +                                QualType TBAABaseTy = QualType(),
>>> +                                uint64_t TBAAOffset = 0);
>>> 
>>>   /// EmitLoadOfScalar - Load a scalar value from an address, taking
>>>   /// care to appropriately convert from the memory representation to
>>> @@ -2224,7 +2226,9 @@
>>>   /// the LLVM value representation.
>>>   void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
>>>                          bool Volatile, unsigned Alignment, QualType Ty,
>>> -                         llvm::MDNode *TBAAInfo = 0, bool isInit=false);
>>> +                         llvm::MDNode *TBAAInfo = 0, bool isInit = false,
>>> +                         QualType TBAABaseTy = QualType(),
>>> +                         uint64_t TBAAOffset = 0);
>>> 
>>>   /// EmitStoreOfScalar - Store a scalar value to an address, taking
>>>   /// care to appropriately convert from the memory representation to
>>> Index: lib/CodeGen/CodeGenModule.cpp
>>> ===================================================================
>>> --- lib/CodeGen/CodeGenModule.cpp	(revision 178718)
>>> +++ lib/CodeGen/CodeGenModule.cpp	(working copy)
>>> @@ -227,6 +227,20 @@
>>>   return TBAA->getTBAAStructInfo(QTy);
>>> }
>>> 
>>> +llvm::MDNode *CodeGenModule::getTBAAStructTypeInfo(QualType QTy) {
>>> +  if (!TBAA)
>>> +    return 0;
>>> +  return TBAA->getTBAAStructTypeInfo(QTy);
>>> +}
>>> +
>>> +llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(QualType BaseTy,
>>> +                                                  llvm::MDNode *AccessN,
>>> +                                                  uint64_t O) {
>>> +  if (!TBAA)
>>> +    return 0;
>>> +  return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O);
>>> +}
>>> +
>>> void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst,
>>>                                         llvm::MDNode *TBAAInfo) {
>>>   Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo);
>>> Index: lib/CodeGen/CodeGenModule.h
>>> ===================================================================
>>> --- lib/CodeGen/CodeGenModule.h	(revision 178718)
>>> +++ lib/CodeGen/CodeGenModule.h	(working copy)
>>> @@ -501,6 +501,11 @@
>>>   llvm::MDNode *getTBAAInfo(QualType QTy);
>>>   llvm::MDNode *getTBAAInfoForVTablePtr();
>>>   llvm::MDNode *getTBAAStructInfo(QualType QTy);
>>> +  /// Return the MDNode in the type DAG for the given struct type.
>>> +  llvm::MDNode *getTBAAStructTypeInfo(QualType QTy);
>>> +  /// Return the path-aware tag for given base type, access node and offset.
>>> +  llvm::MDNode *getTBAAStructTagInfo(QualType BaseTy, llvm::MDNode *AccessN,
>>> +                                     uint64_t O);
>>> 
>>>   bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor);
>>> 
>>> Index: lib/CodeGen/CodeGenTBAA.cpp
>>> ===================================================================
>>> --- lib/CodeGen/CodeGenTBAA.cpp	(revision 178718)
>>> +++ lib/CodeGen/CodeGenTBAA.cpp	(working copy)
>>> @@ -21,6 +21,7 @@
>>> #include "clang/AST/Mangle.h"
>>> #include "clang/AST/RecordLayout.h"
>>> #include "clang/Frontend/CodeGenOptions.h"
>>> +#include "llvm/ADT/SmallSet.h"
>>> #include "llvm/IR/Constants.h"
>>> #include "llvm/IR/LLVMContext.h"
>>> #include "llvm/IR/Metadata.h"
>>> @@ -225,3 +226,87 @@
>>>   // For now, handle any other kind of type conservatively.
>>>   return StructMetadataCache[Ty] = NULL;
>>> }
>>> +
>>> +/// Check if the given type can be handled by path-aware TBAA.
>>> +static bool isTBAAPathStruct(QualType QTy) {
>>> +  if (const RecordType *TTy = QTy->getAs<RecordType>()) {
>>> +    const RecordDecl *RD = TTy->getDecl()->getDefinition();
>>> +    // RD can be struct, union, class, interface or enum.
>>> +    // For now, we only handle struct.
>>> +    if (RD->isStruct() && !RD->hasFlexibleArrayMember())
>>> +      return true;
>>> +  }
>>> +  return false;
>>> +}
>>> +
>>> +llvm::MDNode *
>>> +CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) {
>>> +  const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
>>> +  assert(isTBAAPathStruct(QTy));
>>> +
>>> +  if (llvm::MDNode *N = StructTypeMetadataCache[Ty])
>>> +    return N;
>>> +
>>> +  if (const RecordType *TTy = QTy->getAs<RecordType>()) {
>>> +    const RecordDecl *RD = TTy->getDecl()->getDefinition();
>>> +
>>> +    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
>>> +    SmallVector <std::pair<uint64_t, llvm::MDNode*>, 4> Fields;
>>> +    // To reduce the size of MDNode for a given struct type, we only output
>>> +    // once for all the fields with the same scalar types.
>>> +    // Offsets for scalar fields in the type DAG are not used.
>>> +    llvm::SmallSet <llvm::MDNode*, 4> ScalarFieldTypes;
>>> +    unsigned idx = 0;
>>> +    for (RecordDecl::field_iterator i = RD->field_begin(),
>>> +         e = RD->field_end(); i != e; ++i, ++idx) {
>>> +      QualType FieldQTy = i->getType();
>>> +      llvm::MDNode *FieldNode;
>>> +      if (isTBAAPathStruct(FieldQTy))
>>> +        FieldNode = getTBAAStructTypeInfo(FieldQTy);
>>> +      else {
>>> +        FieldNode = getTBAAInfo(FieldQTy);
>>> +        // Ignore this field if the type already exists.
>>> +        if (ScalarFieldTypes.count(FieldNode))
>>> +          continue;
>>> +        ScalarFieldTypes.insert(FieldNode);
>>> +       }
>>> +      if (!FieldNode)
>>> +        return StructTypeMetadataCache[Ty] = NULL;
>>> +      Fields.push_back(std::make_pair(
>>> +          Layout.getFieldOffset(idx) / Context.getCharWidth(), FieldNode));
>>> +    }
>>> +
>>> +    // TODO: This is using the RTTI name. Is there a better way to get
>>> +    // a unique string for a type?
>>> +    SmallString<256> OutName;
>>> +    llvm::raw_svector_ostream Out(OutName);
>>> +    MContext.mangleCXXRTTIName(QualType(Ty, 0), Out);
>>> +    Out.flush();
>>> +    // Create the struct type node with a vector of pairs (offset, type).
>>> +    return StructTypeMetadataCache[Ty] =
>>> +      MDHelper.createTBAAStructTypeNode(OutName, Fields);
>>> +  }
>>> +
>>> +  return StructMetadataCache[Ty] = NULL;
>>> +}
>>> +
>>> +llvm::MDNode *
>>> +CodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode,
>>> +                                  uint64_t Offset) {
>>> +  if (!CodeGenOpts.StructPathTBAA)
>>> +    return AccessNode;
>>> +
>>> +  const Type *BTy = Context.getCanonicalType(BaseQTy).getTypePtr();
>>> +  TBAAPathTag PathTag = TBAAPathTag(BTy, AccessNode, Offset);
>>> +  if (llvm::MDNode *N = StructTagMetadataCache[PathTag])
>>> +    return N;
>>> +
>>> +  llvm::MDNode *BNode = 0;
>>> +  if (isTBAAPathStruct(BaseQTy))
>>> +    BNode  = getTBAAStructTypeInfo(BaseQTy);
>>> +  if (!BNode)
>>> +    return StructTagMetadataCache[PathTag] = AccessNode;
>>> +
>>> +  return StructTagMetadataCache[PathTag] =
>>> +    MDHelper.createTBAAStructTagNode(BNode, AccessNode, Offset);
>>> +}
>>> Index: lib/CodeGen/CodeGenTBAA.h
>>> ===================================================================
>>> --- lib/CodeGen/CodeGenTBAA.h	(revision 178718)
>>> +++ lib/CodeGen/CodeGenTBAA.h	(working copy)
>>> @@ -35,6 +35,14 @@
>>> namespace CodeGen {
>>>   class CGRecordLayout;
>>> 
>>> +  struct TBAAPathTag {
>>> +    TBAAPathTag(const Type *B, const llvm::MDNode *A, uint64_t O)
>>> +      : BaseT(B), AccessN(A), Offset(O) {}
>>> +    const Type *BaseT;
>>> +    const llvm::MDNode *AccessN;
>>> +    uint64_t Offset;
>>> +  };
>>> +
>>> /// CodeGenTBAA - This class organizes the cross-module state that is used
>>> /// while lowering AST types to LLVM types.
>>> class CodeGenTBAA {
>>> @@ -46,8 +54,13 @@
>>>   // MDHelper - Helper for creating metadata.
>>>   llvm::MDBuilder MDHelper;
>>> 
>>> -  /// MetadataCache - This maps clang::Types to llvm::MDNodes describing them.
>>> +  /// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing
>>> +  /// them.
>>>   llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache;
>>> +  /// This maps clang::Types to a struct node in the type DAG.
>>> +  llvm::DenseMap<const Type *, llvm::MDNode *> StructTypeMetadataCache;
>>> +  /// This maps TBAAPathTags to a tag node.
>>> +  llvm::DenseMap<TBAAPathTag, llvm::MDNode *> StructTagMetadataCache;
>>> 
>>>   /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing
>>>   /// them for struct assignments.
>>> @@ -89,9 +102,49 @@
>>>   /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of
>>>   /// the given type.
>>>   llvm::MDNode *getTBAAStructInfo(QualType QTy);
>>> +
>>> +  /// Get the MDNode in the type DAG for given struct type QType.
>>> +  llvm::MDNode *getTBAAStructTypeInfo(QualType QType);
>>> +  /// Get the tag MDNode for a given base type, the actual sclar access MDNode
>>> +  /// and offset into the base type.
>>> +  llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType,
>>> +                                     llvm::MDNode *AccessNode, uint64_t Offset);
>>> };
>>> 
>>> }  // end namespace CodeGen
>>> }  // end namespace clang
>>> 
>>> +namespace llvm {
>>> +
>>> +template<> struct DenseMapInfo<clang::CodeGen::TBAAPathTag> {
>>> +  static clang::CodeGen::TBAAPathTag getEmptyKey() {
>>> +    return clang::CodeGen::TBAAPathTag(
>>> +      DenseMapInfo<const clang::Type *>::getEmptyKey(),
>>> +      DenseMapInfo<const MDNode *>::getEmptyKey(),
>>> +      DenseMapInfo<uint64_t>::getEmptyKey());
>>> +  }
>>> +
>>> +  static clang::CodeGen::TBAAPathTag getTombstoneKey() {
>>> +    return clang::CodeGen::TBAAPathTag(
>>> +      DenseMapInfo<const clang::Type *>::getTombstoneKey(),
>>> +      DenseMapInfo<const MDNode *>::getTombstoneKey(),
>>> +      DenseMapInfo<uint64_t>::getTombstoneKey());
>>> +  }
>>> +
>>> +  static unsigned getHashValue(const clang::CodeGen::TBAAPathTag &Val) {
>>> +    return DenseMapInfo<const clang::Type *>::getHashValue(Val.BaseT) ^
>>> +           DenseMapInfo<const MDNode *>::getHashValue(Val.AccessN) ^
>>> +           DenseMapInfo<uint64_t>::getHashValue(Val.Offset);
>>> +  }
>>> +
>>> +  static bool isEqual(const clang::CodeGen::TBAAPathTag &LHS,
>>> +                      const clang::CodeGen::TBAAPathTag &RHS) {
>>> +    return LHS.BaseT == RHS.BaseT &&
>>> +           LHS.AccessN == RHS.AccessN &&
>>> +           LHS.Offset == RHS.Offset;
>>> +  }
>>> +};
>>> +
>>> +}  // end namespace llvm
>>> +
>>> #endif
>>> Index: lib/Driver/Tools.cpp
>>> ===================================================================
>>> --- lib/Driver/Tools.cpp	(revision 178718)
>>> +++ lib/Driver/Tools.cpp	(working copy)
>>> @@ -2105,6 +2105,8 @@
>>>                     options::OPT_fno_strict_aliasing,
>>>                     getToolChain().IsStrictAliasingDefault()))
>>>     CmdArgs.push_back("-relaxed-aliasing");
>>> +  if (Args.hasArg(options::OPT_fstruct_path_tbaa))
>>> +    CmdArgs.push_back("-struct-path-tbaa");
>>>   if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
>>>                    false))
>>>     CmdArgs.push_back("-fstrict-enums");
>>> Index: lib/Frontend/CompilerInvocation.cpp
>>> ===================================================================
>>> --- lib/Frontend/CompilerInvocation.cpp	(revision 178718)
>>> +++ lib/Frontend/CompilerInvocation.cpp	(working copy)
>>> @@ -324,6 +324,7 @@
>>>   Opts.UseRegisterSizedBitfieldAccess = Args.hasArg(
>>>     OPT_fuse_register_sized_bitfield_access);
>>>   Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing);
>>> +  Opts.StructPathTBAA = Args.hasArg(OPT_struct_path_tbaa);
>>>   Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags);
>>>   Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants);
>>>   Opts.NoCommon = Args.hasArg(OPT_fno_common);
>>> Index: test/CodeGen/tbaa.cpp
>>> ===================================================================
>>> --- test/CodeGen/tbaa.cpp	(revision 0)
>>> +++ test/CodeGen/tbaa.cpp	(working copy)
>>> @@ -0,0 +1,217 @@
>>> +// RUN: %clang_cc1 -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
>>> +// RUN: %clang_cc1 -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
>>> +// Test TBAA metadata generated by front-end.
>>> +
>>> +#include <stdint.h>
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   uint32_t f32;
>>> +   uint16_t f16_2;
>>> +   uint32_t f32_2;
>>> +} StructA;
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   StructA a;
>>> +   uint32_t f32;
>>> +} StructB;
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   StructB b;
>>> +   uint32_t f32;
>>> +} StructC;
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   StructB b;
>>> +   uint32_t f32;
>>> +   uint8_t f8;
>>> +} StructD;
>>> +
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   uint32_t f32;
>>> +} StructS;
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   uint32_t f32;
>>> +} StructS2;
>>> +
>>> +uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !5
>>> +  *s = 1;
>>> +  A->f32 = 4;
>>> +  return *s;
>>> +}
>>> +
>>> +uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !8
>>> +  *s = 1;
>>> +  A->f16 = 4;
>>> +  return *s;
>>> +}
>>> +
>>> +uint32_t g3(StructA *A, StructB *B, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9
>>> +  A->f32 = 1;
>>> +  B->a.f32 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g4(StructA *A, StructB *B, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !11
>>> +  A->f32 = 1;
>>> +  B->a.f16 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g5(StructA *A, StructB *B, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !12
>>> +  A->f32 = 1;
>>> +  B->f32 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g6(StructA *A, StructB *B, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !13
>>> +  A->f32 = 1;
>>> +  B->a.f32_2 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g7(StructA *A, StructS *S, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !14
>>> +  A->f32 = 1;
>>> +  S->f32 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g8(StructA *A, StructS *S, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !16
>>> +  A->f32 = 1;
>>> +  S->f16 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !17
>>> +  S->f32 = 1;
>>> +  S2->f32 = 4;
>>> +  return S->f32;
>>> +}
>>> +
>>> +uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14
>>> +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !19
>>> +  S->f32 = 1;
>>> +  S2->f16 = 4;
>>> +  return S->f32;
>>> +}
>>> +
>>> +uint32_t g11(StructC *C, StructD *D, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !20
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !22
>>> +  C->b.a.f32 = 1;
>>> +  D->b.a.f32 = 4;
>>> +  return C->b.a.f32;
>>> +}
>>> +
>>> +uint32_t g12(StructC *C, StructD *D, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// TODO: differentiate the two accesses.
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !9
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9
>>> +  StructB *b1 = &(C->b);
>>> +  StructB *b2 = &(D->b);
>>> +  // b1, b2 have different context.
>>> +  b1->a.f32 = 1;
>>> +  b2->a.f32 = 4;
>>> +  return b1->a.f32;
>>> +}
>>> +
>>> +// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2}
>>> +// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"}
>>> +// CHECK: !4 = metadata !{metadata !"int", metadata !1}
>>> +// CHECK: !5 = metadata !{metadata !"short", metadata !1}
>>> +
>>> +// PATH: !1 = metadata !{metadata !"omnipotent char", metadata !2}
>>> +// PATH: !4 = metadata !{metadata !"int", metadata !1}
>>> +// PATH: !5 = metadata !{metadata !6, metadata !4, i64 4}
>>> +// PATH: !6 = metadata !{metadata !"_ZTS7StructA", i64 0, metadata !7, i64 4, metadata !4}
>>> +// PATH: !7 = metadata !{metadata !"short", metadata !1}
>>> +// PATH: !8 = metadata !{metadata !6, metadata !7, i64 0}
>>> +// PATH: !9 = metadata !{metadata !10, metadata !4, i64 8}
>>> +// PATH: !10 = metadata !{metadata !"_ZTS7StructB", i64 0, metadata !7, i64 4, metadata !6, i64 20, metadata !4}
>>> +// PATH: !11 = metadata !{metadata !10, metadata !7, i64 4}
>>> +// PATH: !12 = metadata !{metadata !10, metadata !4, i64 20}
>>> +// PATH: !13 = metadata !{metadata !10, metadata !4, i64 16}
>>> +// PATH: !14 = metadata !{metadata !15, metadata !4, i64 4}
>>> +// PATH: !15 = metadata !{metadata !"_ZTS7StructS", i64 0, metadata !7, i64 4, metadata !4}
>>> +// PATH: !16 = metadata !{metadata !15, metadata !7, i64 0}
>>> +// PATH: !17 = metadata !{metadata !18, metadata !4, i64 4}
>>> +// PATH: !18 = metadata !{metadata !"_ZTS8StructS2", i64 0, metadata !7, i64 4, metadata !4}
>>> +// PATH: !19 = metadata !{metadata !18, metadata !7, i64 0}
>>> +// PATH: !20 = metadata !{metadata !21, metadata !4, i64 12}
>>> +// PATH: !21 = metadata !{metadata !"_ZTS7StructC", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4}
>>> +// PATH: !22 = metadata !{metadata !23, metadata !4, i64 12}
>>> +// PATH: !23 = metadata !{metadata !"_ZTS7StructD", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4, i64 32, metadata !1}
>>> 
>>> Added:
>>>    cfe/trunk/test/CodeGen/tbaa.cpp
>>> Modified:
>>>    cfe/trunk/include/clang/Driver/CC1Options.td
>>>    cfe/trunk/include/clang/Driver/Options.td
>>>    cfe/trunk/include/clang/Frontend/CodeGenOptions.def
>>>    cfe/trunk/lib/CodeGen/CGExpr.cpp
>>>    cfe/trunk/lib/CodeGen/CGValue.h
>>>    cfe/trunk/lib/CodeGen/CodeGenFunction.h
>>>    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>>>    cfe/trunk/lib/CodeGen/CodeGenModule.h
>>>    cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp
>>>    cfe/trunk/lib/CodeGen/CodeGenTBAA.h
>>>    cfe/trunk/lib/Driver/Tools.cpp
>>>    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
>>> 
>>> Modified: cfe/trunk/include/clang/Driver/CC1Options.td
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/include/clang/Driver/CC1Options.td (original)
>>> +++ cfe/trunk/include/clang/Driver/CC1Options.td Thu Apr  4 15:14:17 2013
>>> @@ -161,6 +161,8 @@ def fuse_register_sized_bitfield_access:
>>>   HelpText<"Use register sized accesses to bit-fields, when possible.">;
>>> def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">,
>>>   HelpText<"Turn off Type Based Alias Analysis">;
>>> +def struct_path_tbaa : Flag<["-"], "struct-path-tbaa">,
>>> +  HelpText<"Turn on struct-path aware Type Based Alias Analysis">;
>>> def masm_verbose : Flag<["-"], "masm-verbose">,
>>>   HelpText<"Generate verbose assembly output">;
>>> def mcode_model : Separate<["-"], "mcode-model">,
>>> 
>>> Modified: cfe/trunk/include/clang/Driver/Options.td
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/include/clang/Driver/Options.td (original)
>>> +++ cfe/trunk/include/clang/Driver/Options.td Thu Apr  4 15:14:17 2013
>>> @@ -587,6 +587,7 @@ def fno_spell_checking : Flag<["-"], "fn
>>>   Flags<[CC1Option]>, HelpText<"Disable spell-checking">;
>>> def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>;
>>> def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>;
>>> +def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
>>> def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
>>> def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>;
>>> def fno_threadsafe_statics : Flag<["-"], "fno-threadsafe-statics">, Group<f_Group>,
>>> 
>>> Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.def
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original)
>>> +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Thu Apr  4 15:14:17 2013
>>> @@ -86,6 +86,7 @@ VALUE_CODEGENOPT(OptimizationLevel, 3, 0
>>> VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
>>> CODEGENOPT(RelaxAll          , 1, 0) ///< Relax all machine code instructions.
>>> CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is enabled.
>>> +CODEGENOPT(StructPathTBAA    , 1, 0) ///< Whether or not to use struct-path TBAA.
>>> CODEGENOPT(SaveTempLabels    , 1, 0) ///< Save temporary labels.
>>> CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
>>>                                                  ///< offset in AddressSanitizer.
>>> 
>>> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
>>> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Apr  4 15:14:17 2013
>>> @@ -1044,7 +1044,8 @@ CodeGenFunction::tryEmitAsConstant(DeclR
>>> llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue) {
>>>   return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
>>>                           lvalue.getAlignment().getQuantity(),
>>> -                          lvalue.getType(), lvalue.getTBAAInfo());
>>> +                          lvalue.getType(), lvalue.getTBAAInfo(),
>>> +                          lvalue.getTBAABaseType(), lvalue.getTBAAOffset());
>>> }
>>> 
>>> static bool hasBooleanRepresentation(QualType Ty) {
>>> @@ -1106,7 +1107,9 @@ llvm::MDNode *CodeGenFunction::getRangeF
>>> 
>>> llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
>>>                                               unsigned Alignment, QualType Ty,
>>> -                                              llvm::MDNode *TBAAInfo) {
>>> +                                              llvm::MDNode *TBAAInfo,
>>> +                                              QualType TBAABaseType,
>>> +                                              uint64_t TBAAOffset) {
>>>   // For better performance, handle vector loads differently.
>>>   if (Ty->isVectorType()) {
>>>     llvm::Value *V;
>>> @@ -1158,8 +1161,11 @@ llvm::Value *CodeGenFunction::EmitLoadOf
>>>     Load->setVolatile(true);
>>>   if (Alignment)
>>>     Load->setAlignment(Alignment);
>>> -  if (TBAAInfo)
>>> -    CGM.DecorateInstruction(Load, TBAAInfo);
>>> +  if (TBAAInfo) {
>>> +    llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,
>>> +                                                      TBAAOffset);
>>> +    CGM.DecorateInstruction(Load, TBAAPath);
>>> +  }
>>> 
>>>   if ((SanOpts->Bool && hasBooleanRepresentation(Ty)) ||
>>>       (SanOpts->Enum && Ty->getAs<EnumType>())) {
>>> @@ -1217,7 +1223,8 @@ void CodeGenFunction::EmitStoreOfScalar(
>>>                                         bool Volatile, unsigned Alignment,
>>>                                         QualType Ty,
>>>                                         llvm::MDNode *TBAAInfo,
>>> -                                        bool isInit) {
>>> +                                        bool isInit, QualType TBAABaseType,
>>> +                                        uint64_t TBAAOffset) {
>>> 
>>>   // Handle vectors differently to get better performance.
>>>   if (Ty->isVectorType()) {
>>> @@ -1268,15 +1275,19 @@ void CodeGenFunction::EmitStoreOfScalar(
>>>   llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile);
>>>   if (Alignment)
>>>     Store->setAlignment(Alignment);
>>> -  if (TBAAInfo)
>>> -    CGM.DecorateInstruction(Store, TBAAInfo);
>>> +  if (TBAAInfo) {
>>> +    llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,
>>> +                                                      TBAAOffset);
>>> +    CGM.DecorateInstruction(Store, TBAAPath);
>>> +  }
>>> }
>>> 
>>> void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue,
>>>                                         bool isInit) {
>>>   EmitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
>>>                     lvalue.getAlignment().getQuantity(), lvalue.getType(),
>>> -                    lvalue.getTBAAInfo(), isInit);
>>> +                    lvalue.getTBAAInfo(), isInit, lvalue.getTBAABaseType(),
>>> +                    lvalue.getTBAAOffset());
>>> }
>>> 
>>> /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
>>> @@ -2494,9 +2505,12 @@ LValue CodeGenFunction::EmitLValueForFie
>>> 
>>>   llvm::Value *addr = base.getAddress();
>>>   unsigned cvr = base.getVRQualifiers();
>>> +  bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA;
>>>   if (rec->isUnion()) {
>>>     // For unions, there is no pointer adjustment.
>>>     assert(!type->isReferenceType() && "union has reference member");
>>> +    // TODO: handle path-aware TBAA for union.
>>> +    TBAAPath = false;
>>>   } else {
>>>     // For structs, we GEP to the field that the record layout suggests.
>>>     unsigned idx = CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
>>> @@ -2508,6 +2522,8 @@ LValue CodeGenFunction::EmitLValueForFie
>>>       if (cvr & Qualifiers::Volatile) load->setVolatile(true);
>>>       load->setAlignment(alignment.getQuantity());
>>> 
>>> +      // Loading the reference will disable path-aware TBAA.
>>> +      TBAAPath = false;
>>>       if (CGM.shouldUseTBAA()) {
>>>         llvm::MDNode *tbaa;
>>>         if (mayAlias)
>>> @@ -2541,6 +2557,16 @@ LValue CodeGenFunction::EmitLValueForFie
>>> 
>>>   LValue LV = MakeAddrLValue(addr, type, alignment);
>>>   LV.getQuals().addCVRQualifiers(cvr);
>>> +  if (TBAAPath) {
>>> +    const ASTRecordLayout &Layout =
>>> +        getContext().getASTRecordLayout(field->getParent());
>>> +    // Set the base type to be the base type of the base LValue and
>>> +    // update offset to be relative to the base type.
>>> +    LV.setTBAABaseType(base.getTBAABaseType());
>>> +    LV.setTBAAOffset(base.getTBAAOffset() +
>>> +                     Layout.getFieldOffset(field->getFieldIndex()) /
>>> +                                           getContext().getCharWidth());
>>> +  }
>>> 
>>>   // __weak attribute on a field is ignored.
>>>   if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak)
>>> 
>>> Modified: cfe/trunk/lib/CodeGen/CGValue.h
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGValue.h?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/lib/CodeGen/CGValue.h (original)
>>> +++ cfe/trunk/lib/CodeGen/CGValue.h Thu Apr  4 15:14:17 2013
>>> @@ -157,6 +157,11 @@ class LValue {
>>> 
>>>   Expr *BaseIvarExp;
>>> 
>>> +  /// Used by struct-path-aware TBAA.
>>> +  QualType TBAABaseType;
>>> +  /// Offset relative to the base type.
>>> +  uint64_t TBAAOffset;
>>> +
>>>   /// TBAAInfo - TBAA information to attach to dereferences of this LValue.
>>>   llvm::MDNode *TBAAInfo;
>>> 
>>> @@ -175,6 +180,10 @@ private:
>>>     this->ImpreciseLifetime = false;
>>>     this->ThreadLocalRef = false;
>>>     this->BaseIvarExp = 0;
>>> +
>>> +    // Initialize fields for TBAA.
>>> +    this->TBAABaseType = Type;
>>> +    this->TBAAOffset = 0;
>>>     this->TBAAInfo = TBAAInfo;
>>>   }
>>> 
>>> @@ -232,6 +241,12 @@ public:
>>>   Expr *getBaseIvarExp() const { return BaseIvarExp; }
>>>   void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
>>> 
>>> +  QualType getTBAABaseType() const { return TBAABaseType; }
>>> +  void setTBAABaseType(QualType T) { TBAABaseType = T; }
>>> +
>>> +  uint64_t getTBAAOffset() const { return TBAAOffset; }
>>> +  void setTBAAOffset(uint64_t O) { TBAAOffset = O; }
>>> +
>>>   llvm::MDNode *getTBAAInfo() const { return TBAAInfo; }
>>>   void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; }
>>> 
>>> 
>>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
>>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Apr  4 15:14:17 2013
>>> @@ -2211,7 +2211,9 @@ public:
>>>   /// the LLVM value representation.
>>>   llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
>>>                                 unsigned Alignment, QualType Ty,
>>> -                                llvm::MDNode *TBAAInfo = 0);
>>> +                                llvm::MDNode *TBAAInfo = 0,
>>> +                                QualType TBAABaseTy = QualType(),
>>> +                                uint64_t TBAAOffset = 0);
>>> 
>>>   /// EmitLoadOfScalar - Load a scalar value from an address, taking
>>>   /// care to appropriately convert from the memory representation to
>>> @@ -2224,7 +2226,9 @@ public:
>>>   /// the LLVM value representation.
>>>   void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
>>>                          bool Volatile, unsigned Alignment, QualType Ty,
>>> -                         llvm::MDNode *TBAAInfo = 0, bool isInit=false);
>>> +                         llvm::MDNode *TBAAInfo = 0, bool isInit = false,
>>> +                         QualType TBAABaseTy = QualType(),
>>> +                         uint64_t TBAAOffset = 0);
>>> 
>>>   /// EmitStoreOfScalar - Store a scalar value to an address, taking
>>>   /// care to appropriately convert from the memory representation to
>>> 
>>> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
>>> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu Apr  4 15:14:17 2013
>>> @@ -227,6 +227,20 @@ llvm::MDNode *CodeGenModule::getTBAAStru
>>>   return TBAA->getTBAAStructInfo(QTy);
>>> }
>>> 
>>> +llvm::MDNode *CodeGenModule::getTBAAStructTypeInfo(QualType QTy) {
>>> +  if (!TBAA)
>>> +    return 0;
>>> +  return TBAA->getTBAAStructTypeInfo(QTy);
>>> +}
>>> +
>>> +llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(QualType BaseTy,
>>> +                                                  llvm::MDNode *AccessN,
>>> +                                                  uint64_t O) {
>>> +  if (!TBAA)
>>> +    return 0;
>>> +  return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O);
>>> +}
>>> +
>>> void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst,
>>>                                         llvm::MDNode *TBAAInfo) {
>>>   Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo);
>>> 
>>> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
>>> +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Thu Apr  4 15:14:17 2013
>>> @@ -501,6 +501,11 @@ public:
>>>   llvm::MDNode *getTBAAInfo(QualType QTy);
>>>   llvm::MDNode *getTBAAInfoForVTablePtr();
>>>   llvm::MDNode *getTBAAStructInfo(QualType QTy);
>>> +  /// Return the MDNode in the type DAG for the given struct type.
>>> +  llvm::MDNode *getTBAAStructTypeInfo(QualType QTy);
>>> +  /// Return the path-aware tag for given base type, access node and offset.
>>> +  llvm::MDNode *getTBAAStructTagInfo(QualType BaseTy, llvm::MDNode *AccessN,
>>> +                                     uint64_t O);
>>> 
>>>   bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor);
>>> 
>>> 
>>> Modified: cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp (original)
>>> +++ cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp Thu Apr  4 15:14:17 2013
>>> @@ -21,6 +21,7 @@
>>> #include "clang/AST/Mangle.h"
>>> #include "clang/AST/RecordLayout.h"
>>> #include "clang/Frontend/CodeGenOptions.h"
>>> +#include "llvm/ADT/SmallSet.h"
>>> #include "llvm/IR/Constants.h"
>>> #include "llvm/IR/LLVMContext.h"
>>> #include "llvm/IR/Metadata.h"
>>> @@ -225,3 +226,87 @@ CodeGenTBAA::getTBAAStructInfo(QualType
>>>   // For now, handle any other kind of type conservatively.
>>>   return StructMetadataCache[Ty] = NULL;
>>> }
>>> +
>>> +/// Check if the given type can be handled by path-aware TBAA.
>>> +static bool isTBAAPathStruct(QualType QTy) {
>>> +  if (const RecordType *TTy = QTy->getAs<RecordType>()) {
>>> +    const RecordDecl *RD = TTy->getDecl()->getDefinition();
>>> +    // RD can be struct, union, class, interface or enum.
>>> +    // For now, we only handle struct.
>>> +    if (RD->isStruct() && !RD->hasFlexibleArrayMember())
>>> +      return true;
>>> +  }
>>> +  return false;
>>> +}
>>> +
>>> +llvm::MDNode *
>>> +CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) {
>>> +  const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
>>> +  assert(isTBAAPathStruct(QTy));
>>> +
>>> +  if (llvm::MDNode *N = StructTypeMetadataCache[Ty])
>>> +    return N;
>>> +
>>> +  if (const RecordType *TTy = QTy->getAs<RecordType>()) {
>>> +    const RecordDecl *RD = TTy->getDecl()->getDefinition();
>>> +
>>> +    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
>>> +    SmallVector <std::pair<uint64_t, llvm::MDNode*>, 4> Fields;
>>> +    // To reduce the size of MDNode for a given struct type, we only output
>>> +    // once for all the fields with the same scalar types.
>>> +    // Offsets for scalar fields in the type DAG are not used.
>>> +    llvm::SmallSet <llvm::MDNode*, 4> ScalarFieldTypes;
>>> +    unsigned idx = 0;
>>> +    for (RecordDecl::field_iterator i = RD->field_begin(),
>>> +         e = RD->field_end(); i != e; ++i, ++idx) {
>>> +      QualType FieldQTy = i->getType();
>>> +      llvm::MDNode *FieldNode;
>>> +      if (isTBAAPathStruct(FieldQTy))
>>> +        FieldNode = getTBAAStructTypeInfo(FieldQTy);
>>> +      else {
>>> +        FieldNode = getTBAAInfo(FieldQTy);
>>> +        // Ignore this field if the type already exists.
>>> +        if (ScalarFieldTypes.count(FieldNode))
>>> +          continue;
>>> +        ScalarFieldTypes.insert(FieldNode);
>>> +       }
>>> +      if (!FieldNode)
>>> +        return StructTypeMetadataCache[Ty] = NULL;
>>> +      Fields.push_back(std::make_pair(
>>> +          Layout.getFieldOffset(idx) / Context.getCharWidth(), FieldNode));
>>> +    }
>>> +
>>> +    // TODO: This is using the RTTI name. Is there a better way to get
>>> +    // a unique string for a type?
>>> +    SmallString<256> OutName;
>>> +    llvm::raw_svector_ostream Out(OutName);
>>> +    MContext.mangleCXXRTTIName(QualType(Ty, 0), Out);
>>> +    Out.flush();
>>> +    // Create the struct type node with a vector of pairs (offset, type).
>>> +    return StructTypeMetadataCache[Ty] =
>>> +      MDHelper.createTBAAStructTypeNode(OutName, Fields);
>>> +  }
>>> +
>>> +  return StructMetadataCache[Ty] = NULL;
>>> +}
>>> +
>>> +llvm::MDNode *
>>> +CodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode,
>>> +                                  uint64_t Offset) {
>>> +  if (!CodeGenOpts.StructPathTBAA)
>>> +    return AccessNode;
>>> +
>>> +  const Type *BTy = Context.getCanonicalType(BaseQTy).getTypePtr();
>>> +  TBAAPathTag PathTag = TBAAPathTag(BTy, AccessNode, Offset);
>>> +  if (llvm::MDNode *N = StructTagMetadataCache[PathTag])
>>> +    return N;
>>> +
>>> +  llvm::MDNode *BNode = 0;
>>> +  if (isTBAAPathStruct(BaseQTy))
>>> +    BNode  = getTBAAStructTypeInfo(BaseQTy);
>>> +  if (!BNode)
>>> +    return StructTagMetadataCache[PathTag] = AccessNode;
>>> +
>>> +  return StructTagMetadataCache[PathTag] =
>>> +    MDHelper.createTBAAStructTagNode(BNode, AccessNode, Offset);
>>> +}
>>> 
>>> Modified: cfe/trunk/lib/CodeGen/CodeGenTBAA.h
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTBAA.h?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/lib/CodeGen/CodeGenTBAA.h (original)
>>> +++ cfe/trunk/lib/CodeGen/CodeGenTBAA.h Thu Apr  4 15:14:17 2013
>>> @@ -35,6 +35,14 @@ namespace clang {
>>> namespace CodeGen {
>>>   class CGRecordLayout;
>>> 
>>> +  struct TBAAPathTag {
>>> +    TBAAPathTag(const Type *B, const llvm::MDNode *A, uint64_t O)
>>> +      : BaseT(B), AccessN(A), Offset(O) {}
>>> +    const Type *BaseT;
>>> +    const llvm::MDNode *AccessN;
>>> +    uint64_t Offset;
>>> +  };
>>> +
>>> /// CodeGenTBAA - This class organizes the cross-module state that is used
>>> /// while lowering AST types to LLVM types.
>>> class CodeGenTBAA {
>>> @@ -46,8 +54,13 @@ class CodeGenTBAA {
>>>   // MDHelper - Helper for creating metadata.
>>>   llvm::MDBuilder MDHelper;
>>> 
>>> -  /// MetadataCache - This maps clang::Types to llvm::MDNodes describing them.
>>> +  /// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing
>>> +  /// them.
>>>   llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache;
>>> +  /// This maps clang::Types to a struct node in the type DAG.
>>> +  llvm::DenseMap<const Type *, llvm::MDNode *> StructTypeMetadataCache;
>>> +  /// This maps TBAAPathTags to a tag node.
>>> +  llvm::DenseMap<TBAAPathTag, llvm::MDNode *> StructTagMetadataCache;
>>> 
>>>   /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing
>>>   /// them for struct assignments.
>>> @@ -89,9 +102,49 @@ public:
>>>   /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of
>>>   /// the given type.
>>>   llvm::MDNode *getTBAAStructInfo(QualType QTy);
>>> +
>>> +  /// Get the MDNode in the type DAG for given struct type QType.
>>> +  llvm::MDNode *getTBAAStructTypeInfo(QualType QType);
>>> +  /// Get the tag MDNode for a given base type, the actual sclar access MDNode
>>> +  /// and offset into the base type.
>>> +  llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType,
>>> +                                     llvm::MDNode *AccessNode, uint64_t Offset);
>>> };
>>> 
>>> }  // end namespace CodeGen
>>> }  // end namespace clang
>>> 
>>> +namespace llvm {
>>> +
>>> +template<> struct DenseMapInfo<clang::CodeGen::TBAAPathTag> {
>>> +  static clang::CodeGen::TBAAPathTag getEmptyKey() {
>>> +    return clang::CodeGen::TBAAPathTag(
>>> +      DenseMapInfo<const clang::Type *>::getEmptyKey(),
>>> +      DenseMapInfo<const MDNode *>::getEmptyKey(),
>>> +      DenseMapInfo<uint64_t>::getEmptyKey());
>>> +  }
>>> +
>>> +  static clang::CodeGen::TBAAPathTag getTombstoneKey() {
>>> +    return clang::CodeGen::TBAAPathTag(
>>> +      DenseMapInfo<const clang::Type *>::getTombstoneKey(),
>>> +      DenseMapInfo<const MDNode *>::getTombstoneKey(),
>>> +      DenseMapInfo<uint64_t>::getTombstoneKey());
>>> +  }
>>> +
>>> +  static unsigned getHashValue(const clang::CodeGen::TBAAPathTag &Val) {
>>> +    return DenseMapInfo<const clang::Type *>::getHashValue(Val.BaseT) ^
>>> +           DenseMapInfo<const MDNode *>::getHashValue(Val.AccessN) ^
>>> +           DenseMapInfo<uint64_t>::getHashValue(Val.Offset);
>>> +  }
>>> +
>>> +  static bool isEqual(const clang::CodeGen::TBAAPathTag &LHS,
>>> +                      const clang::CodeGen::TBAAPathTag &RHS) {
>>> +    return LHS.BaseT == RHS.BaseT &&
>>> +           LHS.AccessN == RHS.AccessN &&
>>> +           LHS.Offset == RHS.Offset;
>>> +  }
>>> +};
>>> +
>>> +}  // end namespace llvm
>>> +
>>> #endif
>>> 
>>> Modified: cfe/trunk/lib/Driver/Tools.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/lib/Driver/Tools.cpp (original)
>>> +++ cfe/trunk/lib/Driver/Tools.cpp Thu Apr  4 15:14:17 2013
>>> @@ -2105,6 +2105,8 @@ void Clang::ConstructJob(Compilation &C,
>>>                     options::OPT_fno_strict_aliasing,
>>>                     getToolChain().IsStrictAliasingDefault()))
>>>     CmdArgs.push_back("-relaxed-aliasing");
>>> +  if (Args.hasArg(options::OPT_fstruct_path_tbaa))
>>> +    CmdArgs.push_back("-struct-path-tbaa");
>>>   if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
>>>                    false))
>>>     CmdArgs.push_back("-fstrict-enums");
>>> 
>>> Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=178784&r1=178783&r2=178784&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
>>> +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Thu Apr  4 15:14:17 2013
>>> @@ -324,6 +324,7 @@ static bool ParseCodeGenArgs(CodeGenOpti
>>>   Opts.UseRegisterSizedBitfieldAccess = Args.hasArg(
>>>     OPT_fuse_register_sized_bitfield_access);
>>>   Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing);
>>> +  Opts.StructPathTBAA = Args.hasArg(OPT_struct_path_tbaa);
>>>   Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags);
>>>   Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants);
>>>   Opts.NoCommon = Args.hasArg(OPT_fno_common);
>>> 
>>> Added: cfe/trunk/test/CodeGen/tbaa.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/tbaa.cpp?rev=178784&view=auto
>>> ==============================================================================
>>> --- cfe/trunk/test/CodeGen/tbaa.cpp (added)
>>> +++ cfe/trunk/test/CodeGen/tbaa.cpp Thu Apr  4 15:14:17 2013
>>> @@ -0,0 +1,217 @@
>>> +// RUN: %clang_cc1 -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
>>> +// RUN: %clang_cc1 -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
>>> +// Test TBAA metadata generated by front-end.
>>> +
>>> +#include <stdint.h>
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   uint32_t f32;
>>> +   uint16_t f16_2;
>>> +   uint32_t f32_2;
>>> +} StructA;
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   StructA a;
>>> +   uint32_t f32;
>>> +} StructB;
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   StructB b;
>>> +   uint32_t f32;
>>> +} StructC;
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   StructB b;
>>> +   uint32_t f32;
>>> +   uint8_t f8;
>>> +} StructD;
>>> +
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   uint32_t f32;
>>> +} StructS;
>>> +typedef struct
>>> +{
>>> +   uint16_t f16;
>>> +   uint32_t f32;
>>> +} StructS2;
>>> +
>>> +uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !5
>>> +  *s = 1;
>>> +  A->f32 = 4;
>>> +  return *s;
>>> +}
>>> +
>>> +uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !8
>>> +  *s = 1;
>>> +  A->f16 = 4;
>>> +  return *s;
>>> +}
>>> +
>>> +uint32_t g3(StructA *A, StructB *B, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9
>>> +  A->f32 = 1;
>>> +  B->a.f32 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g4(StructA *A, StructB *B, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !11
>>> +  A->f32 = 1;
>>> +  B->a.f16 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g5(StructA *A, StructB *B, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !12
>>> +  A->f32 = 1;
>>> +  B->f32 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g6(StructA *A, StructB *B, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !13
>>> +  A->f32 = 1;
>>> +  B->a.f32_2 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g7(StructA *A, StructS *S, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !14
>>> +  A->f32 = 1;
>>> +  S->f32 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g8(StructA *A, StructS *S, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
>>> +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !16
>>> +  A->f32 = 1;
>>> +  S->f16 = 4;
>>> +  return A->f32;
>>> +}
>>> +
>>> +uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !17
>>> +  S->f32 = 1;
>>> +  S2->f32 = 4;
>>> +  return S->f32;
>>> +}
>>> +
>>> +uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14
>>> +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !19
>>> +  S->f32 = 1;
>>> +  S2->f16 = 4;
>>> +  return S->f32;
>>> +}
>>> +
>>> +uint32_t g11(StructC *C, StructD *D, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !20
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !22
>>> +  C->b.a.f32 = 1;
>>> +  D->b.a.f32 = 4;
>>> +  return C->b.a.f32;
>>> +}
>>> +
>>> +uint32_t g12(StructC *C, StructD *D, uint64_t count) {
>>> +// CHECK: define i32 @{{.*}}(
>>> +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
>>> +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
>>> +// TODO: differentiate the two accesses.
>>> +// PATH: define i32 @{{.*}}(
>>> +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !9
>>> +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9
>>> +  StructB *b1 = &(C->b);
>>> +  StructB *b2 = &(D->b);
>>> +  // b1, b2 have different context.
>>> +  b1->a.f32 = 1;
>>> +  b2->a.f32 = 4;
>>> +  return b1->a.f32;
>>> +}
>>> +
>>> +// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2}
>>> +// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"}
>>> +// CHECK: !4 = metadata !{metadata !"int", metadata !1}
>>> +// CHECK: !5 = metadata !{metadata !"short", metadata !1}
>>> +
>>> +// PATH: !1 = metadata !{metadata !"omnipotent char", metadata !2}
>>> +// PATH: !4 = metadata !{metadata !"int", metadata !1}
>>> +// PATH: !5 = metadata !{metadata !6, metadata !4, i64 4}
>>> +// PATH: !6 = metadata !{metadata !"_ZTS7StructA", i64 0, metadata !7, i64 4, metadata !4}
>>> +// PATH: !7 = metadata !{metadata !"short", metadata !1}
>>> +// PATH: !8 = metadata !{metadata !6, metadata !7, i64 0}
>>> +// PATH: !9 = metadata !{metadata !10, metadata !4, i64 8}
>>> +// PATH: !10 = metadata !{metadata !"_ZTS7StructB", i64 0, metadata !7, i64 4, metadata !6, i64 20, metadata !4}
>>> +// PATH: !11 = metadata !{metadata !10, metadata !7, i64 4}
>>> +// PATH: !12 = metadata !{metadata !10, metadata !4, i64 20}
>>> +// PATH: !13 = metadata !{metadata !10, metadata !4, i64 16}
>>> +// PATH: !14 = metadata !{metadata !15, metadata !4, i64 4}
>>> +// PATH: !15 = metadata !{metadata !"_ZTS7StructS", i64 0, metadata !7, i64 4, metadata !4}
>>> +// PATH: !16 = metadata !{metadata !15, metadata !7, i64 0}
>>> +// PATH: !17 = metadata !{metadata !18, metadata !4, i64 4}
>>> +// PATH: !18 = metadata !{metadata !"_ZTS8StructS2", i64 0, metadata !7, i64 4, metadata !4}
>>> +// PATH: !19 = metadata !{metadata !18, metadata !7, i64 0}
>>> +// PATH: !20 = metadata !{metadata !21, metadata !4, i64 12}
>>> +// PATH: !21 = metadata !{metadata !"_ZTS7StructC", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4}
>>> +// PATH: !22 = metadata !{metadata !23, metadata !4, i64 12}
>>> +// PATH: !23 = metadata !{metadata !"_ZTS7StructD", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4, i64 32, metadata !1}
>>> 
>>> 
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130404/12f70014/attachment.html>


More information about the cfe-commits mailing list