[CodeGen] emit CG profile for COFF object file

I forgot to add emission of CG profile for COFF object file, when adding the support (https://reviews.llvm.org/D81775)

Differential Revision: https://reviews.llvm.org/D87811
This commit is contained in:
Zequan Wu 2020-09-16 19:05:51 -07:00
parent d419e34c4d
commit 91aed9bf97
5 changed files with 116 additions and 53 deletions

View File

@ -35,7 +35,6 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
protected:
MCSymbolRefExpr::VariantKind PLTRelativeVariantKind =
MCSymbolRefExpr::VK_None;
const TargetMachine *TM = nullptr;
public:
TargetLoweringObjectFileELF() = default;

View File

@ -61,6 +61,8 @@ protected:
/// This section contains the static destructor pointer list.
MCSection *StaticDtorSection = nullptr;
const TargetMachine *TM = nullptr;
public:
TargetLoweringObjectFile() = default;
TargetLoweringObjectFile(const TargetLoweringObjectFile &) = delete;
@ -81,6 +83,9 @@ public:
/// Emit the module-level metadata that the platform cares about.
virtual void emitModuleMetadata(MCStreamer &Streamer, Module &M) const {}
/// Emit Call Graph Profile metadata.
virtual void emitCGProfile(MCStreamer &Streamer, Module &M) const;
/// Get the module-level metadata that the platform cares about.
virtual void getModuleMetadata(Module &M) {}

View File

@ -107,7 +107,6 @@ static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,
void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
const TargetMachine &TgtM) {
TargetLoweringObjectFile::Initialize(Ctx, TgtM);
TM = &TgtM;
CodeModel::Model CM = TgtM.getCodeModel();
InitializeELF(TgtM.Options.UseInitArray);
@ -324,46 +323,7 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
Streamer.AddBlankLine();
}
SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
M.getModuleFlagsMetadata(ModuleFlags);
MDNode *CFGProfile = nullptr;
for (const auto &MFE : ModuleFlags) {
StringRef Key = MFE.Key->getString();
if (Key == "CG Profile") {
CFGProfile = cast<MDNode>(MFE.Val);
break;
}
}
if (!CFGProfile)
return;
auto GetSym = [this](const MDOperand &MDO) -> MCSymbol * {
if (!MDO)
return nullptr;
auto V = cast<ValueAsMetadata>(MDO);
const Function *F = cast<Function>(V->getValue());
return TM->getSymbol(F);
};
for (const auto &Edge : CFGProfile->operands()) {
MDNode *E = cast<MDNode>(Edge);
const MCSymbol *From = GetSym(E->getOperand(0));
const MCSymbol *To = GetSym(E->getOperand(1));
// Skip null functions. This can happen if functions are dead stripped after
// the CGProfile pass has been run.
if (!From || !To)
continue;
uint64_t Count = cast<ConstantAsMetadata>(E->getOperand(2))
->getValue()
->getUniqueInteger()
.getZExtValue();
Streamer.emitCGProfileEntry(
MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C),
MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count);
}
emitCGProfile(Streamer, M);
}
MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
@ -1612,18 +1572,20 @@ void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
StringRef Section;
GetObjCImageInfo(M, Version, Flags, Section);
if (Section.empty())
return;
if (!Section.empty()) {
auto &C = getContext();
auto *S = C.getCOFFSection(Section,
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getReadOnly());
Streamer.SwitchSection(S);
Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
Streamer.emitInt32(Version);
Streamer.emitInt32(Flags);
Streamer.AddBlankLine();
}
auto &C = getContext();
auto *S = C.getCOFFSection(
Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ,
SectionKind::getReadOnly());
Streamer.SwitchSection(S);
Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
Streamer.emitInt32(Version);
Streamer.emitInt32(Flags);
Streamer.AddBlankLine();
emitCGProfile(Streamer, M);
}
void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,

View File

@ -49,6 +49,8 @@ void TargetLoweringObjectFile::Initialize(MCContext &ctx,
// Reset various EH DWARF encodings.
PersonalityEncoding = LSDAEncoding = TTypeEncoding = dwarf::DW_EH_PE_absptr;
CallSiteEncoding = dwarf::DW_EH_PE_uleb128;
this->TM = &TM;
}
TargetLoweringObjectFile::~TargetLoweringObjectFile() {
@ -136,6 +138,50 @@ void TargetLoweringObjectFile::emitPersonalityValue(MCStreamer &Streamer,
const MCSymbol *Sym) const {
}
void TargetLoweringObjectFile::emitCGProfile(MCStreamer &Streamer,
Module &M) const {
MCContext &C = getContext();
SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
M.getModuleFlagsMetadata(ModuleFlags);
MDNode *CFGProfile = nullptr;
for (const auto &MFE : ModuleFlags) {
StringRef Key = MFE.Key->getString();
if (Key == "CG Profile") {
CFGProfile = cast<MDNode>(MFE.Val);
break;
}
}
if (!CFGProfile)
return;
auto GetSym = [this](const MDOperand &MDO) -> MCSymbol * {
if (!MDO)
return nullptr;
auto *V = cast<ValueAsMetadata>(MDO);
const Function *F = cast<Function>(V->getValue());
return TM->getSymbol(F);
};
for (const auto &Edge : CFGProfile->operands()) {
MDNode *E = cast<MDNode>(Edge);
const MCSymbol *From = GetSym(E->getOperand(0));
const MCSymbol *To = GetSym(E->getOperand(1));
// Skip null functions. This can happen if functions are dead stripped after
// the CGProfile pass has been run.
if (!From || !To)
continue;
uint64_t Count = cast<ConstantAsMetadata>(E->getOperand(2))
->getValue()
->getUniqueInteger()
.getZExtValue();
Streamer.emitCGProfileEntry(
MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C),
MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count);
}
}
/// getKindForGlobal - This is a top-level target-independent classifier for
/// a global object. Given a global variable and information from the TM, this

View File

@ -0,0 +1,51 @@
; RUN: llc -filetype=asm %s -o - -mtriple x86_64-pc-windows-msvc | FileCheck %s
; RUN: llc -filetype=obj %s -o %t -mtriple x86_64-pc-windows-msvc
; RUN: llvm-readobj --cg-profile %t | FileCheck %s --check-prefix=OBJ
declare void @b()
define void @a() {
call void @b()
ret void
}
define void @freq(i1 %cond) {
br i1 %cond, label %A, label %B
A:
call void @a();
ret void
B:
call void @b();
ret void
}
!llvm.module.flags = !{!0}
!0 = !{i32 5, !"CG Profile", !1}
!1 = !{!2, !3, !4, !5}
!2 = !{void ()* @a, void ()* @b, i64 32}
!3 = !{void (i1)* @freq, void ()* @a, i64 11}
!4 = !{void (i1)* @freq, void ()* @b, i64 20}
!5 = !{void (i1)* @freq, null, i64 20}
; CHECK: .cg_profile a, b, 32
; CHECK: .cg_profile freq, a, 11
; CHECK: .cg_profile freq, b, 20
; OBJ: CGProfile [
; OBJ: CGProfileEntry {
; OBJ: From: a
; OBJ: To: b
; OBJ: Weight: 32
; OBJ: }
; OBJ: CGProfileEntry {
; OBJ: From: freq
; OBJ: To: a
; OBJ: Weight: 11
; OBJ: }
; OBJ: CGProfileEntry {
; OBJ: From: freq
; OBJ: To: b
; OBJ: Weight: 20
; OBJ: }
; OBJ:]