diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/CodeGenCommonISel.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/CodeGenCommonISel.cpp | 92 |
1 files changed, 90 insertions, 2 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/CodeGenCommonISel.cpp b/contrib/llvm-project/llvm/lib/CodeGen/CodeGenCommonISel.cpp index 8f185a161bd0..a5215969c0dd 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/CodeGenCommonISel.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/CodeGenCommonISel.cpp @@ -17,6 +17,9 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetOpcodes.h" +#include "llvm/IR/DebugInfoMetadata.h" + +#define DEBUG_TYPE "codegen-common" using namespace llvm; @@ -100,8 +103,8 @@ static bool MIIsInTerminatorSequence(const MachineInstr &MI) { // Make sure that the copy dest is not a vreg when the copy source is a // physical register. - if (!OPI2->isReg() || (!Register::isPhysicalRegister(OPI->getReg()) && - Register::isPhysicalRegister(OPI2->getReg()))) + if (!OPI2->isReg() || + (!OPI->getReg().isPhysical() && OPI2->getReg().isPhysical())) return false; return true; @@ -197,3 +200,88 @@ unsigned llvm::getInvertedFPClassTest(unsigned Test) { } return 0; } + +static MachineOperand *getSalvageOpsForCopy(const MachineRegisterInfo &MRI, + MachineInstr &Copy) { + assert(Copy.getOpcode() == TargetOpcode::COPY && "Must be a COPY"); + + return &Copy.getOperand(1); +} + +static MachineOperand *getSalvageOpsForTrunc(const MachineRegisterInfo &MRI, + MachineInstr &Trunc, + SmallVectorImpl<uint64_t> &Ops) { + assert(Trunc.getOpcode() == TargetOpcode::G_TRUNC && "Must be a G_TRUNC"); + + const auto FromLLT = MRI.getType(Trunc.getOperand(1).getReg()); + const auto ToLLT = MRI.getType(Trunc.defs().begin()->getReg()); + + // TODO: Support non-scalar types. + if (!FromLLT.isScalar()) { + return nullptr; + } + + auto ExtOps = DIExpression::getExtOps(FromLLT.getSizeInBits(), + ToLLT.getSizeInBits(), false); + Ops.append(ExtOps.begin(), ExtOps.end()); + return &Trunc.getOperand(1); +} + +static MachineOperand *salvageDebugInfoImpl(const MachineRegisterInfo &MRI, + MachineInstr &MI, + SmallVectorImpl<uint64_t> &Ops) { + switch (MI.getOpcode()) { + case TargetOpcode::G_TRUNC: + return getSalvageOpsForTrunc(MRI, MI, Ops); + case TargetOpcode::COPY: + return getSalvageOpsForCopy(MRI, MI); + default: + return nullptr; + } +} + +void llvm::salvageDebugInfoForDbgValue(const MachineRegisterInfo &MRI, + MachineInstr &MI, + ArrayRef<MachineOperand *> DbgUsers) { + // These are arbitrary chosen limits on the maximum number of values and the + // maximum size of a debug expression we can salvage up to, used for + // performance reasons. + const unsigned MaxExpressionSize = 128; + + for (auto *DefMO : DbgUsers) { + MachineInstr *DbgMI = DefMO->getParent(); + if (DbgMI->isIndirectDebugValue()) { + continue; + } + + int UseMOIdx = DbgMI->findRegisterUseOperandIdx(DefMO->getReg()); + assert(UseMOIdx != -1 && DbgMI->hasDebugOperandForReg(DefMO->getReg()) && + "Must use salvaged instruction as its location"); + + // TODO: Support DBG_VALUE_LIST. + if (DbgMI->getOpcode() != TargetOpcode::DBG_VALUE) { + assert(DbgMI->getOpcode() == TargetOpcode::DBG_VALUE_LIST && + "Must be either DBG_VALUE or DBG_VALUE_LIST"); + continue; + } + + const DIExpression *SalvagedExpr = DbgMI->getDebugExpression(); + + SmallVector<uint64_t, 16> Ops; + auto Op0 = salvageDebugInfoImpl(MRI, MI, Ops); + if (!Op0) + continue; + SalvagedExpr = DIExpression::appendOpsToArg(SalvagedExpr, Ops, 0, true); + + bool IsValidSalvageExpr = + SalvagedExpr->getNumElements() <= MaxExpressionSize; + if (IsValidSalvageExpr) { + auto &UseMO = DbgMI->getOperand(UseMOIdx); + UseMO.setReg(Op0->getReg()); + UseMO.setSubReg(Op0->getSubReg()); + DbgMI->getDebugExpressionOp().setMetadata(SalvagedExpr); + + LLVM_DEBUG(dbgs() << "SALVAGE: " << *DbgMI << '\n'); + } + } +} |