diff options
Diffstat (limited to 'llvm/lib/CodeGen/MachineInstr.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineInstr.cpp | 126 |
1 files changed, 94 insertions, 32 deletions
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 94afaff..c1b04d7 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -841,28 +841,35 @@ const DILabel *MachineInstr::getDebugLabel() const { } const MachineOperand &MachineInstr::getDebugVariableOp() const { - assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE"); - return getOperand(2); + assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*"); + unsigned VariableOp = isDebugValueList() ? 0 : 2; + return getOperand(VariableOp); } MachineOperand &MachineInstr::getDebugVariableOp() { - assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE"); - return getOperand(2); + assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*"); + unsigned VariableOp = isDebugValueList() ? 0 : 2; + return getOperand(VariableOp); } const DILocalVariable *MachineInstr::getDebugVariable() const { - assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE"); - return cast<DILocalVariable>(getOperand(2).getMetadata()); + return cast<DILocalVariable>(getDebugVariableOp().getMetadata()); +} + +const MachineOperand &MachineInstr::getDebugExpressionOp() const { + assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*"); + unsigned ExpressionOp = isDebugValueList() ? 1 : 3; + return getOperand(ExpressionOp); } MachineOperand &MachineInstr::getDebugExpressionOp() { - assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE"); - return getOperand(3); + assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*"); + unsigned ExpressionOp = isDebugValueList() ? 1 : 3; + return getOperand(ExpressionOp); } const DIExpression *MachineInstr::getDebugExpression() const { - assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE"); - return cast<DIExpression>(getOperand(3).getMetadata()); + return cast<DIExpression>(getDebugExpressionOp().getMetadata()); } bool MachineInstr::isDebugEntryValue() const { @@ -1712,7 +1719,7 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, OS << " "; if (isDebugValue() && MO.isMetadata()) { - // Pretty print DBG_VALUE instructions. + // Pretty print DBG_VALUE* instructions. auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata()); if (DIV && !DIV->getName().empty()) OS << "!\"" << DIV->getName() << '\"'; @@ -2116,8 +2123,8 @@ MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID, bool IsIndirect, - MachineOperand &MO, const MDNode *Variable, - const MDNode *Expr) { + const MachineOperand &MO, + const MDNode *Variable, const MDNode *Expr) { assert(isa<DILocalVariable>(Variable) && "not a variable"); assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && @@ -2131,7 +2138,28 @@ MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, else MIB.addReg(0U, RegState::Debug); return MIB.addMetadata(Variable).addMetadata(Expr); - } +} + +MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, + const MCInstrDesc &MCID, bool IsIndirect, + ArrayRef<MachineOperand> MOs, + const MDNode *Variable, const MDNode *Expr) { + assert(isa<DILocalVariable>(Variable) && "not a variable"); + assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); + assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && + "Expected inlined-at fields to agree"); + if (MCID.Opcode == TargetOpcode::DBG_VALUE) + return BuildMI(MF, DL, MCID, IsIndirect, MOs[0], Variable, Expr); + + auto MIB = BuildMI(MF, DL, MCID); + MIB.addMetadata(Variable).addMetadata(Expr); + for (const MachineOperand &MO : MOs) + if (MO.isReg()) + MIB.addReg(MO.getReg(), RegState::Debug); + else + MIB.add(MO); + return MIB; +} MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, @@ -2155,10 +2183,22 @@ MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, return MachineInstrBuilder(MF, *MI); } +MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, + MachineBasicBlock::iterator I, + const DebugLoc &DL, const MCInstrDesc &MCID, + bool IsIndirect, ArrayRef<MachineOperand> MOs, + const MDNode *Variable, const MDNode *Expr) { + MachineFunction &MF = *BB.getParent(); + MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, MOs, Variable, Expr); + BB.insert(I, MI); + return MachineInstrBuilder(MF, *MI); +} + /// Compute the new DIExpression to use with a DBG_VALUE for a spill slot. /// This prepends DW_OP_deref when spilling an indirect DBG_VALUE. -static const DIExpression *computeExprForSpill(const MachineInstr &MI) { - assert(MI.getOperand(0).isReg() && "can't spill non-register"); +static const DIExpression *computeExprForSpill(const MachineInstr &MI, + Register SpillReg) { + assert(MI.hasDebugOperandForReg(SpillReg) && "Spill Reg is not used in MI."); assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) && "Expected inlined-at fields to agree"); @@ -2167,6 +2207,14 @@ static const DIExpression *computeExprForSpill(const MachineInstr &MI) { assert(MI.getDebugOffset().getImm() == 0 && "DBG_VALUE with nonzero offset"); Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore); + } else if (MI.isDebugValueList()) { + // We will replace the spilled register with a frame index, so + // immediately deref all references to the spilled register. + std::array<uint64_t, 1> Ops{{dwarf::DW_OP_deref}}; + for (const MachineOperand &Op : MI.getDebugOperandsForReg(SpillReg)) { + unsigned OpIdx = MI.getDebugOperandIndex(&Op); + Expr = DIExpression::appendOpsToArg(Expr, Ops, OpIdx); + } } return Expr; } @@ -2174,19 +2222,32 @@ static const DIExpression *computeExprForSpill(const MachineInstr &MI) { MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB, MachineBasicBlock::iterator I, const MachineInstr &Orig, - int FrameIndex) { - const DIExpression *Expr = computeExprForSpill(Orig); - return BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc()) - .addFrameIndex(FrameIndex) - .addImm(0U) - .addMetadata(Orig.getDebugVariable()) - .addMetadata(Expr); -} - -void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex) { - const DIExpression *Expr = computeExprForSpill(Orig); - Orig.getDebugOperand(0).ChangeToFrameIndex(FrameIndex); - Orig.getDebugOffset().ChangeToImmediate(0U); + int FrameIndex, Register SpillReg) { + const DIExpression *Expr = computeExprForSpill(Orig, SpillReg); + MachineInstrBuilder NewMI = + BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc()); + // Non-Variadic Operands: Location, Offset, Variable, Expression + // Variadic Operands: Variable, Expression, Locations... + if (Orig.isNonListDebugValue()) + NewMI.addFrameIndex(FrameIndex).addImm(0U); + NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr); + if (Orig.isDebugValueList()) { + for (const MachineOperand &Op : Orig.debug_operands()) + if (Op.isReg() && Op.getReg() == SpillReg) + NewMI.addFrameIndex(FrameIndex); + else + NewMI.add(MachineOperand(Op)); + } + return NewMI; +} + +void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex, + Register Reg) { + const DIExpression *Expr = computeExprForSpill(Orig, Reg); + if (Orig.isNonListDebugValue()) + Orig.getDebugOffset().ChangeToImmediate(0U); + for (MachineOperand &Op : Orig.getDebugOperandsForReg(Reg)) + Op.ChangeToFrameIndex(FrameIndex); Orig.getDebugExpressionOp().setMetadata(Expr); } @@ -2201,7 +2262,7 @@ void MachineInstr::collectDebugValues( DI != DE; ++DI) { if (!DI->isDebugValue()) return; - if (DI->getDebugOperandForReg(MI.getOperand(0).getReg())) + if (DI->hasDebugOperandForReg(MI.getOperand(0).getReg())) DbgValues.push_back(&*DI); } } @@ -2219,14 +2280,15 @@ void MachineInstr::changeDebugValuesDefReg(Register Reg) { auto *DI = MO.getParent(); if (!DI->isDebugValue()) continue; - if (DI->getDebugOperandForReg(DefReg)) { + if (DI->hasDebugOperandForReg(DefReg)) { DbgValues.push_back(DI); } } // Propagate Reg to debug value instructions. for (auto *DBI : DbgValues) - DBI->getDebugOperandForReg(DefReg)->setReg(Reg); + for (MachineOperand &Op : DBI->getDebugOperandsForReg(DefReg)) + Op.setReg(Reg); } using MMOList = SmallVector<const MachineMemOperand *, 2>; |