@@ -2821,45 +2821,6 @@ void InstrRefBasedLDV::dump_mloc_transfer(
2821
2821
}
2822
2822
#endif
2823
2823
2824
- void InstrRefBasedLDV::emitLocations (
2825
- MachineFunction &MF, LiveInsT SavedLiveIns, ValueIDNum **MOutLocs,
2826
- ValueIDNum **MInLocs, DenseMap<DebugVariable, unsigned > &AllVarsNumbering,
2827
- const TargetPassConfig &TPC) {
2828
- TTracker = new TransferTracker (TII, MTracker, MF, *TRI, CalleeSavedRegs, TPC);
2829
- unsigned NumLocs = MTracker->getNumLocs ();
2830
- VTracker = nullptr ;
2831
-
2832
- // For each block, load in the machine value locations and variable value
2833
- // live-ins, then step through each instruction in the block. New DBG_VALUEs
2834
- // to be inserted will be created along the way.
2835
- for (MachineBasicBlock &MBB : MF) {
2836
- unsigned bbnum = MBB.getNumber ();
2837
- MTracker->reset ();
2838
- MTracker->loadFromArray (MInLocs[bbnum], bbnum);
2839
- TTracker->loadInlocs (MBB, MInLocs[bbnum], SavedLiveIns[MBB.getNumber ()],
2840
- NumLocs);
2841
-
2842
- CurBB = bbnum;
2843
- CurInst = 1 ;
2844
- for (auto &MI : MBB) {
2845
- process (MI, MOutLocs, MInLocs);
2846
- TTracker->checkInstForNewValues (CurInst, MI.getIterator ());
2847
- ++CurInst;
2848
- }
2849
-
2850
- // Our block information has now been converted into DBG_VALUEs, to be
2851
- // inserted below. Free the memory we allocated to track variable / register
2852
- // values. If we don't, we needlessy record the same info in memory twice.
2853
- delete[] MInLocs[bbnum];
2854
- delete[] MOutLocs[bbnum];
2855
- MInLocs[bbnum] = nullptr ;
2856
- MOutLocs[bbnum] = nullptr ;
2857
- SavedLiveIns[bbnum].clear ();
2858
- }
2859
-
2860
- emitTransfers (AllVarsNumbering);
2861
- }
2862
-
2863
2824
void InstrRefBasedLDV::initialSetup (MachineFunction &MF) {
2864
2825
// Build some useful data structures.
2865
2826
@@ -2902,8 +2863,175 @@ void InstrRefBasedLDV::initialSetup(MachineFunction &MF) {
2902
2863
#endif
2903
2864
}
2904
2865
2866
+ // Produce an "ejection map" for blocks, i.e., what's the highest-numbered
2867
+ // lexical scope it's used in. When exploring in DFS order and we pass that
2868
+ // scope, the block can be processed and any tracking information freed.
2869
+ void InstrRefBasedLDV::makeDepthFirstEjectionMap (
2870
+ SmallVectorImpl<unsigned > &EjectionMap,
2871
+ const ScopeToDILocT &ScopeToDILocation,
2872
+ ScopeToAssignBlocksT &ScopeToAssignBlocks) {
2873
+ SmallPtrSet<const MachineBasicBlock *, 8 > BlocksToExplore;
2874
+ SmallVector<std::pair<LexicalScope *, ssize_t >, 4 > WorkStack;
2875
+ auto *TopScope = LS.getCurrentFunctionScope ();
2876
+
2877
+ // Unlike lexical scope explorers, we explore in reverse order, to find the
2878
+ // "last" lexical scope used for each block early.
2879
+ WorkStack.push_back ({TopScope, TopScope->getChildren ().size () - 1 });
2880
+
2881
+ while (!WorkStack.empty ()) {
2882
+ auto &ScopePosition = WorkStack.back ();
2883
+ LexicalScope *WS = ScopePosition.first ;
2884
+ ssize_t ChildNum = ScopePosition.second --;
2885
+
2886
+ const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren ();
2887
+ if (ChildNum >= 0 ) {
2888
+ // If ChildNum is positive, there are remaining children to explore.
2889
+ // Push the child and its children-count onto the stack.
2890
+ auto &ChildScope = Children[ChildNum];
2891
+ WorkStack.push_back (
2892
+ std::make_pair (ChildScope, ChildScope->getChildren ().size () - 1 ));
2893
+ } else {
2894
+ WorkStack.pop_back ();
2895
+
2896
+ // We've explored all children and any later blocks: examine all blocks
2897
+ // in our scope. If they haven't yet had an ejection number set, then
2898
+ // this scope will be the last to use that block.
2899
+ auto DILocationIt = ScopeToDILocation.find (WS);
2900
+ if (DILocationIt != ScopeToDILocation.end ()) {
2901
+ getBlocksForScope (DILocationIt->second , BlocksToExplore,
2902
+ ScopeToAssignBlocks.find (WS)->second );
2903
+ for (auto *MBB : BlocksToExplore) {
2904
+ unsigned BBNum = MBB->getNumber ();
2905
+ if (EjectionMap[BBNum] == 0 )
2906
+ EjectionMap[BBNum] = WS->getDFSOut ();
2907
+ }
2908
+
2909
+ BlocksToExplore.clear ();
2910
+ }
2911
+ }
2912
+ }
2913
+ }
2914
+
2915
+ bool InstrRefBasedLDV::depthFirstVLocAndEmit (
2916
+ unsigned MaxNumBlocks, const ScopeToDILocT &ScopeToDILocation,
2917
+ const ScopeToVarsT &ScopeToVars, ScopeToAssignBlocksT &ScopeToAssignBlocks,
2918
+ LiveInsT &Output, ValueIDNum **MOutLocs, ValueIDNum **MInLocs,
2919
+ SmallVectorImpl<VLocTracker> &AllTheVLocs, MachineFunction &MF,
2920
+ DenseMap<DebugVariable, unsigned > &AllVarsNumbering,
2921
+ const TargetPassConfig &TPC) {
2922
+ TTracker = new TransferTracker (TII, MTracker, MF, *TRI, CalleeSavedRegs, TPC);
2923
+ unsigned NumLocs = MTracker->getNumLocs ();
2924
+ VTracker = nullptr ;
2925
+
2926
+ // No scopes? No variable locations.
2927
+ if (!LS.getCurrentFunctionScope ())
2928
+ return false ;
2929
+
2930
+ // Build map from block number to the last scope that uses the block.
2931
+ SmallVector<unsigned , 16 > EjectionMap;
2932
+ EjectionMap.resize (MaxNumBlocks, 0 );
2933
+ makeDepthFirstEjectionMap (EjectionMap, ScopeToDILocation,
2934
+ ScopeToAssignBlocks);
2935
+
2936
+ // Helper lambda for ejecting a block -- if nothing is going to use the block,
2937
+ // we can translate the variable location information into DBG_VALUEs and then
2938
+ // free all of InstrRefBasedLDV's data structures.
2939
+ auto EjectBlock = [&](MachineBasicBlock &MBB) -> void {
2940
+ unsigned BBNum = MBB.getNumber ();
2941
+ AllTheVLocs[BBNum].clear ();
2942
+
2943
+ // Prime the transfer-tracker, and then step through all the block
2944
+ // instructions, installing transfers.
2945
+ MTracker->reset ();
2946
+ MTracker->loadFromArray (MInLocs[BBNum], BBNum);
2947
+ TTracker->loadInlocs (MBB, MInLocs[BBNum], Output[BBNum], NumLocs);
2948
+
2949
+ CurBB = BBNum;
2950
+ CurInst = 1 ;
2951
+ for (auto &MI : MBB) {
2952
+ process (MI, MOutLocs, MInLocs);
2953
+ TTracker->checkInstForNewValues (CurInst, MI.getIterator ());
2954
+ ++CurInst;
2955
+ }
2956
+
2957
+ // Free machine-location tables for this block.
2958
+ delete[] MInLocs[BBNum];
2959
+ delete[] MOutLocs[BBNum];
2960
+ // Make ourselves brittle to use-after-free errors.
2961
+ MInLocs[BBNum] = nullptr ;
2962
+ MOutLocs[BBNum] = nullptr ;
2963
+ // We don't need live-in variable values for this block either.
2964
+ Output[BBNum].clear ();
2965
+ AllTheVLocs[BBNum].clear ();
2966
+ };
2967
+
2968
+ SmallPtrSet<const MachineBasicBlock *, 8 > BlocksToExplore;
2969
+ SmallVector<std::pair<LexicalScope *, ssize_t >, 4 > WorkStack;
2970
+ WorkStack.push_back ({LS.getCurrentFunctionScope (), 0 });
2971
+ unsigned HighestDFSIn = 0 ;
2972
+
2973
+ // Proceed to explore in depth first order.
2974
+ while (!WorkStack.empty ()) {
2975
+ auto &ScopePosition = WorkStack.back ();
2976
+ LexicalScope *WS = ScopePosition.first ;
2977
+ ssize_t ChildNum = ScopePosition.second ++;
2978
+
2979
+ // We obesrve scopes with children twice here, once descending in, once
2980
+ // ascending out of the scope nest. Use HighestDFSIn as a ratchet to ensure
2981
+ // we don't process a scope twice. Additionally, ignore scopes that don't
2982
+ // have a DILocation -- by proxy, this means we never tracked any variable
2983
+ // assignments in that scope.
2984
+ auto DILocIt = ScopeToDILocation.find (WS);
2985
+ if (HighestDFSIn <= WS->getDFSIn () && DILocIt != ScopeToDILocation.end ()) {
2986
+ const DILocation *DILoc = DILocIt->second ;
2987
+ auto &VarsWeCareAbout = ScopeToVars.find (WS)->second ;
2988
+ auto &BlocksInScope = ScopeToAssignBlocks.find (WS)->second ;
2989
+
2990
+ buildVLocValueMap (DILoc, VarsWeCareAbout, BlocksInScope, Output, MOutLocs,
2991
+ MInLocs, AllTheVLocs);
2992
+ }
2993
+
2994
+ HighestDFSIn = std::max (HighestDFSIn, WS->getDFSIn ());
2995
+
2996
+ // Descend into any scope nests.
2997
+ const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren ();
2998
+ if (ChildNum < (ssize_t )Children.size ()) {
2999
+ // There are children to explore -- push onto stack and continue.
3000
+ auto &ChildScope = Children[ChildNum];
3001
+ WorkStack.push_back (std::make_pair (ChildScope, 0 ));
3002
+ } else {
3003
+ WorkStack.pop_back ();
3004
+
3005
+ // We've explored a leaf, or have explored all the children of a scope.
3006
+ // Try to eject any blocks where this is the last scope it's relevant to.
3007
+ auto DILocationIt = ScopeToDILocation.find (WS);
3008
+ if (DILocationIt == ScopeToDILocation.end ())
3009
+ continue ;
3010
+
3011
+ getBlocksForScope (DILocationIt->second , BlocksToExplore,
3012
+ ScopeToAssignBlocks.find (WS)->second );
3013
+ for (auto *MBB : BlocksToExplore)
3014
+ if (WS->getDFSOut () == EjectionMap[MBB->getNumber ()])
3015
+ EjectBlock (const_cast <MachineBasicBlock &>(*MBB));
3016
+
3017
+ BlocksToExplore.clear ();
3018
+ }
3019
+ }
3020
+
3021
+ // Some artificial blocks may not have been ejected, meaning they're not
3022
+ // connected to an actual legitimate scope. This can technically happen
3023
+ // with things like the entry block. In theory, we shouldn't need to do
3024
+ // anything for such out-of-scope blocks, but for the sake of being similar
3025
+ // to VarLocBasedLDV, eject these too.
3026
+ for (auto *MBB : ArtificialBlocks)
3027
+ if (MOutLocs[MBB->getNumber ()])
3028
+ EjectBlock (*MBB);
3029
+
3030
+ return emitTransfers (AllVarsNumbering);
3031
+ }
3032
+
2905
3033
bool InstrRefBasedLDV::emitTransfers (
2906
- DenseMap<DebugVariable, unsigned > &AllVarsNumbering) {
3034
+ DenseMap<DebugVariable, unsigned > &AllVarsNumbering) {
2907
3035
// Go through all the transfers recorded in the TransferTracker -- this is
2908
3036
// both the live-ins to a block, and any movements of values that happen
2909
3037
// in the middle.
@@ -3098,26 +3226,12 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF,
3098
3226
delete[] MInLocs[Idx];
3099
3227
}
3100
3228
} else {
3101
- // Compute the extended ranges, iterating over scopes. There might be
3102
- // something to be said for ordering them by size/locality, but that's for
3103
- // the future. For each scope, solve the variable value problem, producing
3104
- // a map of variables to values in SavedLiveIns.
3105
- for (auto &P : ScopeToVars) {
3106
- buildVLocValueMap (ScopeToDILocation[P.first ], P.second ,
3107
- ScopeToAssignBlocks[P.first ], SavedLiveIns, MOutLocs, MInLocs,
3108
- vlocs);
3109
- }
3110
-
3111
- // Now that we've analysed variable assignments, free any tracking data.
3112
- vlocs.clear ();
3113
-
3114
- // Using the computed value locations and variable values for each block,
3115
- // create the DBG_VALUE instructions representing the extended variable
3116
- // locations.
3117
- emitLocations (MF, SavedLiveIns, MOutLocs, MInLocs, AllVarsNumbering, *TPC);
3118
-
3119
- // Did we actually make any changes? If we created any DBG_VALUEs, then yes.
3120
- Changed = TTracker->Transfers .size () != 0 ;
3229
+ // Optionally, solve the variable value problem and emit to blocks by using
3230
+ // a lexical-scope-depth search. It should be functionally identical to
3231
+ // the "else" block of this condition.
3232
+ Changed = depthFirstVLocAndEmit (
3233
+ MaxNumBlocks, ScopeToDILocation, ScopeToVars, ScopeToAssignBlocks,
3234
+ SavedLiveIns, MOutLocs, MInLocs, vlocs, MF, AllVarsNumbering, *TPC);
3121
3235
}
3122
3236
3123
3237
// Elements of these arrays will be deleted by emitLocations.
0 commit comments