Skip to content

Commit

Permalink
[DebugInfo][InstrRef] Use PHI placement utilities for machine locations
Browse files Browse the repository at this point in the history
InstrRefBasedLDV used to try and determine which values are in which
registers using a lattice approach; however this is hard to understand, and
broken in various ways. This patch replaces that approach with a standard
SSA approach using existing LLVM utilities. PHIs are placed at dominance
frontiers; value propagation then eliminates un-necessary PHIs.

This patch also adds a bunch of unit tests that should cover many of the
weirder forms of control flow.

Differential Revision: https://reviews.llvm.org/D110173
  • Loading branch information
jmorse committed Oct 13, 2021
1 parent 5158cfe commit a3936a6
Show file tree
Hide file tree
Showing 6 changed files with 1,258 additions and 244 deletions.
390 changes: 191 additions & 199 deletions llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp

Large diffs are not rendered by default.

30 changes: 21 additions & 9 deletions llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
Expand Up @@ -581,6 +581,7 @@ class InstrRefBasedLDV : public LDVImpl {
/// Used as the result type for the variable value dataflow problem.
using LiveInsT = SmallVector<SmallVector<VarAndLoc, 8>, 8>;

MachineDominatorTree *DomTree;
const TargetRegisterInfo *TRI;
const TargetInstrInfo *TII;
const TargetFrameLowering *TFI;
Expand Down Expand Up @@ -728,8 +729,19 @@ class InstrRefBasedLDV : public LDVImpl {
/// live-out arrays to the (initialized to zero) multidimensional arrays in
/// \p MInLocs and \p MOutLocs. The outer dimension is indexed by block
/// number, the inner by LocIdx.
void mlocDataflow(ValueIDNum **MInLocs, ValueIDNum **MOutLocs,
SmallVectorImpl<MLocTransferMap> &MLocTransfer);
void buildMLocValueMap(MachineFunction &MF, ValueIDNum **MInLocs,
ValueIDNum **MOutLocs,
SmallVectorImpl<MLocTransferMap> &MLocTransfer);

/// Calculate the iterated-dominance-frontier for a set of defs, using the
/// existing LLVM facilities for this. Works for a single "value" or
/// machine/variable location.
/// \p AllBlocks Set of blocks where we might consume the value.
/// \p DefBlocks Set of blocks where the value/location is defined.
/// \p PHIBlocks Output set of blocks where PHIs must be placed.
void BlockPHIPlacement(const SmallPtrSetImpl<MachineBasicBlock *> &AllBlocks,
const SmallPtrSetImpl<MachineBasicBlock *> &DefBlocks,
SmallVectorImpl<MachineBasicBlock *> &PHIBlocks);

/// Perform a control flow join (lattice value meet) of the values in machine
/// locations at \p MBB. Follows the algorithm described in the file-comment,
Expand All @@ -738,16 +750,15 @@ class InstrRefBasedLDV : public LDVImpl {
/// \p InLocs. \returns two bools -- the first indicates whether a change
/// was made, the second whether a lattice downgrade occurred. If the latter
/// is true, revisiting this block is necessary.
std::tuple<bool, bool>
mlocJoin(MachineBasicBlock &MBB,
SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
ValueIDNum **OutLocs, ValueIDNum *InLocs);
bool mlocJoin(MachineBasicBlock &MBB,
SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
ValueIDNum **OutLocs, ValueIDNum *InLocs);

/// Solve the variable value dataflow problem, for a single lexical scope.
/// Uses the algorithm from the file comment to resolve control flow joins,
/// although there are extra hacks, see vlocJoin. Reads the
/// locations of values from the \p MInLocs and \p MOutLocs arrays (see
/// mlocDataflow) and reads the variable values transfer function from
/// buildMLocValueMap) and reads the variable values transfer function from
/// \p AllTheVlocs. Live-in and Live-out variable values are stored locally,
/// with the live-ins permanently stored to \p Output once the fixedpoint is
/// reached.
Expand Down Expand Up @@ -824,8 +835,9 @@ class InstrRefBasedLDV : public LDVImpl {
/// RPOT block ordering.
void initialSetup(MachineFunction &MF);

bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC,
unsigned InputBBLimit, unsigned InputDbgValLimit) override;
bool ExtendRanges(MachineFunction &MF, MachineDominatorTree *DomTree,
TargetPassConfig *TPC, unsigned InputBBLimit,
unsigned InputDbgValLimit) override;

public:
/// Default construct and initialize the pass.
Expand Down
18 changes: 13 additions & 5 deletions llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
Expand Up @@ -81,6 +81,7 @@ class LiveDebugValues : public MachineFunctionPass {
private:
LDVImpl *TheImpl;
TargetPassConfig *TPC;
MachineDominatorTree MDT;
};

char LiveDebugValues::ID = 0;
Expand All @@ -97,18 +98,25 @@ LiveDebugValues::LiveDebugValues() : MachineFunctionPass(ID) {
}

bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) {
bool InstrRefBased = MF.useDebugInstrRef();
// Allow the user to force selection of InstrRef LDV.
InstrRefBased |= ForceInstrRefLDV;

if (!TheImpl) {
TPC = getAnalysisIfAvailable<TargetPassConfig>();
bool InstrRefBased = MF.useDebugInstrRef();

// Allow the user to force selection of InstrRef LDV.
InstrRefBased |= ForceInstrRefLDV;

if (InstrRefBased)
TheImpl = llvm::makeInstrRefBasedLiveDebugValues();
else
TheImpl = llvm::makeVarLocBasedLiveDebugValues();
}

return TheImpl->ExtendRanges(MF, TPC, InputBBLimit, InputDbgValueLimit);
MachineDominatorTree *DomTree = nullptr;
if (InstrRefBased) {
DomTree = &MDT;
MDT.calculate(MF);
}

return TheImpl->ExtendRanges(MF, DomTree, TPC, InputBBLimit,
InputDbgValueLimit);
}
5 changes: 3 additions & 2 deletions llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.h
Expand Up @@ -9,6 +9,7 @@
#ifndef LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_LIVEDEBUGVALUES_H
#define LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_LIVEDEBUGVALUES_H

#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/TargetPassConfig.h"

Expand All @@ -23,8 +24,8 @@ inline namespace SharedLiveDebugValues {
// implementation.
class LDVImpl {
public:
virtual bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC,
unsigned InputBBLimit,
virtual bool ExtendRanges(MachineFunction &MF, MachineDominatorTree *DomTree,
TargetPassConfig *TPC, unsigned InputBBLimit,
unsigned InputDbgValLimit) = 0;
virtual ~LDVImpl() {}
};
Expand Down
11 changes: 7 additions & 4 deletions llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
Expand Up @@ -1014,8 +1014,9 @@ class VarLocBasedLDV : public LDVImpl {
/// had their instruction creation deferred.
void flushPendingLocs(VarLocInMBB &PendingInLocs, VarLocMap &VarLocIDs);

bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC,
unsigned InputBBLimit, unsigned InputDbgValLimit) override;
bool ExtendRanges(MachineFunction &MF, MachineDominatorTree *DomTree,
TargetPassConfig *TPC, unsigned InputBBLimit,
unsigned InputDbgValLimit) override;

public:
/// Default construct and initialize the pass.
Expand Down Expand Up @@ -2107,9 +2108,11 @@ void VarLocBasedLDV::recordEntryValue(const MachineInstr &MI,

/// Calculate the liveness information for the given machine function and
/// extend ranges across basic blocks.
bool VarLocBasedLDV::ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC,
unsigned InputBBLimit,
bool VarLocBasedLDV::ExtendRanges(MachineFunction &MF,
MachineDominatorTree *DomTree,
TargetPassConfig *TPC, unsigned InputBBLimit,
unsigned InputDbgValLimit) {
(void)DomTree;
LLVM_DEBUG(dbgs() << "\nDebug Range Extension\n");

if (!MF.getFunction().getSubprogram())
Expand Down

0 comments on commit a3936a6

Please sign in to comment.