27 if (!Def->getMF()->getFunction().getSubprogram())
33 if (!Def->getOperand(0).isReg())
35 CurrentReg = Def->getOperand(0).getReg();
40 unsigned RemainingUses = 0;
42 if (
MI.isDebugValue() &&
MI.getParent() ==
MBB)
44 if (RemainingUses == 0)
52 DownEnd =
MBB->end(), Up = Def->getIterator(),
53 UpBegin =
MBB->begin();
54 while (RemainingUses > 0 && Down != DownEnd) {
55 if (Down->isDebugValue()) {
56 if (Down->hasDebugOperandForReg(CurrentReg)) {
57 DbgValues.push_back(&*Down);
60 }
else if (Down->definesRegister(CurrentReg,
nullptr)) {
66 if (Up->isDebugValue() && Up->hasDebugOperandForReg(CurrentReg))
75 if (
A->getOpcode() !=
B->getOpcode() ||
80 if ((OpA.
isImm() && OpB.isImm() && OpA.
getImm() == OpB.getImm()) ||
88WebAssemblyDebugValueManager::getSinkableDebugValues(
90 if (DbgValues.empty())
95 if (Def->getParent() !=
Insert->getParent() &&
96 !Def->getParent()->isSuccessor(
Insert->getParent()))
99 SmallDenseSet<DebugVariable, 4> OurVars;
100 for (MachineInstr *DV : DbgValues)
101 OurVars.
insert(DebugVariable(DV->getDebugVariable(),
102 DV->getDebugExpression(),
103 DV->getDebugLoc()->getInlinedAt()));
105 SmallDenseMap<DebugVariable, SmallVector<MachineInstr *, 2>>
106 SeenDbgVarToDbgValues;
107 auto RecordDbgValue = [&](MachineInstr &
MI) {
108 if (!
MI.isDebugValue())
110 DebugVariable Var(
MI.getDebugVariable(),
MI.getDebugExpression(),
111 MI.getDebugLoc()->getInlinedAt());
113 SeenDbgVarToDbgValues[Var].push_back(&
MI);
116 if (Def->getParent() ==
Insert->getParent()) {
120 DownEnd = Def->getParent()->end(),
121 Up = Def->getIterator(),
122 UpBegin = Def->getParent()->begin();
123 bool DefFirst =
false;
124 while (Down != DownEnd || Up != UpBegin) {
125 if (Down != DownEnd) {
126 if (&*Down == Insert) {
130 RecordDbgValue(*Down);
146 ME = Def->getParent()->end();
150 ME =
Insert->getIterator();
165 MachineRegisterInfo &MRI = Def->getParent()->getParent()->getRegInfo();
166 for (
auto *DV : DbgValues) {
167 DebugVariable Var(DV->getDebugVariable(), DV->getDebugExpression(),
168 DV->getDebugLoc()->getInlinedAt());
169 auto It = SeenDbgVarToDbgValues.
find(Var);
170 if (It == SeenDbgVarToDbgValues.
end()) {
176 auto &OverlappingDbgValues = It->second;
177 bool Sinkable =
true;
178 for (
auto *OverlappingDV : OverlappingDbgValues) {
179 MachineOperand &DbgOp = OverlappingDV->getDebugOperand(0);
180 if (!DbgOp.
isReg()) {
249 return SinkableDbgValues;
254bool WebAssemblyDebugValueManager::isInsertSamePlace(
256 if (Def->getParent() !=
Insert->getParent())
271 for (
const auto &
MI : *
MBB)
272 if (
MI.getDebugLoc() ==
DL)
302 if (isInsertSamePlace(Insert))
311 getSinkableDebugValues(Insert);
320 MBB->splice(Insert, Def->getParent(), Def);
322 if (DbgValues.empty())
329 MBB->insert(Insert, Clone);
373 DV->setDebugValueUndef();
375 DbgValues.
swap(NewDbgValues);
390 bool CloneDef)
const {
395 getSinkableDebugValues(Insert);
405 if (NewReg != CurrentReg && NewReg.
isValid())
407 MBB->insert(Insert, Clone);
410 if (DbgValues.empty())
417 MBB->insert(Insert, Clone);
421 if (NewReg != CurrentReg && NewReg.
isValid())
422 for (
auto *DBI : NewDbgValues)
423 for (
auto &MO : DBI->getDebugOperandsForReg(CurrentReg))
429 if (Reg != CurrentReg && Reg.isValid()) {
430 for (
auto *DBI : DbgValues)
431 for (
auto &MO : DBI->getDebugOperandsForReg(CurrentReg))
434 Def->getOperand(0).setReg(Reg);
439 for (
auto *DBI : DbgValues) {
440 auto IndexType = DBI->isIndirectDebugValue()
443 for (
auto &MO : DBI->getDebugOperandsForReg(CurrentReg))
444 MO.ChangeToTargetIndex(IndexType, LocalId);
450 Def->removeFromParent();
452 DV->setDebugValueUndef();
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseSet and SmallDenseSet classes.
Promote Memory to Register
static bool isSameScalarConst(const MachineInstr *A, const MachineInstr *B)
static bool hasSameDebugLoc(const MachineBasicBlock *MBB, DebugLoc DL)
This file contains the declaration of the WebAssembly-specific manager for DebugValues associated wit...
This file provides WebAssembly-specific target descriptions.
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.
iterator find(const_arg_type_t< KeyT > Val)
MachineInstrBundleIterator< MachineInstr > iterator
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
const MachineOperand & getOperand(unsigned i) const
void setDebugLoc(DebugLoc DL)
Replace current source information with new such.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
const ConstantFP * getFPImm() const
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const MachineFunction & getMF() const
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
void swap(SmallVectorImpl &RHS)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
WebAssemblyDebugValueManager(MachineInstr *Def)
void updateReg(Register Reg)
void cloneSink(MachineInstr *Insert, Register NewReg=Register(), bool CloneDef=true) const
void replaceWithLocal(unsigned LocalId)
void sink(MachineInstr *Insert)
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
bool isScalarConst(unsigned Opc)
This is an optimization pass for GlobalISel generic memory operations.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.