diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 79 |
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. |
