1218887Sdim//===--- CodeGenTBAA.h - TBAA information for LLVM CodeGen ------*- C++ -*-===//
2218887Sdim//
3218887Sdim//                     The LLVM Compiler Infrastructure
4218887Sdim//
5218887Sdim// This file is distributed under the University of Illinois Open Source
6218887Sdim// License. See LICENSE.TXT for details.
7218887Sdim//
8218887Sdim//===----------------------------------------------------------------------===//
9218887Sdim//
10218887Sdim// This is the code that manages TBAA information and defines the TBAA policy
11218887Sdim// for the optimizer to use.
12218887Sdim//
13218887Sdim//===----------------------------------------------------------------------===//
14218887Sdim
15218887Sdim#ifndef CLANG_CODEGEN_CODEGENTBAA_H
16218887Sdim#define CLANG_CODEGEN_CODEGENTBAA_H
17218887Sdim
18226890Sdim#include "clang/Basic/LLVM.h"
19218887Sdim#include "llvm/ADT/DenseMap.h"
20252723Sdim#include "llvm/IR/MDBuilder.h"
21218887Sdim
22218887Sdimnamespace llvm {
23218887Sdim  class LLVMContext;
24218887Sdim  class MDNode;
25218887Sdim}
26218887Sdim
27218887Sdimnamespace clang {
28218887Sdim  class ASTContext;
29245431Sdim  class CodeGenOptions;
30218887Sdim  class LangOptions;
31218887Sdim  class MangleContext;
32218887Sdim  class QualType;
33218887Sdim  class Type;
34218887Sdim
35218887Sdimnamespace CodeGen {
36218887Sdim  class CGRecordLayout;
37218887Sdim
38252723Sdim  struct TBAAPathTag {
39252723Sdim    TBAAPathTag(const Type *B, const llvm::MDNode *A, uint64_t O)
40252723Sdim      : BaseT(B), AccessN(A), Offset(O) {}
41252723Sdim    const Type *BaseT;
42252723Sdim    const llvm::MDNode *AccessN;
43252723Sdim    uint64_t Offset;
44252723Sdim  };
45252723Sdim
46218887Sdim/// CodeGenTBAA - This class organizes the cross-module state that is used
47218887Sdim/// while lowering AST types to LLVM types.
48218887Sdimclass CodeGenTBAA {
49218887Sdim  ASTContext &Context;
50245431Sdim  const CodeGenOptions &CodeGenOpts;
51218887Sdim  const LangOptions &Features;
52218887Sdim  MangleContext &MContext;
53218887Sdim
54235633Sdim  // MDHelper - Helper for creating metadata.
55235633Sdim  llvm::MDBuilder MDHelper;
56235633Sdim
57252723Sdim  /// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing
58252723Sdim  /// them.
59218887Sdim  llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache;
60252723Sdim  /// This maps clang::Types to a struct node in the type DAG.
61252723Sdim  llvm::DenseMap<const Type *, llvm::MDNode *> StructTypeMetadataCache;
62252723Sdim  /// This maps TBAAPathTags to a tag node.
63252723Sdim  llvm::DenseMap<TBAAPathTag, llvm::MDNode *> StructTagMetadataCache;
64252723Sdim  /// This maps a scalar type to a scalar tag node.
65252723Sdim  llvm::DenseMap<const llvm::MDNode *, llvm::MDNode *> ScalarTagMetadataCache;
66218887Sdim
67245431Sdim  /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing
68245431Sdim  /// them for struct assignments.
69245431Sdim  llvm::DenseMap<const Type *, llvm::MDNode *> StructMetadataCache;
70245431Sdim
71218887Sdim  llvm::MDNode *Root;
72218887Sdim  llvm::MDNode *Char;
73218887Sdim
74218887Sdim  /// getRoot - This is the mdnode for the root of the metadata type graph
75218887Sdim  /// for this translation unit.
76218887Sdim  llvm::MDNode *getRoot();
77218887Sdim
78218887Sdim  /// getChar - This is the mdnode for "char", which is special, and any types
79218887Sdim  /// considered to be equivalent to it.
80218887Sdim  llvm::MDNode *getChar();
81218887Sdim
82245431Sdim  /// CollectFields - Collect information about the fields of a type for
83245431Sdim  /// !tbaa.struct metadata formation. Return false for an unsupported type.
84245431Sdim  bool CollectFields(uint64_t BaseOffset,
85245431Sdim                     QualType Ty,
86245431Sdim                     SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields,
87245431Sdim                     bool MayAlias);
88245431Sdim
89252723Sdim  /// A wrapper function to create a scalar type. For struct-path aware TBAA,
90252723Sdim  /// the scalar type has the same format as the struct type: name, offset,
91252723Sdim  /// pointer to another node in the type DAG.
92252723Sdim  llvm::MDNode *createTBAAScalarType(StringRef Name, llvm::MDNode *Parent);
93252723Sdim
94218887Sdimpublic:
95218887Sdim  CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext,
96245431Sdim              const CodeGenOptions &CGO,
97218887Sdim              const LangOptions &Features,
98218887Sdim              MangleContext &MContext);
99218887Sdim  ~CodeGenTBAA();
100218887Sdim
101218887Sdim  /// getTBAAInfo - Get the TBAA MDNode to be used for a dereference
102218887Sdim  /// of the given type.
103218887Sdim  llvm::MDNode *getTBAAInfo(QualType QTy);
104235633Sdim
105235633Sdim  /// getTBAAInfoForVTablePtr - Get the TBAA MDNode to be used for a
106235633Sdim  /// dereference of a vtable pointer.
107235633Sdim  llvm::MDNode *getTBAAInfoForVTablePtr();
108245431Sdim
109245431Sdim  /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of
110245431Sdim  /// the given type.
111245431Sdim  llvm::MDNode *getTBAAStructInfo(QualType QTy);
112252723Sdim
113252723Sdim  /// Get the MDNode in the type DAG for given struct type QType.
114252723Sdim  llvm::MDNode *getTBAAStructTypeInfo(QualType QType);
115252723Sdim  /// Get the tag MDNode for a given base type, the actual scalar access MDNode
116252723Sdim  /// and offset into the base type.
117252723Sdim  llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType,
118252723Sdim                                     llvm::MDNode *AccessNode, uint64_t Offset);
119252723Sdim
120263509Sdim  /// Get the scalar tag MDNode for a given scalar type.
121252723Sdim  llvm::MDNode *getTBAAScalarTagInfo(llvm::MDNode *AccessNode);
122218887Sdim};
123218887Sdim
124218887Sdim}  // end namespace CodeGen
125218887Sdim}  // end namespace clang
126218887Sdim
127252723Sdimnamespace llvm {
128252723Sdim
129252723Sdimtemplate<> struct DenseMapInfo<clang::CodeGen::TBAAPathTag> {
130252723Sdim  static clang::CodeGen::TBAAPathTag getEmptyKey() {
131252723Sdim    return clang::CodeGen::TBAAPathTag(
132252723Sdim      DenseMapInfo<const clang::Type *>::getEmptyKey(),
133252723Sdim      DenseMapInfo<const MDNode *>::getEmptyKey(),
134252723Sdim      DenseMapInfo<uint64_t>::getEmptyKey());
135252723Sdim  }
136252723Sdim
137252723Sdim  static clang::CodeGen::TBAAPathTag getTombstoneKey() {
138252723Sdim    return clang::CodeGen::TBAAPathTag(
139252723Sdim      DenseMapInfo<const clang::Type *>::getTombstoneKey(),
140252723Sdim      DenseMapInfo<const MDNode *>::getTombstoneKey(),
141252723Sdim      DenseMapInfo<uint64_t>::getTombstoneKey());
142252723Sdim  }
143252723Sdim
144252723Sdim  static unsigned getHashValue(const clang::CodeGen::TBAAPathTag &Val) {
145252723Sdim    return DenseMapInfo<const clang::Type *>::getHashValue(Val.BaseT) ^
146252723Sdim           DenseMapInfo<const MDNode *>::getHashValue(Val.AccessN) ^
147252723Sdim           DenseMapInfo<uint64_t>::getHashValue(Val.Offset);
148252723Sdim  }
149252723Sdim
150252723Sdim  static bool isEqual(const clang::CodeGen::TBAAPathTag &LHS,
151252723Sdim                      const clang::CodeGen::TBAAPathTag &RHS) {
152252723Sdim    return LHS.BaseT == RHS.BaseT &&
153252723Sdim           LHS.AccessN == RHS.AccessN &&
154252723Sdim           LHS.Offset == RHS.Offset;
155252723Sdim  }
156252723Sdim};
157252723Sdim
158252723Sdim}  // end namespace llvm
159252723Sdim
160218887Sdim#endif
161