@@ -97,8 +97,6 @@ STATISTIC(MissingAllocForContextId,
97
97
" Number of missing alloc nodes for context ids" );
98
98
STATISTIC (SkippedCallsCloning,
99
99
" Number of calls skipped during cloning due to unexpected operand" );
100
- STATISTIC (MismatchedCloneAssignments,
101
- " Number of callsites assigned to call multiple non-matching clones" );
102
100
103
101
static cl::opt<std::string> DotFilePathPrefix (
104
102
" memprof-dot-file-path-prefix" , cl::init(" " ), cl::Hidden,
@@ -2062,20 +2060,6 @@ static bool isMemProfClone(const Function &F) {
2062
2060
return F.getName ().contains (MemProfCloneSuffix);
2063
2061
}
2064
2062
2065
- // Return the clone number of the given function by extracting it from the
2066
- // memprof suffix. Assumes the caller has already confirmed it is a memprof
2067
- // clone.
2068
- static unsigned getMemProfCloneNum (const Function &F) {
2069
- assert (isMemProfClone (F));
2070
- auto Pos = F.getName ().find_last_of (' .' );
2071
- assert (Pos > 0 );
2072
- unsigned CloneNo;
2073
- bool Err = F.getName ().drop_front (Pos + 1 ).getAsInteger (10 , CloneNo);
2074
- assert (!Err);
2075
- (void )Err;
2076
- return CloneNo;
2077
- }
2078
-
2079
2063
std::string ModuleCallsiteContextGraph::getLabel (const Function *Func,
2080
2064
const Instruction *Call,
2081
2065
unsigned CloneNo) const {
@@ -3995,22 +3979,7 @@ IndexCallsiteContextGraph::getAllocationCallType(const CallInfo &Call) const {
3995
3979
3996
3980
void ModuleCallsiteContextGraph::updateCall (CallInfo &CallerCall,
3997
3981
FuncInfo CalleeFunc) {
3998
- auto *CurF = cast<CallBase>(CallerCall.call ())->getCalledFunction ();
3999
- auto NewCalleeCloneNo = CalleeFunc.cloneNo ();
4000
- if (isMemProfClone (*CurF)) {
4001
- // If we already assigned this callsite to call a specific non-default
4002
- // clone (i.e. not the original function which is clone 0), ensure that we
4003
- // aren't trying to now update it to call a different clone, which is
4004
- // indicative of a bug in the graph or function assignment.
4005
- auto CurCalleeCloneNo = getMemProfCloneNum (*CurF);
4006
- if (CurCalleeCloneNo != NewCalleeCloneNo) {
4007
- LLVM_DEBUG (dbgs () << " Mismatch in call clone assignment: was "
4008
- << CurCalleeCloneNo << " now " << NewCalleeCloneNo
4009
- << " \n " );
4010
- MismatchedCloneAssignments++;
4011
- }
4012
- }
4013
- if (NewCalleeCloneNo > 0 )
3982
+ if (CalleeFunc.cloneNo () > 0 )
4014
3983
cast<CallBase>(CallerCall.call ())->setCalledFunction (CalleeFunc.func ());
4015
3984
OREGetter (CallerCall.call ()->getFunction ())
4016
3985
.emit (OptimizationRemark (DEBUG_TYPE, " MemprofCall" , CallerCall.call ())
@@ -4026,19 +3995,7 @@ void IndexCallsiteContextGraph::updateCall(CallInfo &CallerCall,
4026
3995
assert (CI &&
4027
3996
" Caller cannot be an allocation which should not have profiled calls" );
4028
3997
assert (CI->Clones .size () > CallerCall.cloneNo ());
4029
- auto NewCalleeCloneNo = CalleeFunc.cloneNo ();
4030
- auto &CurCalleeCloneNo = CI->Clones [CallerCall.cloneNo ()];
4031
- // If we already assigned this callsite to call a specific non-default
4032
- // clone (i.e. not the original function which is clone 0), ensure that we
4033
- // aren't trying to now update it to call a different clone, which is
4034
- // indicative of a bug in the graph or function assignment.
4035
- if (CurCalleeCloneNo != 0 && CurCalleeCloneNo != NewCalleeCloneNo) {
4036
- LLVM_DEBUG (dbgs () << " Mismatch in call clone assignment: was "
4037
- << CurCalleeCloneNo << " now " << NewCalleeCloneNo
4038
- << " \n " );
4039
- MismatchedCloneAssignments++;
4040
- }
4041
- CurCalleeCloneNo = NewCalleeCloneNo;
3998
+ CI->Clones [CallerCall.cloneNo ()] = CalleeFunc.cloneNo ();
4042
3999
}
4043
4000
4044
4001
// Update the debug information attached to NewFunc to use the clone Name. Note
@@ -4746,19 +4703,6 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4746
4703
// where the callers were assigned to different clones of a function.
4747
4704
}
4748
4705
4749
- auto FindFirstAvailFuncClone = [&]() {
4750
- // Find first function in FuncClonesToCallMap without an assigned
4751
- // clone of this callsite Node. We should always have one
4752
- // available at this point due to the earlier cloning when the
4753
- // FuncClonesToCallMap size was smaller than the clone number.
4754
- for (auto &CF : FuncClonesToCallMap) {
4755
- if (!FuncCloneToCurNodeCloneMap.count (CF.first ))
4756
- return CF.first ;
4757
- }
4758
- assert (false &&
4759
- " Expected an available func clone for this callsite clone" );
4760
- };
4761
-
4762
4706
// See if we can use existing function clone. Walk through
4763
4707
// all caller edges to see if any have already been assigned to
4764
4708
// a clone of this callsite's function. If we can use it, do so. If not,
@@ -4875,7 +4819,16 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4875
4819
// clone of OrigFunc for another caller during this iteration over
4876
4820
// its caller edges.
4877
4821
if (!FuncCloneAssignedToCurCallsiteClone) {
4878
- FuncCloneAssignedToCurCallsiteClone = FindFirstAvailFuncClone ();
4822
+ // Find first function in FuncClonesToCallMap without an assigned
4823
+ // clone of this callsite Node. We should always have one
4824
+ // available at this point due to the earlier cloning when the
4825
+ // FuncClonesToCallMap size was smaller than the clone number.
4826
+ for (auto &CF : FuncClonesToCallMap) {
4827
+ if (!FuncCloneToCurNodeCloneMap.count (CF.first )) {
4828
+ FuncCloneAssignedToCurCallsiteClone = CF.first ;
4829
+ break ;
4830
+ }
4831
+ }
4879
4832
assert (FuncCloneAssignedToCurCallsiteClone);
4880
4833
// Assign Clone to FuncCloneAssignedToCurCallsiteClone
4881
4834
AssignCallsiteCloneToFuncClone (
@@ -4889,31 +4842,6 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4889
4842
FuncCloneAssignedToCurCallsiteClone);
4890
4843
}
4891
4844
}
4892
- // If we didn't assign a function clone to this callsite clone yet, e.g.
4893
- // none of its callers has a non-null call, do the assignment here.
4894
- // We want to ensure that every callsite clone is assigned to some
4895
- // function clone, so that the call updates below work as expected.
4896
- // In particular if this is the original callsite, we want to ensure it
4897
- // is assigned to the original function, otherwise the original function
4898
- // will appear available for assignment to other callsite clones,
4899
- // leading to unintended effects. For one, the unknown and not updated
4900
- // callers will call into cloned paths leading to the wrong hints,
4901
- // because they still call the original function (clone 0). Also,
4902
- // because all callsites start out as being clone 0 by default, we can't
4903
- // easily distinguish between callsites explicitly assigned to clone 0
4904
- // vs those never assigned, which can lead to multiple updates of the
4905
- // calls when invoking updateCall below, with mismatched clone values.
4906
- // TODO: Add a flag to the callsite nodes or some other mechanism to
4907
- // better distinguish and identify callsite clones that are not getting
4908
- // assigned to function clones as expected.
4909
- if (!FuncCloneAssignedToCurCallsiteClone) {
4910
- FuncCloneAssignedToCurCallsiteClone = FindFirstAvailFuncClone ();
4911
- assert (FuncCloneAssignedToCurCallsiteClone &&
4912
- " No available func clone for this callsite clone" );
4913
- AssignCallsiteCloneToFuncClone (
4914
- FuncCloneAssignedToCurCallsiteClone, Call, Clone,
4915
- /* IsAlloc=*/ AllocationCallToContextNodeMap.contains (Call));
4916
- }
4917
4845
}
4918
4846
if (VerifyCCG) {
4919
4847
checkNode<DerivedCCG, FuncTy, CallTy>(Node);
0 commit comments