From d0c1e29aecdaaa67ffabbaf2dd255809e6df4978 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sat, 16 Aug 2008 12:57:07 +0000 Subject: [PATCH] Reduce heap trashing due to std::string construction / concatenation via caching of section flags string representations git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54842 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/ELFTargetAsmInfo.h | 2 +- include/llvm/Target/TargetAsmInfo.h | 15 ++++++++++++++- lib/Target/ELFTargetAsmInfo.cpp | 2 +- lib/Target/Sparc/SparcTargetAsmInfo.cpp | 4 ++-- lib/Target/Sparc/SparcTargetAsmInfo.h | 2 +- lib/Target/TargetAsmInfo.cpp | 15 ++++++++++++++- lib/Target/X86/X86TargetAsmInfo.cpp | 2 +- lib/Target/X86/X86TargetAsmInfo.h | 2 +- 8 files changed, 35 insertions(+), 9 deletions(-) diff --git a/include/llvm/Target/ELFTargetAsmInfo.h b/include/llvm/Target/ELFTargetAsmInfo.h index fe339f8e591..3dacb33eb32 100644 --- a/include/llvm/Target/ELFTargetAsmInfo.h +++ b/include/llvm/Target/ELFTargetAsmInfo.h @@ -27,7 +27,7 @@ namespace llvm { explicit ELFTargetAsmInfo(const TargetMachine &TM); virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; - virtual std::string PrintSectionFlags(unsigned flags) const; + virtual std::string printSectionFlags(unsigned flags) const; const Section* MergeableConstSection(const GlobalVariable *GV) const; inline const Section* MergeableConstSection(const Type *Ty) const; const Section* MergeableStringSection(const GlobalVariable *GV) const; diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index 04e91cb3812..8eb951578b9 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -16,6 +16,7 @@ #ifndef LLVM_TARGET_ASM_INFO_H #define LLVM_TARGET_ASM_INFO_H +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/DataTypes.h" #include @@ -83,6 +84,16 @@ namespace llvm { static inline unsigned setEntitySize(unsigned Flags, unsigned Size) { return ((Flags & ~EntitySize) | ((Size & 0xFF) << 24)); } + + struct KeyInfo { + static inline unsigned getEmptyKey() { return Invalid; } + static inline unsigned getTombstoneKey() { return Invalid - 1; } + static unsigned getHashValue(const unsigned &Key) { return Key; } + static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; } + static bool isPod() { return true; } + }; + + typedef DenseMap FlagsStringsMapType; } class TargetMachine; @@ -109,6 +120,7 @@ namespace llvm { class TargetAsmInfo { private: mutable StringMap
Sections; + mutable SectionFlags::FlagsStringsMapType FlagsStrings; protected: //===------------------------------------------------------------------===// // Properties to be set by the target writer, used to configure asm printer. @@ -551,7 +563,8 @@ namespace llvm { virtual std::string UniqueSectionForGlobal(const GlobalValue* GV, SectionKind::Kind kind) const; - virtual std::string PrintSectionFlags(unsigned flags) const { return ""; } + const std::string& getSectionFlags(unsigned Flags) const; + virtual std::string printSectionFlags(unsigned flags) const { return ""; } virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; diff --git a/lib/Target/ELFTargetAsmInfo.cpp b/lib/Target/ELFTargetAsmInfo.cpp index 82ac847e845..9ffc72d2340 100644 --- a/lib/Target/ELFTargetAsmInfo.cpp +++ b/lib/Target/ELFTargetAsmInfo.cpp @@ -148,7 +148,7 @@ ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { return getReadOnlySection_(); } -std::string ELFTargetAsmInfo::PrintSectionFlags(unsigned flags) const { +std::string ELFTargetAsmInfo::printSectionFlags(unsigned flags) const { std::string Flags = ",\""; if (!(flags & SectionFlags::Debug)) diff --git a/lib/Target/Sparc/SparcTargetAsmInfo.cpp b/lib/Target/Sparc/SparcTargetAsmInfo.cpp index c81b9e1f73d..afa5327d952 100644 --- a/lib/Target/Sparc/SparcTargetAsmInfo.cpp +++ b/lib/Target/Sparc/SparcTargetAsmInfo.cpp @@ -27,9 +27,9 @@ SparcELFTargetAsmInfo::SparcELFTargetAsmInfo(const TargetMachine &TM): CStringSection=".rodata.str"; } -std::string SparcELFTargetAsmInfo::PrintSectionFlags(unsigned flags) const { +std::string SparcELFTargetAsmInfo::printSectionFlags(unsigned flags) const { if (flags & SectionFlags::Mergeable) - return ELFTargetAsmInfo::PrintSectionFlags(flags); + return ELFTargetAsmInfo::printSectionFlags(flags); std::string Flags; if (!(flags & SectionFlags::Debug)) diff --git a/lib/Target/Sparc/SparcTargetAsmInfo.h b/lib/Target/Sparc/SparcTargetAsmInfo.h index 253a5d78f05..1af5d80b550 100644 --- a/lib/Target/Sparc/SparcTargetAsmInfo.h +++ b/lib/Target/Sparc/SparcTargetAsmInfo.h @@ -25,7 +25,7 @@ namespace llvm { struct SparcELFTargetAsmInfo : public ELFTargetAsmInfo { explicit SparcELFTargetAsmInfo(const TargetMachine &TM); - std::string PrintSectionFlags(unsigned flags) const; + std::string printSectionFlags(unsigned flags) const; }; } // namespace llvm diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp index 9bc0b4055e3..1ef2182033e 100644 --- a/lib/Target/TargetAsmInfo.cpp +++ b/lib/Target/TargetAsmInfo.cpp @@ -291,7 +291,7 @@ TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const { // If section is named we need to switch into it via special '.section' // directive and also append funky flags. Otherwise - section name is just // some magic assembler directive. - return getSwitchToSectionDirective() + S->Name + PrintSectionFlags(S->Flags); + return getSwitchToSectionDirective() + S->Name + getSectionFlags(S->Flags); } // Lame default implementation. Calculate the section name for global. @@ -376,3 +376,16 @@ TargetAsmInfo::getUnnamedSection(const char *Directive, unsigned Flags) const { return &S; } + +const std::string& +TargetAsmInfo::getSectionFlags(unsigned Flags) const { + SectionFlags::FlagsStringsMapType::iterator I = FlagsStrings.find(Flags); + + // We didn't print these flags yet, print and save them to map. This reduces + // amount of heap trashing due to std::string construction / concatenation. + if (I == FlagsStrings.end()) + I = FlagsStrings.insert(std::make_pair(Flags, + printSectionFlags(Flags))).first; + + return I->second; +} diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp index 984c6b225c5..178aec0d57b 100644 --- a/lib/Target/X86/X86TargetAsmInfo.cpp +++ b/lib/Target/X86/X86TargetAsmInfo.cpp @@ -404,7 +404,7 @@ X86COFFTargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV, } } -std::string X86COFFTargetAsmInfo::PrintSectionFlags(unsigned flags) const { +std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const { std::string Flags = ",\""; if (flags & SectionFlags::Code) diff --git a/lib/Target/X86/X86TargetAsmInfo.h b/lib/Target/X86/X86TargetAsmInfo.h index 0c30545f899..d7e11e0c248 100644 --- a/lib/Target/X86/X86TargetAsmInfo.h +++ b/lib/Target/X86/X86TargetAsmInfo.h @@ -52,7 +52,7 @@ namespace llvm { bool Global) const; virtual std::string UniqueSectionForGlobal(const GlobalValue* GV, SectionKind::Kind kind) const; - virtual std::string PrintSectionFlags(unsigned flags) const; + virtual std::string printSectionFlags(unsigned flags) const; protected: const X86TargetMachine *X86TM; };