diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 13 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTBAA.cpp | 47 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTBAA.h | 12 |
5 files changed, 61 insertions, 24 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index fe0d0701055..4d72dc1c884 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1175,7 +1175,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, if (TBAAInfo) { llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, TBAAOffset); - CGM.DecorateInstruction(Load, TBAAPath); + CGM.DecorateInstruction(Load, TBAAPath, false/*ConvertTypeToTag*/); } if ((SanOpts->Bool && hasBooleanRepresentation(Ty)) || @@ -1289,7 +1289,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, if (TBAAInfo) { llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, TBAAOffset); - CGM.DecorateInstruction(Store, TBAAPath); + CGM.DecorateInstruction(Store, TBAAPath, false/*ConvertTypeToTag*/); } } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e8e3d1ae76e..4126bea295b 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,9 +242,18 @@ llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(QualType BaseTy, return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O); } +/// Decorate the instruction with a TBAA tag. For scalar TBAA, the tag +/// is the same as the type. For struct-path aware TBAA, the tag +/// is different from the type: base type, access type and offset. +/// When ConvertTypeToTag is true, we create a tag based on the scalar type. void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst, - llvm::MDNode *TBAAInfo) { - Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo); + llvm::MDNode *TBAAInfo, + bool ConvertTypeToTag) { + if (ConvertTypeToTag && TBAA && CodeGenOpts.StructPathTBAA) + Inst->setMetadata(llvm::LLVMContext::MD_tbaa, + TBAA->getTBAAScalarTagInfo(TBAAInfo)); + else + Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo); } bool CodeGenModule::isTargetDarwin() const { diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 6bc44563fae..f8b09711f78 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -519,8 +519,13 @@ public: bool isPaddedAtomicType(QualType type); bool isPaddedAtomicType(const AtomicType *type); - static void DecorateInstruction(llvm::Instruction *Inst, - llvm::MDNode *TBAAInfo); + /// Decorate the instruction with a TBAA tag. For scalar TBAA, the tag + /// is the same as the type. For struct-path aware TBAA, the tag + /// is different from the type: base type, access type and offset. + /// When ConvertTypeToTag is true, we create a tag based on the scalar type. + void DecorateInstruction(llvm::Instruction *Inst, + llvm::MDNode *TBAAInfo, + bool ConvertTypeToTag = true); /// getSize - Emit the given number of characters as a value of type size_t. llvm::ConstantInt *getSize(CharUnits numChars); diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 7e4d34ab898..bb1ebda9084 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -50,13 +50,25 @@ llvm::MDNode *CodeGenTBAA::getRoot() { return Root; } +// For struct-path aware TBAA, the scalar type has the same format as +// the struct type: name, offset, pointer to another node in the type DAG. +// For scalar TBAA, the scalar type is the same as the scalar tag: +// name and a parent pointer. +llvm::MDNode *CodeGenTBAA::createTBAAScalarType(StringRef Name, + llvm::MDNode *Parent) { + if (CodeGenOpts.StructPathTBAA) + return MDHelper.createTBAAScalarTypeNode(Name, 0, Parent); + else + return MDHelper.createTBAANode(Name, Parent); +} + llvm::MDNode *CodeGenTBAA::getChar() { // Define the root of the tree for user-accessible memory. C and C++ // give special powers to char and certain similar types. However, // these special powers only cover user-accessible memory, and doesn't // include things like vtables. if (!Char) - Char = MDHelper.createTBAANode("omnipotent char", getRoot()); + Char = createTBAAScalarType("omnipotent char", getRoot()); return Char; } @@ -124,7 +136,7 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) { // "underlying types". default: return MetadataCache[Ty] = - MDHelper.createTBAANode(BTy->getName(Features), getChar()); + createTBAAScalarType(BTy->getName(Features), getChar()); } } @@ -132,8 +144,8 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) { // TODO: Implement C++'s type "similarity" and consider dis-"similar" // pointers distinct. if (Ty->isPointerType()) - return MetadataCache[Ty] = MDHelper.createTBAANode("any pointer", - getChar()); + return MetadataCache[Ty] = createTBAAScalarType("any pointer", + getChar()); // Enum types are distinct types. In C++ they have "underlying types", // however they aren't related for TBAA. @@ -160,7 +172,7 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) { llvm::raw_svector_ostream Out(OutName); MContext.mangleCXXRTTIName(QualType(ETy, 0), Out); Out.flush(); - return MetadataCache[Ty] = MDHelper.createTBAANode(OutName, getChar()); + return MetadataCache[Ty] = createTBAAScalarType(OutName, getChar()); } // For now, handle any other kind of type conservatively. @@ -168,7 +180,7 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) { } llvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() { - return MDHelper.createTBAANode("vtable pointer", getRoot()); + return createTBAAScalarType("vtable pointer", getRoot()); } bool @@ -252,10 +264,6 @@ CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) { 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) { @@ -263,13 +271,8 @@ CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) { llvm::MDNode *FieldNode; if (isTBAAPathStruct(FieldQTy)) FieldNode = getTBAAStructTypeInfo(FieldQTy); - else { + 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( @@ -305,8 +308,18 @@ CodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode, if (isTBAAPathStruct(BaseQTy)) BNode = getTBAAStructTypeInfo(BaseQTy); if (!BNode) - return StructTagMetadataCache[PathTag] = AccessNode; + return StructTagMetadataCache[PathTag] = + MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0); return StructTagMetadataCache[PathTag] = MDHelper.createTBAAStructTagNode(BNode, AccessNode, Offset); } + +llvm::MDNode * +CodeGenTBAA::getTBAAScalarTagInfo(llvm::MDNode *AccessNode) { + if (llvm::MDNode *N = ScalarTagMetadataCache[AccessNode]) + return N; + + return ScalarTagMetadataCache[AccessNode] = + MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0); +} diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h index 9ddc3aa9700..f0c9e06f02b 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.h +++ b/clang/lib/CodeGen/CodeGenTBAA.h @@ -61,6 +61,8 @@ class CodeGenTBAA { llvm::DenseMap<const Type *, llvm::MDNode *> StructTypeMetadataCache; /// This maps TBAAPathTags to a tag node. llvm::DenseMap<TBAAPathTag, llvm::MDNode *> StructTagMetadataCache; + /// This maps a scalar type to a scalar tag node. + llvm::DenseMap<const llvm::MDNode *, llvm::MDNode *> ScalarTagMetadataCache; /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing /// them for struct assignments. @@ -84,6 +86,11 @@ class CodeGenTBAA { SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields, bool MayAlias); + /// A wrapper function to create a scalar type. For struct-path aware TBAA, + /// the scalar type has the same format as the struct type: name, offset, + /// pointer to another node in the type DAG. + llvm::MDNode *createTBAAScalarType(StringRef Name, llvm::MDNode *Parent); + public: CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext, const CodeGenOptions &CGO, @@ -105,10 +112,13 @@ public: /// 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 + /// Get the tag MDNode for a given base type, the actual scalar access MDNode /// and offset into the base type. llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType, llvm::MDNode *AccessNode, uint64_t Offset); + + /// Get the sclar tag MDNode for a given scalar type. + llvm::MDNode *getTBAAScalarTagInfo(llvm::MDNode *AccessNode); }; } // end namespace CodeGen |