summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp79
1 files changed, 53 insertions, 26 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index cd14a4f57f76..701a6a2f0f7a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -78,6 +78,8 @@
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
@@ -1672,7 +1674,7 @@ static ConstantInt *extractNumericCGTypeId(const Function &F) {
/// Emits .callgraph section.
void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
- FunctionInfo &FuncInfo) {
+ FunctionCallGraphInfo &FuncCGInfo) {
if (!MF.getTarget().Options.EmitCallGraphSection)
return;
@@ -1711,27 +1713,34 @@ void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
// Emit function kind, and type id if available.
if (!IsIndirectTarget) {
OutStreamer->emitInt64(
- static_cast<uint64_t>(FunctionInfo::FunctionKind::NOT_INDIRECT_TARGET));
+ static_cast<uint64_t>(FunctionKind::NOT_INDIRECT_TARGET));
} else {
if (const auto *TypeId = extractNumericCGTypeId(F)) {
- OutStreamer->emitInt64(static_cast<uint64_t>(
- FunctionInfo::FunctionKind::INDIRECT_TARGET_KNOWN_TID));
+ OutStreamer->emitInt64(
+ static_cast<uint64_t>(FunctionKind::INDIRECT_TARGET_KNOWN_TID));
OutStreamer->emitInt64(TypeId->getZExtValue());
} else {
- OutStreamer->emitInt64(static_cast<uint64_t>(
- FunctionInfo::FunctionKind::INDIRECT_TARGET_UNKNOWN_TID));
+ OutStreamer->emitInt64(
+ static_cast<uint64_t>(FunctionKind::INDIRECT_TARGET_UNKNOWN_TID));
}
}
// Emit callsite labels, where each element is a pair of type id and
// indirect callsite pc.
- const auto &CallSiteLabels = FuncInfo.CallSiteLabels;
+ const auto &CallSiteLabels = FuncCGInfo.CallSiteLabels;
OutStreamer->emitInt64(CallSiteLabels.size());
for (const auto &[TypeId, Label] : CallSiteLabels) {
OutStreamer->emitInt64(TypeId);
OutStreamer->emitSymbolValue(Label, TM.getProgramPointerSize());
}
- FuncInfo.CallSiteLabels.clear();
+ FuncCGInfo.CallSiteLabels.clear();
+
+ const auto &DirectCallees = FuncCGInfo.DirectCallees;
+ OutStreamer->emitInt64(DirectCallees.size());
+ for (const auto &CalleeSymbol : DirectCallees) {
+ OutStreamer->emitSymbolValue(CalleeSymbol, TM.getProgramPointerSize());
+ }
+ FuncCGInfo.DirectCallees.clear();
OutStreamer->popSection();
}
@@ -1866,20 +1875,40 @@ static StringRef getMIMnemonic(const MachineInstr &MI, MCStreamer &Streamer) {
return Name;
}
-void AsmPrinter::emitIndirectCalleeLabels(
- FunctionInfo &FuncInfo,
+void AsmPrinter::handleCallsiteForCallgraph(
+ FunctionCallGraphInfo &FuncCGInfo,
const MachineFunction::CallSiteInfoMap &CallSitesInfoMap,
const MachineInstr &MI) {
- // Only indirect calls have type identifiers set.
+ assert(MI.isCall() &&
+ "Callsite labels are meant for call instructions only.");
+ const MachineOperand &CalleeOperand = MI.getOperand(0);
+ if (CalleeOperand.isGlobal() || CalleeOperand.isSymbol()) {
+ // Handle direct calls.
+ MCSymbol *CalleeSymbol = nullptr;
+ switch (CalleeOperand.getType()) {
+ case llvm::MachineOperand::MO_GlobalAddress:
+ CalleeSymbol = getSymbol(CalleeOperand.getGlobal());
+ break;
+ case llvm::MachineOperand::MO_ExternalSymbol:
+ CalleeSymbol = GetExternalSymbolSymbol(CalleeOperand.getSymbolName());
+ break;
+ default:
+ llvm_unreachable(
+ "Expected to only handle direct call instructions here.");
+ }
+ FuncCGInfo.DirectCallees.insert(CalleeSymbol);
+ return; // Early exit after handling the direct call instruction.
+ }
const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
if (CallSiteInfo == CallSitesInfoMap.end())
return;
-
+ // Handle indirect callsite info.
+ // Only indirect calls have type identifiers set.
for (ConstantInt *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
MCSymbol *S = MF->getContext().createTempSymbol();
OutStreamer->emitLabel(S);
uint64_t CalleeTypeIdVal = CalleeTypeId->getZExtValue();
- FuncInfo.CallSiteLabels.emplace_back(CalleeTypeIdVal, S);
+ FuncCGInfo.CallSiteLabels.emplace_back(CalleeTypeIdVal, S);
}
}
@@ -1929,7 +1958,7 @@ void AsmPrinter::emitFunctionBody() {
MBBSectionRanges[MF->front().getSectionID()] =
MBBSectionRange{CurrentFnBegin, nullptr};
- FunctionInfo FuncInfo;
+ FunctionCallGraphInfo FuncCGInfo;
const auto &CallSitesInfoMap = MF->getCallSitesInfo();
for (auto &MBB : *MF) {
// Print a label for the basic block.
@@ -2066,7 +2095,7 @@ void AsmPrinter::emitFunctionBody() {
OutStreamer->emitLabel(createCallsiteEndSymbol(MBB));
if (TM.Options.EmitCallGraphSection && MI.isCall())
- emitIndirectCalleeLabels(FuncInfo, CallSitesInfoMap, MI);
+ handleCallsiteForCallgraph(FuncCGInfo, CallSitesInfoMap, MI);
// If there is a post-instruction symbol, emit a label for it here.
if (MCSymbol *S = MI.getPostInstrSymbol())
@@ -2248,7 +2277,7 @@ void AsmPrinter::emitFunctionBody() {
emitStackSizeSection(*MF);
// Emit section containing call graph metadata.
- emitCallGraphSection(*MF, FuncInfo);
+ emitCallGraphSection(*MF, FuncCGInfo);
// Emit .su file containing function stack size information.
emitStackUsage(*MF);
@@ -2508,6 +2537,8 @@ void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {
void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) {
if (!RS.needsSection())
return;
+ if (!RS.getFilename())
+ return;
MCSection *RemarksSection =
OutContext.getObjectFileInfo()->getRemarksSection();
@@ -2518,20 +2549,16 @@ void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) {
return;
}
- remarks::RemarkSerializer &RemarkSerializer = RS.getSerializer();
-
- std::optional<SmallString<128>> Filename;
- if (std::optional<StringRef> FilenameRef = RS.getFilename()) {
- Filename = *FilenameRef;
- sys::fs::make_absolute(*Filename);
- assert(!Filename->empty() && "The filename can't be empty.");
- }
+ SmallString<128> Filename = *RS.getFilename();
+ sys::fs::make_absolute(Filename);
+ assert(!Filename.empty() && "The filename can't be empty.");
std::string Buf;
raw_string_ostream OS(Buf);
+
+ remarks::RemarkSerializer &RemarkSerializer = RS.getSerializer();
std::unique_ptr<remarks::MetaSerializer> MetaSerializer =
- Filename ? RemarkSerializer.metaSerializer(OS, Filename->str())
- : RemarkSerializer.metaSerializer(OS);
+ RemarkSerializer.metaSerializer(OS, Filename);
MetaSerializer->emit();
// Switch to the remarks section.