Skip to content

Commit

Permalink
Reland [CodeGen] emit CG profile for COFF object file
Browse files Browse the repository at this point in the history
This reverts commit 90242ca.

Error fixed at f543539

Differential Revision: https://reviews.llvm.org/D87811
  • Loading branch information
ZequanWu committed Sep 24, 2020
1 parent 9bcf7b1 commit 506b617
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 53 deletions.
1 change: 0 additions & 1 deletion llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
protected:
MCSymbolRefExpr::VariantKind PLTRelativeVariantKind =
MCSymbolRefExpr::VK_None;
const TargetMachine *TM = nullptr;

public:
TargetLoweringObjectFileELF() = default;
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/Target/TargetLoweringObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
/// This section contains the static destructor pointer list.
MCSection *StaticDtorSection = nullptr;

const TargetMachine *TM = nullptr;

public:
TargetLoweringObjectFile() = default;
TargetLoweringObjectFile(const TargetLoweringObjectFile &) = delete;
Expand All @@ -81,6 +83,9 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
/// 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) {}

Expand Down
66 changes: 14 additions & 52 deletions llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -1598,18 +1558,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::emitLinkerDirectives(
Expand Down
48 changes: 48 additions & 0 deletions llvm/lib/Target/TargetLoweringObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -136,6 +138,52 @@ 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());
if (F->hasDLLImportStorageClass())
return nullptr;
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
Expand Down
51 changes: 51 additions & 0 deletions llvm/test/MC/COFF/cgprofile.ll
Original file line number Diff line number Diff line change
@@ -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:]

0 comments on commit 506b617

Please sign in to comment.