@@ -2821,45 +2821,6 @@ void InstrRefBasedLDV::dump_mloc_transfer(
28212821}
28222822#endif
28232823
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-
28632824void InstrRefBasedLDV::initialSetup (MachineFunction &MF) {
28642825 // Build some useful data structures.
28652826
@@ -2902,8 +2863,175 @@ void InstrRefBasedLDV::initialSetup(MachineFunction &MF) {
29022863#endif
29032864}
29042865
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+
29053033bool InstrRefBasedLDV::emitTransfers (
2906- DenseMap<DebugVariable, unsigned > &AllVarsNumbering) {
3034+ DenseMap<DebugVariable, unsigned > &AllVarsNumbering) {
29073035 // Go through all the transfers recorded in the TransferTracker -- this is
29083036 // both the live-ins to a block, and any movements of values that happen
29093037 // in the middle.
@@ -3098,26 +3226,12 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF,
30983226 delete[] MInLocs[Idx];
30993227 }
31003228 } 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);
31213235 }
31223236
31233237 // Elements of these arrays will be deleted by emitLocations.
0 commit comments