aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/CodeGenCommonISel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/CodeGenCommonISel.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/CodeGenCommonISel.cpp92
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');
+ }
+ }
+}