Index: llvm/include/llvm/BinaryFormat/MachO.h =================================================================== --- llvm/include/llvm/BinaryFormat/MachO.h +++ llvm/include/llvm/BinaryFormat/MachO.h @@ -334,6 +334,7 @@ N_WEAK_DEF = 0x0080u, N_SYMBOL_RESOLVER = 0x0100u, N_ALT_ENTRY = 0x0200u, + N_COLD_FUNC = 0x0400u, // For undefined symbols coming from libraries, see GET_LIBRARY_ORDINAL() // as these are in the top 8 bits. SELF_LIBRARY_ORDINAL = 0x0, Index: llvm/include/llvm/MC/MCDirectives.h =================================================================== --- llvm/include/llvm/MC/MCDirectives.h +++ llvm/include/llvm/MC/MCDirectives.h @@ -19,6 +19,7 @@ MCSA_Invalid = 0, ///< Not a valid directive. // Various directives in alphabetical order. + MCSA_Cold, ///< .cold (MachO) MCSA_ELF_TypeFunction, ///< .type _foo, STT_FUNC # aka @function MCSA_ELF_TypeIndFunction, ///< .type _foo, STT_GNU_IFUNC MCSA_ELF_TypeObject, ///< .type _foo, STT_OBJECT # aka @object Index: llvm/include/llvm/MC/MCSymbolMachO.h =================================================================== --- llvm/include/llvm/MC/MCSymbolMachO.h +++ llvm/include/llvm/MC/MCSymbolMachO.h @@ -34,6 +34,7 @@ SF_WeakDefinition = 0x0080, SF_SymbolResolver = 0x0100, SF_AltEntry = 0x0200, + SF_Cold = 0x0400, // Common alignment SF_CommonAlignmentMask = 0xF0FF, @@ -97,6 +98,10 @@ return getFlags() & SF_AltEntry; } + void setCold() const { modifyFlags(SF_Cold, SF_Cold); } + + bool isCold() const { return getFlags() & SF_Cold; } + void setDesc(unsigned Value) const { assert(Value == (Value & SF_DescFlagsMask) && "Invalid .desc value!"); Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -663,6 +663,9 @@ if (MAI->hasDotTypeDotSizeDirective()) OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction); + if (F.hasFnAttribute(Attribute::Cold)) + OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_Cold); + if (isVerbose()) { F.printAsOperand(OutStreamer->GetCommentOS(), /*PrintType=*/false, F.getParent()); Index: llvm/lib/MC/MCAsmStreamer.cpp =================================================================== --- llvm/lib/MC/MCAsmStreamer.cpp +++ llvm/lib/MC/MCAsmStreamer.cpp @@ -656,6 +656,9 @@ // .weak_reference case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break; case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break; + case MCSA_Cold: + // Assemblers currently do not support a .cold directive. + return false; } Symbol->print(OS, MAI); Index: llvm/lib/MC/MCELFStreamer.cpp =================================================================== --- llvm/lib/MC/MCELFStreamer.cpp +++ llvm/lib/MC/MCELFStreamer.cpp @@ -201,6 +201,7 @@ // In the future it might be worth trying to make these operations more well // defined. switch (Attribute) { + case MCSA_Cold: case MCSA_LazyReference: case MCSA_Reference: case MCSA_SymbolResolver: Index: llvm/lib/MC/MCMachOStreamer.cpp =================================================================== --- llvm/lib/MC/MCMachOStreamer.cpp +++ llvm/lib/MC/MCMachOStreamer.cpp @@ -386,6 +386,10 @@ Symbol->setWeakDefinition(); Symbol->setWeakReference(); break; + + case MCSA_Cold: + Symbol->setCold(); + break; } return true; Index: llvm/test/tools/llvm-nm/AArch64/Inputs/cold-func.ll =================================================================== --- /dev/null +++ llvm/test/tools/llvm-nm/AArch64/Inputs/cold-func.ll @@ -0,0 +1,3 @@ +define void @cold_func() cold { + ret void +} Index: llvm/test/tools/llvm-nm/AArch64/macho-cold.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-nm/AArch64/macho-cold.test @@ -0,0 +1,4 @@ +RUN: llc -O0 -mtriple=aarch64-apple-ios %p/Inputs/cold-func.ll -filetype=obj -o %t.aarch64.o +RUN: llvm-nm -m %t.aarch64.o | FileCheck %s + +CHECK: [cold] _cold_func Index: llvm/tools/llvm-nm/llvm-nm.cpp =================================================================== --- llvm/tools/llvm-nm/llvm-nm.cpp +++ llvm/tools/llvm-nm/llvm-nm.cpp @@ -554,6 +554,11 @@ (NDesc & MachO::N_ALT_ENTRY) == MachO::N_ALT_ENTRY) outs() << "[alt entry] "; + if (Filetype == MachO::MH_OBJECT && + ((NType & MachO::N_TYPE) != MachO::N_UNDF) && + (NDesc & MachO::N_COLD_FUNC) == MachO::N_COLD_FUNC) + outs() << "[cold] "; + if ((NDesc & MachO::N_ARM_THUMB_DEF) == MachO::N_ARM_THUMB_DEF) outs() << "[Thumb] ";