|
78 | 78 | #include "llvm/IR/GlobalValue.h"
|
79 | 79 | #include "llvm/IR/GlobalVariable.h"
|
80 | 80 | #include "llvm/IR/Instruction.h"
|
| 81 | +#include "llvm/IR/Instructions.h" |
81 | 82 | #include "llvm/IR/LLVMRemarkStreamer.h"
|
82 | 83 | #include "llvm/IR/Mangler.h"
|
83 | 84 | #include "llvm/IR/Metadata.h"
|
@@ -1673,7 +1674,7 @@ static ConstantInt *extractNumericCGTypeId(const Function &F) {
|
1673 | 1674 |
|
1674 | 1675 | /// Emits .callgraph section.
|
1675 | 1676 | void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
|
1676 |
| - FunctionInfo &FuncInfo) { |
| 1677 | + FunctionCallGraphInfo &FuncCGInfo) { |
1677 | 1678 | if (!MF.getTarget().Options.EmitCallGraphSection)
|
1678 | 1679 | return;
|
1679 | 1680 |
|
@@ -1712,27 +1713,34 @@ void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
|
1712 | 1713 | // Emit function kind, and type id if available.
|
1713 | 1714 | if (!IsIndirectTarget) {
|
1714 | 1715 | OutStreamer->emitInt64(
|
1715 |
| - static_cast<uint64_t>(FunctionInfo::FunctionKind::NOT_INDIRECT_TARGET)); |
| 1716 | + static_cast<uint64_t>(FunctionKind::NOT_INDIRECT_TARGET)); |
1716 | 1717 | } else {
|
1717 | 1718 | if (const auto *TypeId = extractNumericCGTypeId(F)) {
|
1718 |
| - OutStreamer->emitInt64(static_cast<uint64_t>( |
1719 |
| - FunctionInfo::FunctionKind::INDIRECT_TARGET_KNOWN_TID)); |
| 1719 | + OutStreamer->emitInt64( |
| 1720 | + static_cast<uint64_t>(FunctionKind::INDIRECT_TARGET_KNOWN_TID)); |
1720 | 1721 | OutStreamer->emitInt64(TypeId->getZExtValue());
|
1721 | 1722 | } else {
|
1722 |
| - OutStreamer->emitInt64(static_cast<uint64_t>( |
1723 |
| - FunctionInfo::FunctionKind::INDIRECT_TARGET_UNKNOWN_TID)); |
| 1723 | + OutStreamer->emitInt64( |
| 1724 | + static_cast<uint64_t>(FunctionKind::INDIRECT_TARGET_UNKNOWN_TID)); |
1724 | 1725 | }
|
1725 | 1726 | }
|
1726 | 1727 |
|
1727 | 1728 | // Emit callsite labels, where each element is a pair of type id and
|
1728 | 1729 | // indirect callsite pc.
|
1729 |
| - const auto &CallSiteLabels = FuncInfo.CallSiteLabels; |
| 1730 | + const auto &CallSiteLabels = FuncCGInfo.CallSiteLabels; |
1730 | 1731 | OutStreamer->emitInt64(CallSiteLabels.size());
|
1731 | 1732 | for (const auto &[TypeId, Label] : CallSiteLabels) {
|
1732 | 1733 | OutStreamer->emitInt64(TypeId);
|
1733 | 1734 | OutStreamer->emitSymbolValue(Label, TM.getProgramPointerSize());
|
1734 | 1735 | }
|
1735 |
| - FuncInfo.CallSiteLabels.clear(); |
| 1736 | + FuncCGInfo.CallSiteLabels.clear(); |
| 1737 | + |
| 1738 | + const auto &DirectCallees = FuncCGInfo.DirectCallees; |
| 1739 | + OutStreamer->emitInt64(DirectCallees.size()); |
| 1740 | + for (const auto &CalleeSymbol : DirectCallees) { |
| 1741 | + OutStreamer->emitSymbolValue(CalleeSymbol, TM.getProgramPointerSize()); |
| 1742 | + } |
| 1743 | + FuncCGInfo.DirectCallees.clear(); |
1736 | 1744 |
|
1737 | 1745 | OutStreamer->popSection();
|
1738 | 1746 | }
|
@@ -1867,20 +1875,40 @@ static StringRef getMIMnemonic(const MachineInstr &MI, MCStreamer &Streamer) {
|
1867 | 1875 | return Name;
|
1868 | 1876 | }
|
1869 | 1877 |
|
1870 |
| -void AsmPrinter::emitIndirectCalleeLabels( |
1871 |
| - FunctionInfo &FuncInfo, |
| 1878 | +void AsmPrinter::handleCallsiteForCallgraph( |
| 1879 | + FunctionCallGraphInfo &FuncCGInfo, |
1872 | 1880 | const MachineFunction::CallSiteInfoMap &CallSitesInfoMap,
|
1873 | 1881 | const MachineInstr &MI) {
|
1874 |
| - // Only indirect calls have type identifiers set. |
| 1882 | + assert(MI.isCall() && |
| 1883 | + "Callsite labels are meant for call instructions only."); |
| 1884 | + const MachineOperand &CalleeOperand = MI.getOperand(0); |
| 1885 | + if (CalleeOperand.isGlobal() || CalleeOperand.isSymbol()) { |
| 1886 | + // Handle direct calls. |
| 1887 | + MCSymbol *CalleeSymbol = nullptr; |
| 1888 | + switch (CalleeOperand.getType()) { |
| 1889 | + case llvm::MachineOperand::MO_GlobalAddress: |
| 1890 | + CalleeSymbol = getSymbol(CalleeOperand.getGlobal()); |
| 1891 | + break; |
| 1892 | + case llvm::MachineOperand::MO_ExternalSymbol: |
| 1893 | + CalleeSymbol = GetExternalSymbolSymbol(CalleeOperand.getSymbolName()); |
| 1894 | + break; |
| 1895 | + default: |
| 1896 | + llvm_unreachable( |
| 1897 | + "Expected to only handle direct call instructions here."); |
| 1898 | + } |
| 1899 | + FuncCGInfo.DirectCallees.insert(CalleeSymbol); |
| 1900 | + return; // Early exit after handling the direct call instruction. |
| 1901 | + } |
1875 | 1902 | const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
|
1876 | 1903 | if (CallSiteInfo == CallSitesInfoMap.end())
|
1877 | 1904 | return;
|
1878 |
| - |
| 1905 | + // Handle indirect callsite info. |
| 1906 | + // Only indirect calls have type identifiers set. |
1879 | 1907 | for (ConstantInt *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
|
1880 | 1908 | MCSymbol *S = MF->getContext().createTempSymbol();
|
1881 | 1909 | OutStreamer->emitLabel(S);
|
1882 | 1910 | uint64_t CalleeTypeIdVal = CalleeTypeId->getZExtValue();
|
1883 |
| - FuncInfo.CallSiteLabels.emplace_back(CalleeTypeIdVal, S); |
| 1911 | + FuncCGInfo.CallSiteLabels.emplace_back(CalleeTypeIdVal, S); |
1884 | 1912 | }
|
1885 | 1913 | }
|
1886 | 1914 |
|
@@ -1930,7 +1958,7 @@ void AsmPrinter::emitFunctionBody() {
|
1930 | 1958 | MBBSectionRanges[MF->front().getSectionID()] =
|
1931 | 1959 | MBBSectionRange{CurrentFnBegin, nullptr};
|
1932 | 1960 |
|
1933 |
| - FunctionInfo FuncInfo; |
| 1961 | + FunctionCallGraphInfo FuncCGInfo; |
1934 | 1962 | const auto &CallSitesInfoMap = MF->getCallSitesInfo();
|
1935 | 1963 | for (auto &MBB : *MF) {
|
1936 | 1964 | // Print a label for the basic block.
|
@@ -2067,7 +2095,7 @@ void AsmPrinter::emitFunctionBody() {
|
2067 | 2095 | OutStreamer->emitLabel(createCallsiteEndSymbol(MBB));
|
2068 | 2096 |
|
2069 | 2097 | if (TM.Options.EmitCallGraphSection && MI.isCall())
|
2070 |
| - emitIndirectCalleeLabels(FuncInfo, CallSitesInfoMap, MI); |
| 2098 | + handleCallsiteForCallgraph(FuncCGInfo, CallSitesInfoMap, MI); |
2071 | 2099 |
|
2072 | 2100 | // If there is a post-instruction symbol, emit a label for it here.
|
2073 | 2101 | if (MCSymbol *S = MI.getPostInstrSymbol())
|
@@ -2249,7 +2277,7 @@ void AsmPrinter::emitFunctionBody() {
|
2249 | 2277 | emitStackSizeSection(*MF);
|
2250 | 2278 |
|
2251 | 2279 | // Emit section containing call graph metadata.
|
2252 |
| - emitCallGraphSection(*MF, FuncInfo); |
| 2280 | + emitCallGraphSection(*MF, FuncCGInfo); |
2253 | 2281 |
|
2254 | 2282 | // Emit .su file containing function stack size information.
|
2255 | 2283 | emitStackUsage(*MF);
|
|
0 commit comments