@@ -253,6 +253,22 @@ class PPCAIXAsmPrinter : public PPCAsmPrinter {
253
253
DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1 >>
254
254
GOAliasMap;
255
255
256
+ // The __profd_* symbol for the profiling instrumentation data and the
257
+ // corresponding __profc_* counters it refernces.
258
+ struct ProfilingSubSection {
259
+ MCSectionXCOFF *ProfD;
260
+ MCSectionXCOFF *ProfC;
261
+ };
262
+
263
+ // Collect the 'sub-sections' of the profile-generate symbols
264
+ // so we can:
265
+ // 1) rename to the common CSECT name after emission.
266
+ // 2) emit the refs from the profc_ symbol to the related CSECTs.
267
+ SmallVector<ProfilingSubSection> ProfGenSubSections;
268
+
269
+ void emitSharedSectionPGORefs (Module &M);
270
+ void emitSplitSectionPGORefs ();
271
+
256
272
uint16_t getNumberOfVRSaved ();
257
273
void emitTracebackTable ();
258
274
@@ -2792,6 +2808,57 @@ void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) {
2792
2808
auto *Csect = static_cast <MCSectionXCOFF *>(
2793
2809
getObjFileLowering ().SectionForGlobal (GV, GVKind, TM));
2794
2810
2811
+ // When compiling with function sections enabled, we need some special
2812
+ // codegen to rename the CSECTs. For each profiling data symbol find its
2813
+ // associated profiling counters.
2814
+ if (TM.getFunctionSections () &&
2815
+ Csect->getName ().starts_with (" __llvm_prf_data." )) {
2816
+ // Unraveling the initializer to find the related counters variable. The
2817
+ // initializer is a structure whose third member is a subtract expression
2818
+ // between the counters label and the label for the start of this structure.
2819
+ // Use the subtract expression to get the GlobalValue for the counters
2820
+ // global.
2821
+ assert (GV->hasInitializer () &&
2822
+ " profiling data symbol must have an initializer" );
2823
+ assert (isa<ConstantStruct>(GV->getInitializer ()) &&
2824
+ " expect the initializer for a profiling data symbol to be a struct" );
2825
+ const ConstantStruct *Initializer =
2826
+ cast<ConstantStruct>(GV->getInitializer ());
2827
+
2828
+ // The initializer structure is: { i64, i64, i32, ptr, ptr, i32, [4 x i16] }
2829
+ // and the reference to the global variable for the counters is in the
2830
+ // first i32 member.
2831
+ const Constant *Member = Initializer->getAggregateElement (2 );
2832
+ assert (Member && " profiling data symbol has more then 3 elements" );
2833
+
2834
+ // Want to decompose a constant expression of the form:
2835
+ // sub (ptrtoint (ptr @__profc_sym), ptrtoint (ptr @__profd_sym))
2836
+ // to get the GlobalVariable for the '@__profc_sym` symbol.
2837
+ assert (isa<ConstantExpr>(Member) &&
2838
+ " expected member initializer is a constant expression." );
2839
+ const ConstantExpr *CExpr = cast<ConstantExpr>(Member);
2840
+ assert (CExpr->getOpcode () == Instruction::Sub &&
2841
+ " expected member intializer is a sub expression." );
2842
+
2843
+ Value *V1 = CExpr->getOperand (0 );
2844
+ assert (V1 && isa<ConstantExpr>(V1) &&
2845
+ " expected sub expression operand to be constant expr." );
2846
+ ConstantExpr *PointerToIntExpr = cast<ConstantExpr>(V1);
2847
+ assert (PointerToIntExpr->isCast () && " unexpected operand type." );
2848
+
2849
+ Value *PointerToIntOperand = PointerToIntExpr->getOperand (0 );
2850
+ assert (isa<GlobalVariable>(PointerToIntOperand) &&
2851
+ " expected global variable of profc symbol" );
2852
+
2853
+ const GlobalVariable *ProfCGV = cast<GlobalVariable>(PointerToIntOperand);
2854
+ // Map the global variable to its CSECT.
2855
+ SectionKind ProfCKind = getObjFileLowering ().getKindForGlobal (GV, TM);
2856
+ MCSectionXCOFF *ProfCCsect = cast<MCSectionXCOFF>(
2857
+ getObjFileLowering ().SectionForGlobal (ProfCGV, ProfCKind, TM));
2858
+
2859
+ ProfGenSubSections.push_back ({Csect, ProfCCsect});
2860
+ }
2861
+
2795
2862
// Switch to the containing csect.
2796
2863
OutStreamer->switchSection (Csect);
2797
2864
@@ -2893,7 +2960,7 @@ void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2893
2960
getObjFileLowering ().getFunctionEntryPointSymbol (Alias, TM));
2894
2961
}
2895
2962
2896
- void PPCAIXAsmPrinter::emitPGORefs (Module &M) {
2963
+ void PPCAIXAsmPrinter::emitSharedSectionPGORefs (Module &M) {
2897
2964
if (!OutContext.hasXCOFFSection (
2898
2965
" __llvm_prf_cnts" ,
2899
2966
XCOFF::CsectProperties (XCOFF::XMC_RW, XCOFF::XTY_SD)))
@@ -2942,6 +3009,54 @@ void PPCAIXAsmPrinter::emitPGORefs(Module &M) {
2942
3009
}
2943
3010
}
2944
3011
3012
+ void PPCAIXAsmPrinter::emitSplitSectionPGORefs () {
3013
+ MCSymbol *NamesSym = nullptr ;
3014
+ MCSymbol *VNDSSym = nullptr ;
3015
+
3016
+ if (OutContext.hasXCOFFSection (
3017
+ " __llvm_prf_names" ,
3018
+ XCOFF::CsectProperties (XCOFF::XMC_RO, XCOFF::XTY_SD)))
3019
+ NamesSym = OutContext.getOrCreateSymbol (" __llvm_prf_names[RO]" );
3020
+
3021
+ if (OutContext.hasXCOFFSection (
3022
+ " __llvm_prf_vnds" ,
3023
+ XCOFF::CsectProperties (XCOFF::XMC_RW, XCOFF::XTY_SD)))
3024
+ VNDSSym = OutContext.getOrCreateSymbol (" __llvm_prf_vnds[RW]" );
3025
+
3026
+ for (auto SubSections : ProfGenSubSections) {
3027
+ MCSectionXCOFF *ProfDCsect = SubSections.ProfD ;
3028
+ MCSectionXCOFF *ProfCCsect = SubSections.ProfC ;
3029
+
3030
+ OutStreamer->switchSection (ProfCCsect);
3031
+
3032
+ if (NamesSym)
3033
+ OutStreamer->emitXCOFFRefDirective (NamesSym);
3034
+
3035
+ if (VNDSSym)
3036
+ OutStreamer->emitXCOFFRefDirective (VNDSSym);
3037
+
3038
+ OutStreamer->emitXCOFFRefDirective (ProfDCsect->getQualNameSymbol ());
3039
+
3040
+ // Rename the subsection for the counters
3041
+ OutStreamer->emitXCOFFRenameDirective (ProfCCsect->getQualNameSymbol (),
3042
+ " __llvm_prf_cnts" );
3043
+ OutStreamer->addBlankLine ();
3044
+
3045
+ // Rename the subsection for the data.
3046
+ OutStreamer->switchSection (ProfDCsect);
3047
+ OutStreamer->emitXCOFFRenameDirective (ProfDCsect->getQualNameSymbol (),
3048
+ " __llvm_prf_data" );
3049
+ OutStreamer->addBlankLine ();
3050
+ }
3051
+ }
3052
+
3053
+ void PPCAIXAsmPrinter::emitPGORefs (Module &M) {
3054
+ if (!TM.getFunctionSections ())
3055
+ emitSharedSectionPGORefs (M);
3056
+ else
3057
+ emitSplitSectionPGORefs ();
3058
+ }
3059
+
2945
3060
void PPCAIXAsmPrinter::emitGCOVRefs () {
2946
3061
if (!OutContext.hasXCOFFSection (
2947
3062
" __llvm_gcov_ctr_section" ,
0 commit comments