|
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