Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Cherry-pick fixes for LiveDebugValues pass. #53

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 67 additions & 18 deletions lib/CodeGen/LiveDebugValues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/UniqueVector.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
Expand Down Expand Up @@ -60,6 +61,26 @@ class LiveDebugValues : public MachineFunctionPass {
private:
const TargetRegisterInfo *TRI;
const TargetInstrInfo *TII;
LexicalScopes LS;

/// Keeps track of lexical scopes associated with a user value's source
/// location.
class UserValueScopes {
DebugLoc DL;
LexicalScopes &LS;
SmallPtrSet<const MachineBasicBlock *, 4> LBlocks;

public:
UserValueScopes(DebugLoc D, LexicalScopes &L) : DL(std::move(D)), LS(L) {}

/// Return true if current scope dominates at least one machine
/// instruction in a given machine basic block.
bool dominates(MachineBasicBlock *MBB) {
if (LBlocks.empty())
LS.getMachineBasicBlocks(DL, LBlocks);
return LBlocks.count(MBB) != 0 || LS.dominates(DL, MBB);
}
};

/// Based on std::pair so it can be used as an index into a DenseMap.
typedef std::pair<const DILocalVariable *, const DILocation *>
Expand All @@ -83,7 +104,7 @@ class LiveDebugValues : public MachineFunctionPass {
struct VarLoc {
const DebugVariable Var;
const MachineInstr &MI; ///< Only used for cloning a new DBG_VALUE.

mutable UserValueScopes UVS;
enum { InvalidKind = 0, RegisterKind } Kind;

/// The value location. Stored separately to avoid repeatedly
Expand All @@ -96,9 +117,9 @@ class LiveDebugValues : public MachineFunctionPass {
uint64_t Hash;
} Loc;

VarLoc(const MachineInstr &MI)
VarLoc(const MachineInstr &MI, LexicalScopes &LS)
: Var(MI.getDebugVariable(), MI.getDebugLoc()->getInlinedAt()), MI(MI),
Kind(InvalidKind) {
UVS(MI.getDebugLoc(), LS), Kind(InvalidKind) {
static_assert((sizeof(Loc) == sizeof(uint64_t)),
"hash does not cover all members of Loc");
assert(MI.isDebugValue() && "not a DBG_VALUE");
Expand All @@ -125,6 +146,10 @@ class LiveDebugValues : public MachineFunctionPass {
return 0;
}

/// Determine whether the lexical scope of this value's debug location
/// dominates MBB.
bool dominates(MachineBasicBlock &MBB) const { return UVS.dominates(&MBB); }

void dump() const { MI.dump(); }

bool operator==(const VarLoc &Other) const {
Expand Down Expand Up @@ -201,7 +226,8 @@ class LiveDebugValues : public MachineFunctionPass {
VarLocInMBB &OutLocs, VarLocMap &VarLocIDs);

bool join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
const VarLocMap &VarLocIDs);
const VarLocMap &VarLocIDs,
SmallPtrSet<const MachineBasicBlock *, 16> &Visited);

bool ExtendRanges(MachineFunction &MF);

Expand All @@ -228,6 +254,7 @@ class LiveDebugValues : public MachineFunctionPass {
/// Calculate the liveness information for the given machine function.
bool runOnMachineFunction(MachineFunction &MF) override;
};

} // namespace

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -294,7 +321,7 @@ void LiveDebugValues::transferDebugValue(const MachineInstr &MI,
// Add the VarLoc to OpenRanges from this DBG_VALUE.
// TODO: Currently handles DBG_VALUE which has only reg as location.
if (isDbgValueDescribedByReg(MI)) {
VarLoc VL(MI);
VarLoc VL(MI, LS);
unsigned ID = VarLocIDs.insert(VL);
OpenRanges.insert(ID, VL.Var);
}
Expand Down Expand Up @@ -368,29 +395,48 @@ bool LiveDebugValues::transfer(MachineInstr &MI, OpenRangesSet &OpenRanges,
/// inserting a new DBG_VALUE instruction at the start of the @MBB - if the same
/// source variable in all the predecessors of @MBB reside in the same location.
bool LiveDebugValues::join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs,
VarLocInMBB &InLocs, const VarLocMap &VarLocIDs) {
VarLocInMBB &InLocs, const VarLocMap &VarLocIDs,
SmallPtrSet<const MachineBasicBlock *, 16> &Visited) {
DEBUG(dbgs() << "join MBB: " << MBB.getName() << "\n");
bool Changed = false;

VarLocSet InLocsT; // Temporary incoming locations.

// For all predecessors of this MBB, find the set of VarLocs that
// can be joined.
int NumVisited = 0;
for (auto p : MBB.predecessors()) {
// Ignore unvisited predecessor blocks. As we are processing
// the blocks in reverse post-order any unvisited block can
// be considered to not remove any incoming values.
if (!Visited.count(p))
continue;
auto OL = OutLocs.find(p);
// Join is null in case of empty OutLocs from any of the pred.
if (OL == OutLocs.end())
return false;

// Just copy over the Out locs to incoming locs for the first predecessor.
if (p == *MBB.pred_begin()) {
// Just copy over the Out locs to incoming locs for the first visited
// predecessor, and for all other predecessors join the Out locs.
if (!NumVisited)
InLocsT = OL->second;
continue;
}
// Join with this predecessor.
InLocsT &= OL->second;
else
InLocsT &= OL->second;
NumVisited++;
}

// Filter out DBG_VALUES that are out of scope.
VarLocSet KillSet;
for (auto ID : InLocsT)
if (!VarLocIDs[ID].dominates(MBB))
KillSet.set(ID);
InLocsT.intersectWithComplement(KillSet);

// As we are processing blocks in reverse post-order we
// should have processed at least one predecessor, unless it
// is the entry block which has no predecessor.
assert((NumVisited || MBB.pred_empty()) &&
"Should have processed at least one predecessor");
if (InLocsT.empty())
return false;

Expand Down Expand Up @@ -463,6 +509,7 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
// To solve it, we perform join() and transfer() using the two worklist method
// until the ranges converge.
// Ranges have converged when both worklists are empty.
SmallPtrSet<const MachineBasicBlock *, 16> Visited;
while (!Worklist.empty() || !Pending.empty()) {
// We track what is on the pending worklist to avoid inserting the same
// thing twice. We could avoid this with a custom priority queue, but this
Expand All @@ -471,8 +518,8 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
while (!Worklist.empty()) {
MachineBasicBlock *MBB = OrderToBB[Worklist.top()];
Worklist.pop();
MBBJoined = join(*MBB, OutLocs, InLocs, VarLocIDs);

MBBJoined = join(*MBB, OutLocs, InLocs, VarLocIDs, Visited);
Visited.insert(MBB);
if (MBBJoined) {
MBBJoined = false;
Changed = true;
Expand Down Expand Up @@ -505,12 +552,14 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
}

bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) {
if (!MF.getFunction()->getSubprogram())
// LiveDebugValues will already have removed all DBG_VALUEs.
return false;

TRI = MF.getSubtarget().getRegisterInfo();
TII = MF.getSubtarget().getInstrInfo();
LS.initialize(MF);

bool Changed = false;

Changed |= ExtendRanges(MF);

bool Changed = ExtendRanges(MF);
return Changed;
}
Loading