diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -1191,23 +1191,29 @@ auto MakeUndefDbgValue = [&](MachineInstr &MI) { const MCInstrDesc &RefII = TII->get(TargetOpcode::DBG_VALUE_LIST); MI.setDesc(RefII); - MI.getDebugOperand(0).setReg(0); + MI.setDebugValueUndef(); }; DenseMap ArgDbgPHIs; for (auto &MBB : *this) { for (auto &MI : MBB) { - if (!MI.isDebugRef() || !MI.getDebugOperand(0).isReg()) + if (!MI.isDebugRef()) continue; - Register Reg = MI.getDebugOperand(0).getReg(); + bool IsValidRef = true; + + for (MachineOperand &MO : MI.debug_operands()) { + if (!MO.isReg()) + continue; + + Register Reg = MO.getReg(); // Some vregs can be deleted as redundant in the meantime. Mark those // as DBG_VALUE $noreg. Additionally, some normal instructions are // quickly deleted, leaving dangling references to vregs with no def. if (Reg == 0 || !RegInfo->hasOneDef(Reg)) { - MakeUndefDbgValue(MI); - continue; + IsValidRef = false; + break; } assert(Reg.isVirtual()); @@ -1218,12 +1224,12 @@ // for why this is important. if (DefMI.isCopyLike() || TII->isCopyInstr(DefMI)) { auto Result = salvageCopySSA(DefMI, ArgDbgPHIs); - MI.getDebugOperand(0).ChangeToDbgInstrRef(Result.first, Result.second); + MO.ChangeToDbgInstrRef(Result.first, Result.second); } else { // Otherwise, identify the operand number that the VReg refers to. unsigned OperandIdx = 0; - for (const auto &MO : DefMI.operands()) { - if (MO.isReg() && MO.isDef() && MO.getReg() == Reg) + for (const auto &DefMO : DefMI.operands()) { + if (DefMO.isReg() && DefMO.isDef() && DefMO.getReg() == Reg) break; ++OperandIdx; } @@ -1231,8 +1237,12 @@ // Morph this instr ref to point at the given instruction and operand. unsigned ID = DefMI.getDebugInstrNum(); - MI.getDebugOperand(0).ChangeToDbgInstrRef(ID, OperandIdx); + MO.ChangeToDbgInstrRef(ID, OperandIdx); + } } + + if (!IsValidRef) + MakeUndefDbgValue(MI); } } } diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1262,8 +1262,9 @@ // If using instruction referencing, produce this as a DBG_INSTR_REF, // to be later patched up by finalizeDebugInstrRefs. Tack a deref onto // the expression, we don't have an "indirect" flag in DBG_INSTR_REF. - auto *NewExpr = - DIExpression::prepend(DI->getExpression(), DIExpression::DerefBefore); + SmallVector Ops( + {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_deref}); + auto *NewExpr = DIExpression::prependOpcodes(DI->getExpression(), Ops); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD.getDL(), TII.get(TargetOpcode::DBG_INSTR_REF), /*IsIndirect*/ false, *Op, DI->getVariable(), NewExpr); @@ -1325,9 +1326,11 @@ /* isKill */ false, /* isDead */ false, /* isUndef */ false, /* isEarlyClobber */ false, /* SubReg */ 0, /* isDebug */ true)}); + SmallVector Ops({dwarf::DW_OP_LLVM_arg, 0}); + auto *NewExpr = DIExpression::prependOpcodes(DI->getExpression(), Ops); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD.getDL(), TII.get(TargetOpcode::DBG_INSTR_REF), /*IsIndirect*/ false, MOs, - DI->getVariable(), DI->getExpression()); + DI->getVariable(), NewExpr); } } else { // We don't know how to handle other cases, so we drop. diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h @@ -128,6 +128,10 @@ /// Emit a DBG_VALUE $noreg, indicating a variable has no location. MachineInstr *EmitDbgNoLocation(SDDbgValue *SD); + /// Emit a DBG_VALUE_LIST from the operands to SDDbgValue. + MachineInstr *EmitDbgValueList(SDDbgValue *SD, + DenseMap &VRBaseMap); + /// Emit a DBG_VALUE from the operands to SDDbgValue. MachineInstr *EmitDbgValueFromSingleOp(SDDbgValue *SD, DenseMap &VRBaseMap); diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -679,7 +679,6 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD, DenseMap &VRBaseMap) { MDNode *Var = SD->getVariable(); - MDNode *Expr = SD->getExpression(); DebugLoc DL = SD->getDebugLoc(); assert(cast(Var)->isValidLocationForIntrinsic(DL) && "Expected inlined-at fields to agree"); @@ -692,26 +691,15 @@ if (SD->isInvalidated()) return EmitDbgNoLocation(SD); - // Emit variadic dbg_value nodes as DBG_VALUE_LIST. - if (SD->isVariadic()) { - // DBG_VALUE_LIST := "DBG_VALUE_LIST" var, expression, loc (, loc)* - const MCInstrDesc &DbgValDesc = TII->get(TargetOpcode::DBG_VALUE_LIST); - // Build the DBG_VALUE_LIST instruction base. - auto MIB = BuildMI(*MF, DL, DbgValDesc); - MIB.addMetadata(Var); - MIB.addMetadata(Expr); - AddDbgValueLocationOps(MIB, DbgValDesc, LocationOps, VRBaseMap); - return &*MIB; - } - // Attempt to produce a DBG_INSTR_REF if we've been asked to. - // We currently exclude the possibility of instruction references for - // variadic nodes; if at some point we enable them, this should be moved - // above the variadic block. if (EmitDebugInstrRefs) if (auto *InstrRef = EmitDbgInstrRef(SD, VRBaseMap)) return InstrRef; + // Emit variadic dbg_value nodes as DBG_VALUE_LIST. + if (SD->isVariadic()) + return EmitDbgValueList(SD, VRBaseMap); + return EmitDbgValueFromSingleOp(SD, VRBaseMap); } @@ -765,18 +753,30 @@ MachineInstr * InstrEmitter::EmitDbgInstrRef(SDDbgValue *SD, DenseMap &VRBaseMap) { - assert(!SD->isVariadic()); - SDDbgOperand DbgOperand = SD->getLocationOps()[0]; MDNode *Var = SD->getVariable(); DIExpression *Expr = (DIExpression*)SD->getExpression(); DebugLoc DL = SD->getDebugLoc(); const MCInstrDesc &RefII = TII->get(TargetOpcode::DBG_INSTR_REF); - // Handle variable locations that don't actually depend on the instructions - // in the program: constants and stack locations. - if (DbgOperand.getKind() == SDDbgOperand::FRAMEIX || - DbgOperand.getKind() == SDDbgOperand::CONST) + // Returns true if the given operand is not a legal debug operand for a + // DBG_INSTR_REF. + auto IsInvalidOp = [](SDDbgOperand DbgOp) { + return DbgOp.getKind() == SDDbgOperand::FRAMEIX; + }; + // Returns true if the given operand is not itself an instruction reference + // but is a legal debug operand for a DBG_INSTR_REF. + auto IsNonInstrRefOp = [](SDDbgOperand DbgOp) { + return DbgOp.getKind() == SDDbgOperand::CONST; + }; + + // If this variable location does not depend on any instructions or contains + // any stack locations, produce it as a standard debug value instead. + if (any_of(SD->getLocationOps(), IsInvalidOp) || + all_of(SD->getLocationOps(), IsNonInstrRefOp)) { + if (SD->isVariadic()) + return EmitDbgValueList(SD, VRBaseMap); return EmitDbgValueFromSingleOp(SD, VRBaseMap); + } // Immediately fold any indirectness from the LLVM-IR intrinsic into the // expression: @@ -784,24 +784,34 @@ std::vector Elts = {dwarf::DW_OP_deref}; Expr = DIExpression::append(Expr, Elts); } + // If this is not already a variadic expression, it must be modified to become + // one. + if (!SD->isVariadic()) { + SmallVector Elts = {dwarf::DW_OP_LLVM_arg, 0}; + Expr = DIExpression::prependOpcodes(Expr, Elts); + } + + SmallVector MOs; // It may not be immediately possible to identify the MachineInstr that // defines a VReg, it can depend for example on the order blocks are // emitted in. When this happens, or when further analysis is needed later, // produce an instruction like this: // - // DBG_INSTR_REF %0:gr64, 0, !123, !456 + // DBG_INSTR_REF !123, !456, %0:gr64 // // i.e., point the instruction at the vreg, and patch it up later in // MachineFunction::finalizeDebugInstrRefs. - auto EmitHalfDoneInstrRef = [&](unsigned VReg) -> MachineInstr * { - SmallVector MOs({MachineOperand::CreateReg( + auto AddVRegOp = [&](unsigned VReg) { + MOs.push_back(MachineOperand::CreateReg( /* Reg */ VReg, /* isDef */ false, /* isImp */ false, /* isKill */ false, /* isDead */ false, /* isUndef */ false, /* isEarlyClobber */ false, - /* SubReg */ 0, /* isDebug */ true)}); - return BuildMI(*MF, DL, RefII, false, MOs, Var, Expr); + /* SubReg */ 0, /* isDebug */ true)); }; + unsigned OpCount = SD->getLocationOps().size(); + for (unsigned OpIdx = 0; OpIdx < OpCount; ++OpIdx) { + SDDbgOperand DbgOperand = SD->getLocationOps()[OpIdx]; // Try to find both the defined register and the instruction defining it. MachineInstr *DefMI = nullptr; @@ -812,36 +822,65 @@ // No definition means that block hasn't been emitted yet. Leave a vreg // reference to be fixed later. - if (!MRI->hasOneDef(VReg)) - return EmitHalfDoneInstrRef(VReg); + if (!MRI->hasOneDef(VReg)) { + AddVRegOp(VReg); + continue; + } DefMI = &*MRI->def_instr_begin(VReg); - } else { - assert(DbgOperand.getKind() == SDDbgOperand::SDNODE); + } else if (DbgOperand.getKind() == SDDbgOperand::SDNODE) { // Look up the corresponding VReg for the given SDNode, if any. SDNode *Node = DbgOperand.getSDNode(); SDValue Op = SDValue(Node, DbgOperand.getResNo()); DenseMap::iterator I = VRBaseMap.find(Op); // No VReg -> produce a DBG_VALUE $noreg instead. if (I == VRBaseMap.end()) - return EmitDbgNoLocation(SD); + break; // Try to pick out a defining instruction at this point. VReg = getVR(Op, VRBaseMap); // Again, if there's no instruction defining the VReg right now, fix it up // later. - if (!MRI->hasOneDef(VReg)) - return EmitHalfDoneInstrRef(VReg); + if (!MRI->hasOneDef(VReg)) { + AddVRegOp(VReg); + continue; + } DefMI = &*MRI->def_instr_begin(VReg); + } else if (DbgOperand.getKind() == SDDbgOperand::FRAMEIX) { + MOs.push_back(MachineOperand::CreateFI(DbgOperand.getFrameIx())); + continue; + } else { + assert(DbgOperand.getKind() == SDDbgOperand::CONST); + // TODO: Probably extract this out into a function shared with + // AddDbgValueLocationOps. + const Value *V = DbgOperand.getConst(); + if (const ConstantInt *CI = dyn_cast(V)) { + if (CI->getBitWidth() > 64) + MOs.push_back(MachineOperand::CreateCImm(CI)); + else + MOs.push_back(MachineOperand::CreateImm(CI->getSExtValue())); + } else if (const ConstantFP *CF = dyn_cast(V)) { + MOs.push_back(MachineOperand::CreateFPImm(CF)); + } else if (isa(V)) { + // Note: This assumes that all nullptr constants are zero-valued. + MOs.push_back(MachineOperand::CreateImm(0)); + } else { + // Could be an Undef. In any case insert an Undef so we can see what we + // dropped. + AddVRegOp(0U); + } + continue; } // Avoid copy like instructions: they don't define values, only move them. - // Leave a virtual-register reference until it can be fixed up later, to find - // the underlying value definition. - if (DefMI->isCopyLike() || TII->isCopyInstr(*DefMI)) - return EmitHalfDoneInstrRef(VReg); + // Leave a virtual-register reference until it can be fixed up later, to + // find the underlying value definition. + if (DefMI->isCopyLike() || TII->isCopyInstr(*DefMI)) { + AddVRegOp(VReg); + continue; + } // Find the operand number which defines the specified VReg. unsigned OperandIdx = 0; @@ -854,8 +893,14 @@ // Make the DBG_INSTR_REF refer to that instruction, and that operand. unsigned InstrNum = DefMI->getDebugInstrNum(); - SmallVector MOs( - {MachineOperand::CreateDbgInstrRef(InstrNum, OperandIdx)}); + MOs.push_back(MachineOperand::CreateDbgInstrRef(InstrNum, OperandIdx)); + } + + // If we haven't created a valid MachineOperand for every DbgOp, abort and + // produce an undef DBG_VALUE. + if (MOs.size() != OpCount) + return EmitDbgNoLocation(SD); + return BuildMI(*MF, DL, RefII, false, MOs, Var, Expr); } @@ -874,6 +919,22 @@ return &*MIB; } +MachineInstr * +InstrEmitter::EmitDbgValueList(SDDbgValue *SD, + DenseMap &VRBaseMap) { + MDNode *Var = SD->getVariable(); + DIExpression *Expr = SD->getExpression(); + DebugLoc DL = SD->getDebugLoc(); + // DBG_VALUE_LIST := "DBG_VALUE_LIST" var, expression, loc (, loc)* + const MCInstrDesc &DbgValDesc = TII->get(TargetOpcode::DBG_VALUE_LIST); + // Build the DBG_VALUE_LIST instruction base. + auto MIB = BuildMI(*MF, DL, DbgValDesc); + MIB.addMetadata(Var); + MIB.addMetadata(Expr); + AddDbgValueLocationOps(MIB, DbgValDesc, SD->getLocationOps(), VRBaseMap); + return &*MIB; +} + MachineInstr * InstrEmitter::EmitDbgValueFromSingleOp(SDDbgValue *SD, DenseMap &VRBaseMap) { diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5563,6 +5563,8 @@ // the DIExpression. if (Indirect) NewDIExpr = DIExpression::prepend(FragExpr, DIExpression::DerefBefore); + SmallVector Ops({dwarf::DW_OP_LLVM_arg, 0}); + NewDIExpr = DIExpression::prependOpcodes(NewDIExpr, Ops); return BuildMI(MF, DL, Inst, false, MOs, Variable, NewDIExpr); } else { // Create a completely standard DBG_VALUE.