258 lines
9.2 KiB
C
258 lines
9.2 KiB
C
|
//===--- CodeGenTBAA.h - TBAA information for LLVM CodeGen ------*- C++ -*-===//
|
||
|
//
|
||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
//
|
||
|
// This is the code that manages TBAA information and defines the TBAA policy
|
||
|
// for the optimizer to use.
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H
|
||
|
#define LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H
|
||
|
|
||
|
#include "clang/AST/Type.h"
|
||
|
#include "clang/Basic/LLVM.h"
|
||
|
#include "llvm/ADT/DenseMap.h"
|
||
|
#include "llvm/IR/MDBuilder.h"
|
||
|
#include "llvm/IR/Metadata.h"
|
||
|
|
||
|
namespace clang {
|
||
|
class ASTContext;
|
||
|
class CodeGenOptions;
|
||
|
class LangOptions;
|
||
|
class MangleContext;
|
||
|
class QualType;
|
||
|
class Type;
|
||
|
|
||
|
namespace CodeGen {
|
||
|
class CGRecordLayout;
|
||
|
|
||
|
// TBAAAccessKind - A kind of TBAA memory access descriptor.
|
||
|
enum class TBAAAccessKind : unsigned {
|
||
|
Ordinary,
|
||
|
MayAlias,
|
||
|
Incomplete,
|
||
|
};
|
||
|
|
||
|
// TBAAAccessInfo - Describes a memory access in terms of TBAA.
|
||
|
struct TBAAAccessInfo {
|
||
|
TBAAAccessInfo(TBAAAccessKind Kind, llvm::MDNode *BaseType,
|
||
|
llvm::MDNode *AccessType, uint64_t Offset, uint64_t Size)
|
||
|
: Kind(Kind), BaseType(BaseType), AccessType(AccessType),
|
||
|
Offset(Offset), Size(Size)
|
||
|
{}
|
||
|
|
||
|
TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType,
|
||
|
uint64_t Offset, uint64_t Size)
|
||
|
: TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType,
|
||
|
Offset, Size)
|
||
|
{}
|
||
|
|
||
|
explicit TBAAAccessInfo(llvm::MDNode *AccessType, uint64_t Size)
|
||
|
: TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0, Size)
|
||
|
{}
|
||
|
|
||
|
TBAAAccessInfo()
|
||
|
: TBAAAccessInfo(/* AccessType= */ nullptr, /* Size= */ 0)
|
||
|
{}
|
||
|
|
||
|
static TBAAAccessInfo getMayAliasInfo() {
|
||
|
return TBAAAccessInfo(TBAAAccessKind::MayAlias,
|
||
|
/* BaseType= */ nullptr, /* AccessType= */ nullptr,
|
||
|
/* Offset= */ 0, /* Size= */ 0);
|
||
|
}
|
||
|
|
||
|
bool isMayAlias() const { return Kind == TBAAAccessKind::MayAlias; }
|
||
|
|
||
|
static TBAAAccessInfo getIncompleteInfo() {
|
||
|
return TBAAAccessInfo(TBAAAccessKind::Incomplete,
|
||
|
/* BaseType= */ nullptr, /* AccessType= */ nullptr,
|
||
|
/* Offset= */ 0, /* Size= */ 0);
|
||
|
}
|
||
|
|
||
|
bool isIncomplete() const { return Kind == TBAAAccessKind::Incomplete; }
|
||
|
|
||
|
bool operator==(const TBAAAccessInfo &Other) const {
|
||
|
return Kind == Other.Kind &&
|
||
|
BaseType == Other.BaseType &&
|
||
|
AccessType == Other.AccessType &&
|
||
|
Offset == Other.Offset &&
|
||
|
Size == Other.Size;
|
||
|
}
|
||
|
|
||
|
bool operator!=(const TBAAAccessInfo &Other) const {
|
||
|
return !(*this == Other);
|
||
|
}
|
||
|
|
||
|
explicit operator bool() const {
|
||
|
return *this != TBAAAccessInfo();
|
||
|
}
|
||
|
|
||
|
/// Kind - The kind of the access descriptor.
|
||
|
TBAAAccessKind Kind;
|
||
|
|
||
|
/// BaseType - The base/leading access type. May be null if this access
|
||
|
/// descriptor represents an access that is not considered to be an access
|
||
|
/// to an aggregate or union member.
|
||
|
llvm::MDNode *BaseType;
|
||
|
|
||
|
/// AccessType - The final access type. May be null if there is no TBAA
|
||
|
/// information available about this access.
|
||
|
llvm::MDNode *AccessType;
|
||
|
|
||
|
/// Offset - The byte offset of the final access within the base one. Must be
|
||
|
/// zero if the base access type is not specified.
|
||
|
uint64_t Offset;
|
||
|
|
||
|
/// Size - The size of access, in bytes.
|
||
|
uint64_t Size;
|
||
|
};
|
||
|
|
||
|
/// CodeGenTBAA - This class organizes the cross-module state that is used
|
||
|
/// while lowering AST types to LLVM types.
|
||
|
class CodeGenTBAA {
|
||
|
ASTContext &Context;
|
||
|
llvm::Module &Module;
|
||
|
const CodeGenOptions &CodeGenOpts;
|
||
|
const LangOptions &Features;
|
||
|
MangleContext &MContext;
|
||
|
|
||
|
// MDHelper - Helper for creating metadata.
|
||
|
llvm::MDBuilder MDHelper;
|
||
|
|
||
|
/// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing
|
||
|
/// them.
|
||
|
llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache;
|
||
|
/// This maps clang::Types to a base access type in the type DAG.
|
||
|
llvm::DenseMap<const Type *, llvm::MDNode *> BaseTypeMetadataCache;
|
||
|
/// This maps TBAA access descriptors to tag nodes.
|
||
|
llvm::DenseMap<TBAAAccessInfo, llvm::MDNode *> AccessTagMetadataCache;
|
||
|
|
||
|
/// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing
|
||
|
/// them for struct assignments.
|
||
|
llvm::DenseMap<const Type *, llvm::MDNode *> StructMetadataCache;
|
||
|
|
||
|
llvm::MDNode *Root;
|
||
|
llvm::MDNode *Char;
|
||
|
|
||
|
/// getRoot - This is the mdnode for the root of the metadata type graph
|
||
|
/// for this translation unit.
|
||
|
llvm::MDNode *getRoot();
|
||
|
|
||
|
/// getChar - This is the mdnode for "char", which is special, and any types
|
||
|
/// considered to be equivalent to it.
|
||
|
llvm::MDNode *getChar();
|
||
|
|
||
|
/// CollectFields - Collect information about the fields of a type for
|
||
|
/// !tbaa.struct metadata formation. Return false for an unsupported type.
|
||
|
bool CollectFields(uint64_t BaseOffset,
|
||
|
QualType Ty,
|
||
|
SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields,
|
||
|
bool MayAlias);
|
||
|
|
||
|
/// createScalarTypeNode - A wrapper function to create a metadata node
|
||
|
/// describing a scalar type.
|
||
|
llvm::MDNode *createScalarTypeNode(StringRef Name, llvm::MDNode *Parent,
|
||
|
uint64_t Size);
|
||
|
|
||
|
/// getTypeInfoHelper - An internal helper function to generate metadata used
|
||
|
/// to describe accesses to objects of the given type.
|
||
|
llvm::MDNode *getTypeInfoHelper(const Type *Ty);
|
||
|
|
||
|
/// getBaseTypeInfoHelper - An internal helper function to generate metadata
|
||
|
/// used to describe accesses to objects of the given base type.
|
||
|
llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty);
|
||
|
|
||
|
public:
|
||
|
CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO,
|
||
|
const LangOptions &Features, MangleContext &MContext);
|
||
|
~CodeGenTBAA();
|
||
|
|
||
|
/// getTypeInfo - Get metadata used to describe accesses to objects of the
|
||
|
/// given type.
|
||
|
llvm::MDNode *getTypeInfo(QualType QTy);
|
||
|
|
||
|
/// getAccessInfo - Get TBAA information that describes an access to
|
||
|
/// an object of the given type.
|
||
|
TBAAAccessInfo getAccessInfo(QualType AccessType);
|
||
|
|
||
|
/// getVTablePtrAccessInfo - Get the TBAA information that describes an
|
||
|
/// access to a virtual table pointer.
|
||
|
TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType);
|
||
|
|
||
|
/// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of
|
||
|
/// the given type.
|
||
|
llvm::MDNode *getTBAAStructInfo(QualType QTy);
|
||
|
|
||
|
/// getBaseTypeInfo - Get metadata that describes the given base access type.
|
||
|
/// Return null if the type is not suitable for use in TBAA access tags.
|
||
|
llvm::MDNode *getBaseTypeInfo(QualType QTy);
|
||
|
|
||
|
/// getAccessTagInfo - Get TBAA tag for a given memory access.
|
||
|
llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info);
|
||
|
|
||
|
/// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of
|
||
|
/// type casts.
|
||
|
TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,
|
||
|
TBAAAccessInfo TargetInfo);
|
||
|
|
||
|
/// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the
|
||
|
/// purpose of conditional operator.
|
||
|
TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA,
|
||
|
TBAAAccessInfo InfoB);
|
||
|
|
||
|
/// mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the
|
||
|
/// purpose of memory transfer calls.
|
||
|
TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
|
||
|
TBAAAccessInfo SrcInfo);
|
||
|
};
|
||
|
|
||
|
} // end namespace CodeGen
|
||
|
} // end namespace clang
|
||
|
|
||
|
namespace llvm {
|
||
|
|
||
|
template<> struct DenseMapInfo<clang::CodeGen::TBAAAccessInfo> {
|
||
|
static clang::CodeGen::TBAAAccessInfo getEmptyKey() {
|
||
|
unsigned UnsignedKey = DenseMapInfo<unsigned>::getEmptyKey();
|
||
|
return clang::CodeGen::TBAAAccessInfo(
|
||
|
static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey),
|
||
|
DenseMapInfo<MDNode *>::getEmptyKey(),
|
||
|
DenseMapInfo<MDNode *>::getEmptyKey(),
|
||
|
DenseMapInfo<uint64_t>::getEmptyKey(),
|
||
|
DenseMapInfo<uint64_t>::getEmptyKey());
|
||
|
}
|
||
|
|
||
|
static clang::CodeGen::TBAAAccessInfo getTombstoneKey() {
|
||
|
unsigned UnsignedKey = DenseMapInfo<unsigned>::getTombstoneKey();
|
||
|
return clang::CodeGen::TBAAAccessInfo(
|
||
|
static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey),
|
||
|
DenseMapInfo<MDNode *>::getTombstoneKey(),
|
||
|
DenseMapInfo<MDNode *>::getTombstoneKey(),
|
||
|
DenseMapInfo<uint64_t>::getTombstoneKey(),
|
||
|
DenseMapInfo<uint64_t>::getTombstoneKey());
|
||
|
}
|
||
|
|
||
|
static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) {
|
||
|
auto KindValue = static_cast<unsigned>(Val.Kind);
|
||
|
return DenseMapInfo<unsigned>::getHashValue(KindValue) ^
|
||
|
DenseMapInfo<MDNode *>::getHashValue(Val.BaseType) ^
|
||
|
DenseMapInfo<MDNode *>::getHashValue(Val.AccessType) ^
|
||
|
DenseMapInfo<uint64_t>::getHashValue(Val.Offset) ^
|
||
|
DenseMapInfo<uint64_t>::getHashValue(Val.Size);
|
||
|
}
|
||
|
|
||
|
static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS,
|
||
|
const clang::CodeGen::TBAAAccessInfo &RHS) {
|
||
|
return LHS == RHS;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} // end namespace llvm
|
||
|
|
||
|
#endif
|