52
52
#include " ValueProfileCollector.h"
53
53
#include " llvm/ADT/APInt.h"
54
54
#include " llvm/ADT/ArrayRef.h"
55
+ #include " llvm/ADT/MapVector.h"
55
56
#include " llvm/ADT/STLExtras.h"
56
57
#include " llvm/ADT/SmallVector.h"
57
58
#include " llvm/ADT/Statistic.h"
63
64
#include " llvm/Analysis/BlockFrequencyInfo.h"
64
65
#include " llvm/Analysis/BranchProbabilityInfo.h"
65
66
#include " llvm/Analysis/CFG.h"
67
+ #include " llvm/Analysis/EHPersonalities.h"
66
68
#include " llvm/Analysis/LoopInfo.h"
67
69
#include " llvm/Analysis/OptimizationRemarkEmitter.h"
68
70
#include " llvm/Analysis/ProfileSummaryInfo.h"
@@ -799,6 +801,37 @@ BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *E) {
799
801
return canInstrument (InstrBB);
800
802
}
801
803
804
+ // When generating value profiling calls on Windows routines that make use of
805
+ // handler funclets for exception processing an operand bundle needs to attached
806
+ // to the called function. This routine will set \p OpBundles to contain the
807
+ // funclet information, if any is needed, that should be placed on the generated
808
+ // value profiling call for the value profile candidate call.
809
+ static void
810
+ populateEHOperandBundle (VPCandidateInfo &Cand,
811
+ DenseMap<BasicBlock *, ColorVector> &BlockColors,
812
+ SmallVectorImpl<OperandBundleDef> &OpBundles) {
813
+ auto *OrigCall = dyn_cast<CallBase>(Cand.AnnotatedInst );
814
+ if (OrigCall && !isa<IntrinsicInst>(OrigCall)) {
815
+ // The instrumentation call should belong to the same funclet as a
816
+ // non-intrinsic call, so just copy the operand bundle, if any exists.
817
+ Optional<OperandBundleUse> ParentFunclet =
818
+ OrigCall->getOperandBundle (LLVMContext::OB_funclet);
819
+ if (ParentFunclet)
820
+ OpBundles.emplace_back (OperandBundleDef (*ParentFunclet));
821
+ } else {
822
+ // Intrinsics or other instructions do not get funclet information from the
823
+ // front-end. Need to use the BlockColors that was computed by the routine
824
+ // colorEHFunclets to determine whether a funclet is needed.
825
+ if (!BlockColors.empty ()) {
826
+ const ColorVector &CV = BlockColors.find (OrigCall->getParent ())->second ;
827
+ assert (CV.size () == 1 && " non-unique color for block!" );
828
+ Instruction *EHPad = CV.front ()->getFirstNonPHI ();
829
+ if (EHPad->isEHPad ())
830
+ OpBundles.emplace_back (" funclet" , EHPad);
831
+ }
832
+ }
833
+ }
834
+
802
835
// Visit all edge and instrument the edges not in MST, and do value profiling.
803
836
// Critical edges will be split.
804
837
static void instrumentOneFunc (
@@ -839,6 +872,15 @@ static void instrumentOneFunc(
839
872
840
873
NumOfPGOICall += FuncInfo.ValueSites [IPVK_IndirectCallTarget].size ();
841
874
875
+ // Intrinsic function calls do not have funclet operand bundles needed for
876
+ // Windows exception handling attached to them. However, if value profiling is
877
+ // inserted for one of these calls, then a funclet value will need to be set
878
+ // on the instrumentation call based on the funclet coloring.
879
+ DenseMap<BasicBlock *, ColorVector> BlockColors;
880
+ if (F.hasPersonalityFn () &&
881
+ isFuncletEHPersonality (classifyEHPersonality (F.getPersonalityFn ())))
882
+ BlockColors = colorEHFunclets (F);
883
+
842
884
// For each VP Kind, walk the VP candidates and instrument each one.
843
885
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
844
886
unsigned SiteIndex = 0 ;
@@ -860,11 +902,14 @@ static void instrumentOneFunc(
860
902
ToProfile = Builder.CreatePtrToInt (Cand.V , Builder.getInt64Ty ());
861
903
assert (ToProfile && " value profiling Value is of unexpected type" );
862
904
905
+ SmallVector<OperandBundleDef, 1 > OpBundles;
906
+ populateEHOperandBundle (Cand, BlockColors, OpBundles);
863
907
Builder.CreateCall (
864
908
Intrinsic::getDeclaration (M, Intrinsic::instrprof_value_profile),
865
909
{ConstantExpr::getBitCast (FuncInfo.FuncNameVar , I8PtrTy),
866
910
Builder.getInt64 (FuncInfo.FunctionHash ), ToProfile,
867
- Builder.getInt32 (Kind), Builder.getInt32 (SiteIndex++)});
911
+ Builder.getInt32 (Kind), Builder.getInt32 (SiteIndex++)},
912
+ OpBundles);
868
913
}
869
914
} // IPVK_First <= Kind <= IPVK_Last
870
915
}
0 commit comments