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
18226633Sdim#include "clang/Basic/LLVM.h"
19218887Sdim#include "llvm/ADT/DenseMap.h"
20249423Sdim#include "llvm/IR/MDBuilder.h"
21218887Sdim
22218887Sdimnamespace llvm {
23218887Sdim  class LLVMContext;
24218887Sdim  class MDNode;
25218887Sdim}
26218887Sdim
27218887Sdimnamespace clang {
28218887Sdim  class ASTContext;
29239462Sdim  class CodeGenOptions;
30218887Sdim  class LangOptions;
31218887Sdim  class MangleContext;
32218887Sdim  class QualType;
33218887Sdim  class Type;
34218887Sdim
35218887Sdimnamespace CodeGen {
36218887Sdim  class CGRecordLayout;
37218887Sdim
38249423Sdim  struct TBAAPathTag {
39249423Sdim    TBAAPathTag(const Type *B, const llvm::MDNode *A, uint64_t O)
40249423Sdim      : BaseT(B), AccessN(A), Offset(O) {}
41249423Sdim    const Type *BaseT;
42249423Sdim    const llvm::MDNode *AccessN;
43249423Sdim    uint64_t Offset;
44249423Sdim  };
45249423Sdim
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;
50239462Sdim  const CodeGenOptions &CodeGenOpts;
51218887Sdim  const LangOptions &Features;
52218887Sdim  MangleContext &MContext;
53218887Sdim
54234982Sdim  // MDHelper - Helper for creating metadata.
55234982Sdim  llvm::MDBuilder MDHelper;
56234982Sdim
57249423Sdim  /// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing
58249423Sdim  /// them.
59218887Sdim  llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache;
60249423Sdim  /// This maps clang::Types to a struct node in the type DAG.
61249423Sdim  llvm::DenseMap<const Type *, llvm::MDNode *> StructTypeMetadataCache;
62249423Sdim  /// This maps TBAAPathTags to a tag node.
63249423Sdim  llvm::DenseMap<TBAAPathTag, llvm::MDNode *> StructTagMetadataCache;
64251662Sdim  /// This maps a scalar type to a scalar tag node.
65251662Sdim  llvm::DenseMap<const llvm::MDNode *, llvm::MDNode *> ScalarTagMetadataCache;
66218887Sdim
67243830Sdim  /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing
68243830Sdim  /// them for struct assignments.
69243830Sdim  llvm::DenseMap<const Type *, llvm::MDNode *> StructMetadataCache;
70243830Sdim
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
82243830Sdim  /// CollectFields - Collect information about the fields of a type for
83243830Sdim  /// !tbaa.struct metadata formation. Return false for an unsupported type.
84243830Sdim  bool CollectFields(uint64_t BaseOffset,
85243830Sdim                     QualType Ty,
86243830Sdim                     SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields,
87243830Sdim                     bool MayAlias);
88243830Sdim
89251662Sdim  /// A wrapper function to create a scalar type. For struct-path aware TBAA,
90251662Sdim  /// the scalar type has the same format as the struct type: name, offset,
91251662Sdim  /// pointer to another node in the type DAG.
92251662Sdim  llvm::MDNode *createTBAAScalarType(StringRef Name, llvm::MDNode *Parent);
93251662Sdim
94218887Sdimpublic:
95218887Sdim  CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext,
96239462Sdim              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);
104234353Sdim
105234353Sdim  /// getTBAAInfoForVTablePtr - Get the TBAA MDNode to be used for a
106234353Sdim  /// dereference of a vtable pointer.
107234353Sdim  llvm::MDNode *getTBAAInfoForVTablePtr();
108243830Sdim
109243830Sdim  /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of
110243830Sdim  /// the given type.
111243830Sdim  llvm::MDNode *getTBAAStructInfo(QualType QTy);
112249423Sdim
113249423Sdim  /// Get the MDNode in the type DAG for given struct type QType.
114249423Sdim  llvm::MDNode *getTBAAStructTypeInfo(QualType QType);
115251662Sdim  /// Get the tag MDNode for a given base type, the actual scalar access MDNode
116249423Sdim  /// and offset into the base type.
117249423Sdim  llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType,
118249423Sdim                                     llvm::MDNode *AccessNode, uint64_t Offset);
119251662Sdim
120263508Sdim  /// Get the scalar tag MDNode for a given scalar type.
121251662Sdim  llvm::MDNode *getTBAAScalarTagInfo(llvm::MDNode *AccessNode);
122218887Sdim};
123218887Sdim
124218887Sdim}  // end namespace CodeGen
125218887Sdim}  // end namespace clang
126218887Sdim
127249423Sdimnamespace llvm {
128249423Sdim
129249423Sdimtemplate<> struct DenseMapInfo<clang::CodeGen::TBAAPathTag> {
130249423Sdim  static clang::CodeGen::TBAAPathTag getEmptyKey() {
131249423Sdim    return clang::CodeGen::TBAAPathTag(
132249423Sdim      DenseMapInfo<const clang::Type *>::getEmptyKey(),
133249423Sdim      DenseMapInfo<const MDNode *>::getEmptyKey(),
134249423Sdim      DenseMapInfo<uint64_t>::getEmptyKey());
135249423Sdim  }
136249423Sdim
137249423Sdim  static clang::CodeGen::TBAAPathTag getTombstoneKey() {
138249423Sdim    return clang::CodeGen::TBAAPathTag(
139249423Sdim      DenseMapInfo<const clang::Type *>::getTombstoneKey(),
140249423Sdim      DenseMapInfo<const MDNode *>::getTombstoneKey(),
141249423Sdim      DenseMapInfo<uint64_t>::getTombstoneKey());
142249423Sdim  }
143249423Sdim
144249423Sdim  static unsigned getHashValue(const clang::CodeGen::TBAAPathTag &Val) {
145249423Sdim    return DenseMapInfo<const clang::Type *>::getHashValue(Val.BaseT) ^
146249423Sdim           DenseMapInfo<const MDNode *>::getHashValue(Val.AccessN) ^
147249423Sdim           DenseMapInfo<uint64_t>::getHashValue(Val.Offset);
148249423Sdim  }
149249423Sdim
150249423Sdim  static bool isEqual(const clang::CodeGen::TBAAPathTag &LHS,
151249423Sdim                      const clang::CodeGen::TBAAPathTag &RHS) {
152249423Sdim    return LHS.BaseT == RHS.BaseT &&
153249423Sdim           LHS.AccessN == RHS.AccessN &&
154249423Sdim           LHS.Offset == RHS.Offset;
155249423Sdim  }
156249423Sdim};
157249423Sdim
158249423Sdim}  // end namespace llvm
159249423Sdim
160218887Sdim#endif
161