@@ -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
@@ -2810,6 +2826,57 @@ void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) {
2810
2826
MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
2811
2827
getObjFileLowering ().SectionForGlobal (GV, GVKind, TM));
2812
2828
2829
+ // When compiling with function sections enabled, we need some special
2830
+ // codegen to rename the CSECTs. For each profiling data symbol find its
2831
+ // associated profiling counters.
2832
+ if (TM.getFunctionSections () &&
2833
+ Csect->getName ().starts_with (" __llvm_prf_data." )) {
2834
+ // Unraveling the initializer to find the related counters variable. The
2835
+ // initializer is a structure whose third member is a subtract expression
2836
+ // between the counters label and the label for the start of this structure.
2837
+ // Use the subtract expression to get the GlobalValue for the counters
2838
+ // global.
2839
+ assert (GV->hasInitializer () &&
2840
+ " profiling data symbol must have an initializer" );
2841
+ assert (isa<ConstantStruct>(GV->getInitializer ()) &&
2842
+ " expect the initializer for a profiling data symbol to be a struct" );
2843
+ const ConstantStruct *Initializer =
2844
+ cast<ConstantStruct>(GV->getInitializer ());
2845
+
2846
+ // The initializer structure is: { i64, i64, i32, ptr, ptr, i32, [4 x i16] }
2847
+ // and the reference to the global variable for the counters is in the
2848
+ // first i32 member.
2849
+ const Constant *Member = Initializer->getAggregateElement (2 );
2850
+ assert (Member && " profiling data symbol has more then 3 elements" );
2851
+
2852
+ // Want to decompose a constant expression of the form:
2853
+ // sub (ptrtoint (ptr @__profc_sym), ptrtoint (ptr @__profd_sym))
2854
+ // to get the GlobalVariable for the '@__profc_sym` symbol.
2855
+ assert (isa<ConstantExpr>(Member) &&
2856
+ " expected member initializer is a constant expression." );
2857
+ const ConstantExpr *CExpr = cast<ConstantExpr>(Member);
2858
+ assert (CExpr->getOpcode () == Instruction::Sub &&
2859
+ " expected member intializer is a sub expression." );
2860
+
2861
+ Value *V1 = CExpr->getOperand (0 );
2862
+ assert (V1 && isa<ConstantExpr>(V1) &&
2863
+ " expected sub expression operand to be constant expr." );
2864
+ ConstantExpr *PointerToIntExpr = cast<ConstantExpr>(V1);
2865
+ assert (PointerToIntExpr->isCast () && " unexpected operand type." );
2866
+
2867
+ Value *PointerToIntOperand = PointerToIntExpr->getOperand (0 );
2868
+ assert (isa<GlobalVariable>(PointerToIntOperand) &&
2869
+ " expected global variable of profc symbol" );
2870
+
2871
+ const GlobalVariable *ProfCGV = cast<GlobalVariable>(PointerToIntOperand);
2872
+ // Map the global variable to its CSECT.
2873
+ SectionKind ProfCKind = getObjFileLowering ().getKindForGlobal (GV, TM);
2874
+ MCSectionXCOFF *ProfCCsect = cast<MCSectionXCOFF>(
2875
+ getObjFileLowering ().SectionForGlobal (ProfCGV, ProfCKind, TM));
2876
+
2877
+ ProfGenSubSections.push_back ({Csect, ProfCCsect});
2878
+ }
2879
+
2813
2880
// Switch to the containing csect.
2814
2881
OutStreamer->switchSection (Csect);
2815
2882
@@ -2911,7 +2978,7 @@ void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2911
2978
getObjFileLowering ().getFunctionEntryPointSymbol (Alias, TM));
2912
2979
}
2913
2980
2914
- void PPCAIXAsmPrinter::emitPGORefs (Module &M) {
2981
+ void PPCAIXAsmPrinter::emitSharedSectionPGORefs (Module &M) {
2915
2982
if (!OutContext.hasXCOFFSection (
2916
2983
" __llvm_prf_cnts" ,
2917
2984
XCOFF::CsectProperties (XCOFF::XMC_RW, XCOFF::XTY_SD)))
@@ -2960,6 +3027,54 @@ void PPCAIXAsmPrinter::emitPGORefs(Module &M) {
2960
3027
}
2961
3028
}
2962
3029
3030
+ void PPCAIXAsmPrinter::emitSplitSectionPGORefs () {
3031
+ MCSymbol *NamesSym = nullptr ;
3032
+ MCSymbol *VNDSSym = nullptr ;
3033
+
3034
+ if (OutContext.hasXCOFFSection (
3035
+ " __llvm_prf_names" ,
3036
+ XCOFF::CsectProperties (XCOFF::XMC_RO, XCOFF::XTY_SD)))
3037
+ NamesSym = OutContext.getOrCreateSymbol (" __llvm_prf_names[RO]" );
3038
+
3039
+ if (OutContext.hasXCOFFSection (
3040
+ " __llvm_prf_vnds" ,
3041
+ XCOFF::CsectProperties (XCOFF::XMC_RW, XCOFF::XTY_SD)))
3042
+ VNDSSym = OutContext.getOrCreateSymbol (" __llvm_prf_vnds[RW]" );
3043
+
3044
+ for (auto SubSections : ProfGenSubSections) {
3045
+ MCSectionXCOFF *ProfDCsect = SubSections.ProfD ;
3046
+ MCSectionXCOFF *ProfCCsect = SubSections.ProfC ;
3047
+
3048
+ OutStreamer->switchSection (ProfCCsect);
3049
+
3050
+ if (NamesSym)
3051
+ OutStreamer->emitXCOFFRefDirective (NamesSym);
3052
+
3053
+ if (VNDSSym)
3054
+ OutStreamer->emitXCOFFRefDirective (VNDSSym);
3055
+
3056
+ OutStreamer->emitXCOFFRefDirective (ProfDCsect->getQualNameSymbol ());
3057
+
3058
+ // Rename the subsection for the counters
3059
+ OutStreamer->emitXCOFFRenameDirective (ProfCCsect->getQualNameSymbol (),
3060
+ " __llvm_prf_cnts" );
3061
+ OutStreamer->addBlankLine ();
3062
+
3063
+ // Rename the subsection for the data.
3064
+ OutStreamer->switchSection (ProfDCsect);
3065
+ OutStreamer->emitXCOFFRenameDirective (ProfDCsect->getQualNameSymbol (),
3066
+ " __llvm_prf_data" );
3067
+ OutStreamer->addBlankLine ();
3068
+ }
3069
+ }
3070
+
3071
+ void PPCAIXAsmPrinter::emitPGORefs (Module &M) {
3072
+ if (!TM.getFunctionSections ())
3073
+ emitSharedSectionPGORefs (M);
3074
+ else
3075
+ emitSplitSectionPGORefs ();
3076
+ }
3077
+
2963
3078
void PPCAIXAsmPrinter::emitGCOVRefs () {
2964
3079
if (!OutContext.hasXCOFFSection (
2965
3080
" __llvm_gcov_ctr_section" ,
0 commit comments