ubsan: Only emit constants for filenames and type descriptors once.

Produces neater IR in significantly less time.

(~18% faster -O0 compile time for sqlite3 with -fsanitize=undefined)

llvm-svn: 194231
This commit is contained in:
Will Dietz 2013-11-08 01:09:22 +00:00
parent 0dc0e6d32c
commit 949ec546c4
3 changed files with 20 additions and 6 deletions

View File

@ -2027,7 +2027,10 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
/// followed by an array of i8 containing the type name. TypeKind is 0 for an /// followed by an array of i8 containing the type name. TypeKind is 0 for an
/// integer, 1 for a floating point value, and -1 for anything else. /// integer, 1 for a floating point value, and -1 for anything else.
llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
// FIXME: Only emit each type's descriptor once. // Only emit each type's descriptor once.
if (llvm::Constant *C = CGM.getTypeDescriptor(T))
return C;
uint16_t TypeKind = -1; uint16_t TypeKind = -1;
uint16_t TypeInfo = 0; uint16_t TypeInfo = 0;
@ -2060,6 +2063,10 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
llvm::GlobalVariable::PrivateLinkage, llvm::GlobalVariable::PrivateLinkage,
Descriptor); Descriptor);
GV->setUnnamedAddr(true); GV->setUnnamedAddr(true);
// Remember the descriptor for this type.
CGM.setTypeDescriptor(T, GV);
return GV; return GV;
} }
@ -2102,9 +2109,7 @@ llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) {
PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc); PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc);
llvm::Constant *Data[] = { llvm::Constant *Data[] = {
// FIXME: Only emit each file name once. PLoc.isValid() ? CGM.GetAddrOfConstantCString(PLoc.getFilename(), ".src")
PLoc.isValid() ? cast<llvm::Constant>(
Builder.CreateGlobalStringPtr(PLoc.getFilename()))
: llvm::Constant::getNullValue(Int8PtrTy), : llvm::Constant::getNullValue(Int8PtrTy),
Builder.getInt32(PLoc.isValid() ? PLoc.getLine() : 0), Builder.getInt32(PLoc.isValid() ? PLoc.getLine() : 0),
Builder.getInt32(PLoc.isValid() ? PLoc.getColumn() : 0) Builder.getInt32(PLoc.isValid() ? PLoc.getColumn() : 0)

View File

@ -318,6 +318,9 @@ class CodeGenModule : public CodeGenTypeCache {
llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap; llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap;
llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap; llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap;
/// Map used to get unique type descriptor constants for sanitizers.
llvm::DenseMap<QualType, llvm::Constant *> TypeDescriptorMap;
/// Map used to track internal linkage functions declared within /// Map used to track internal linkage functions declared within
/// extern "C" regions. /// extern "C" regions.
typedef llvm::MapVector<IdentifierInfo *, typedef llvm::MapVector<IdentifierInfo *,
@ -498,6 +501,13 @@ public:
AtomicGetterHelperFnMap[Ty] = Fn; AtomicGetterHelperFnMap[Ty] = Fn;
} }
llvm::Constant *getTypeDescriptor(QualType Ty) {
return TypeDescriptorMap[Ty];
}
void setTypeDescriptor(QualType Ty, llvm::Constant *C) {
TypeDescriptorMap[Ty] = C;
}
CGDebugInfo *getModuleDebugInfo() { return DebugInfo; } CGDebugInfo *getModuleDebugInfo() { return DebugInfo; }
llvm::MDNode *getNoObjCARCExceptionsMetadata() { llvm::MDNode *getNoObjCARCExceptionsMetadata() {

View File

@ -7,8 +7,7 @@
// CHECK: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]] // CHECK: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]]
// CHECK: @[[UINT:.*]] = private unnamed_addr constant { i16, i16, [15 x i8] } { i16 0, i16 10, [15 x i8] c"'unsigned int'\00" } // CHECK: @[[UINT:.*]] = private unnamed_addr constant { i16, i16, [15 x i8] } { i16 0, i16 10, [15 x i8] c"'unsigned int'\00" }
// CHECK: @[[LINE_200:.*]] = private unnamed_addr global {{.*}}, i32 200, i32 5 {{.*}} @[[UINT]] // CHECK: @[[LINE_200:.*]] = private unnamed_addr global {{.*}}, i32 200, i32 5 {{.*}} @[[UINT]]
// CHECK: @[[DIVINT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" } // CHECK: @[[LINE_300:.*]] = private unnamed_addr global {{.*}}, i32 300, i32 5 {{.*}} @[[INT]]
// CHECK: @[[LINE_300:.*]] = private unnamed_addr global {{.*}}, i32 300, i32 5 {{.*}} @[[DIVINT]]
int32_t x; int32_t x;