Optional<DbgVariableLocation> DbgVariableLocation::extractFromMachineInstruction( const MachineInstr &Instruction) { DbgVariableLocation Location; if (!Instruction.isDebugValue()) return None; if (!Instruction.getOperand(0).isReg()) return None; Location.Register = Instruction.getOperand(0).getReg(); Location.FragmentInfo.reset(); // We only handle expressions generated by DIExpression::appendOffset, // which doesn't require a full stack machine. int64_t Offset = 0; const DIExpression *DIExpr = Instruction.getDebugExpression(); auto Op = DIExpr->expr_op_begin(); while (Op != DIExpr->expr_op_end()) { switch (Op->getOp()) { case dwarf::DW_OP_constu: { int Value = Op->getArg(0); ++Op; if (Op != DIExpr->expr_op_end()) { switch (Op->getOp()) { case dwarf::DW_OP_minus: Offset -= Value; break; case dwarf::DW_OP_plus: Offset += Value; break; default: continue; } } } break; case dwarf::DW_OP_plus_uconst: Offset += Op->getArg(0); break; case dwarf::DW_OP_LLVM_fragment: Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)}; break; case dwarf::DW_OP_deref: Location.LoadChain.push_back(Offset); Offset = 0; break; default: return None; } ++Op; } // Do one final implicit DW_OP_deref if this was an indirect DBG_VALUE // instruction. // FIXME: Replace these with DIExpression. if (Instruction.isIndirectDebugValue()) Location.LoadChain.push_back(Offset); return Location; }
/// spillVirtReg - Do the actual work of spilling. void RAFast::spillVirtReg(MachineBasicBlock::iterator MI, LiveRegMap::iterator LRI) { LiveReg &LR = *LRI; assert(PhysRegState[LR.PhysReg] == LRI->VirtReg && "Broken RegState mapping"); if (LR.Dirty) { // If this physreg is used by the instruction, we want to kill it on the // instruction, not on the spill. bool SpillKill = LR.LastUse != MI; LR.Dirty = false; DEBUG(dbgs() << "Spilling " << PrintReg(LRI->VirtReg, TRI) << " in " << PrintReg(LR.PhysReg, TRI)); const TargetRegisterClass *RC = MRI->getRegClass(LRI->VirtReg); int FI = getStackSpaceFor(LRI->VirtReg, RC); DEBUG(dbgs() << " to stack slot #" << FI << "\n"); TII->storeRegToStackSlot(*MBB, MI, LR.PhysReg, SpillKill, FI, RC, TRI); ++NumStores; // Update statistics // If this register is used by DBG_VALUE then insert new DBG_VALUE to // identify spilled location as the place to find corresponding variable's // value. SmallVectorImpl<MachineInstr *> &LRIDbgValues = LiveDbgValueMap[LRI->VirtReg]; for (unsigned li = 0, le = LRIDbgValues.size(); li != le; ++li) { MachineInstr *DBG = LRIDbgValues[li]; const MDNode *Var = DBG->getDebugVariable(); const MDNode *Expr = DBG->getDebugExpression(); bool IsIndirect = DBG->isIndirectDebugValue(); uint64_t Offset = IsIndirect ? DBG->getOperand(1).getImm() : 0; DebugLoc DL = DBG->getDebugLoc(); assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) && "Expected inlined-at fields to agree"); MachineInstr *NewDV = BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::DBG_VALUE)) .addFrameIndex(FI) .addImm(Offset) .addMetadata(Var) .addMetadata(Expr); assert(NewDV->getParent() == MBB && "dangling parent pointer"); (void)NewDV; DEBUG(dbgs() << "Inserting debug info due to spill:" << "\n" << *NewDV); } // Now this register is spilled there is should not be any DBG_VALUE // pointing to this register because they are all pointing to spilled value // now. LRIDbgValues.clear(); if (SpillKill) LR.LastUse = nullptr; // Don't kill register again } killVirtReg(LRI); }
bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) { // DBG_VALUE loc, offset, variable if (MI.getNumOperands() != 4 || !(MI.getOperand(1).isReg() || MI.getOperand(1).isImm()) || !MI.getOperand(2).isMetadata()) { DEBUG(dbgs() << "Can't handle " << MI); return false; } // Get or create the UserValue for (variable,offset). bool IsIndirect = MI.isIndirectDebugValue(); unsigned Offset = IsIndirect ? MI.getOperand(1).getImm() : 0; const MDNode *Var = MI.getDebugVariable(); const MDNode *Expr = MI.getDebugExpression(); //here. UserValue *UV = getUserValue(Var, Expr, Offset, IsIndirect, MI.getDebugLoc()); UV->addDef(Idx, MI.getOperand(0)); return true; }
/// spillAroundUses - insert spill code around each use of Reg. void InlineSpiller::spillAroundUses(unsigned Reg) { DEBUG(dbgs() << "spillAroundUses " << PrintReg(Reg) << '\n'); LiveInterval &OldLI = LIS.getInterval(Reg); // Iterate over instructions using Reg. for (MachineRegisterInfo::reg_bundle_iterator RegI = MRI.reg_bundle_begin(Reg), E = MRI.reg_bundle_end(); RegI != E; ) { MachineInstr *MI = &*(RegI++); // Debug values are not allowed to affect codegen. if (MI->isDebugValue()) { // Modify DBG_VALUE now that the value is in a spill slot. bool IsIndirect = MI->isIndirectDebugValue(); uint64_t Offset = IsIndirect ? MI->getOperand(1).getImm() : 0; const MDNode *Var = MI->getDebugVariable(); const MDNode *Expr = MI->getDebugExpression(); DebugLoc DL = MI->getDebugLoc(); DEBUG(dbgs() << "Modifying debug info due to spill:" << "\t" << *MI); MachineBasicBlock *MBB = MI->getParent(); BuildMI(*MBB, MBB->erase(MI), DL, TII.get(TargetOpcode::DBG_VALUE)) .addFrameIndex(StackSlot) .addImm(Offset) .addMetadata(Var) .addMetadata(Expr); continue; } // Ignore copies to/from snippets. We'll delete them. if (SnippetCopies.count(MI)) continue; // Stack slot accesses may coalesce away. if (coalesceStackAccess(MI, Reg)) continue; // Analyze instruction. SmallVector<std::pair<MachineInstr*, unsigned>, 8> Ops; MIBundleOperands::VirtRegInfo RI = MIBundleOperands(MI).analyzeVirtReg(Reg, &Ops); // Find the slot index where this instruction reads and writes OldLI. // This is usually the def slot, except for tied early clobbers. SlotIndex Idx = LIS.getInstructionIndex(MI).getRegSlot(); if (VNInfo *VNI = OldLI.getVNInfoAt(Idx.getRegSlot(true))) if (SlotIndex::isSameInstr(Idx, VNI->def)) Idx = VNI->def; // Check for a sibling copy. unsigned SibReg = isFullCopyOf(MI, Reg); if (SibReg && isSibling(SibReg)) { // This may actually be a copy between snippets. if (isRegToSpill(SibReg)) { DEBUG(dbgs() << "Found new snippet copy: " << *MI); SnippetCopies.insert(MI); continue; } if (RI.Writes) { // Hoist the spill of a sib-reg copy. if (hoistSpill(OldLI, MI)) { // This COPY is now dead, the value is already in the stack slot. MI->getOperand(0).setIsDead(); DeadDefs.push_back(MI); continue; } } else { // This is a reload for a sib-reg copy. Drop spills downstream. LiveInterval &SibLI = LIS.getInterval(SibReg); eliminateRedundantSpills(SibLI, SibLI.getVNInfoAt(Idx)); // The COPY will fold to a reload below. } } // Attempt to fold memory ops. if (foldMemoryOperand(Ops)) continue; // Create a new virtual register for spill/fill. // FIXME: Infer regclass from instruction alone. unsigned NewVReg = Edit->createFrom(Reg); if (RI.Reads) insertReload(NewVReg, Idx, MI); // Rewrite instruction operands. bool hasLiveDef = false; for (unsigned i = 0, e = Ops.size(); i != e; ++i) { MachineOperand &MO = Ops[i].first->getOperand(Ops[i].second); MO.setReg(NewVReg); if (MO.isUse()) { if (!Ops[i].first->isRegTiedToDefOperand(Ops[i].second)) MO.setIsKill(); } else { if (!MO.isDead()) hasLiveDef = true; } } DEBUG(dbgs() << "\trewrite: " << Idx << '\t' << *MI << '\n'); // FIXME: Use a second vreg if instruction has no tied ops. if (RI.Writes) if (hasLiveDef) insertSpill(NewVReg, true, MI); } }