aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/TargetRegisterInfo.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
commitb60736ec1405bb0a8dd40989f67ef4c93da068ab (patch)
tree5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /llvm/lib/CodeGen/TargetRegisterInfo.cpp
parentcfca06d7963fa0909f90483b42a6d7d194d01e08 (diff)
Diffstat (limited to 'llvm/lib/CodeGen/TargetRegisterInfo.cpp')
-rw-r--r--llvm/lib/CodeGen/TargetRegisterInfo.cpp53
1 files changed, 52 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
index e2ef12d8ac77..5fd7eef5808f 100644
--- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
@@ -26,6 +26,7 @@
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Attributes.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
@@ -68,7 +69,7 @@ bool TargetRegisterInfo::shouldRegionSplitForVirtReg(
const MachineFunction &MF, const LiveInterval &VirtReg) const {
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
const MachineRegisterInfo &MRI = MF.getRegInfo();
- MachineInstr *MI = MRI.getUniqueVRegDef(VirtReg.reg);
+ MachineInstr *MI = MRI.getUniqueVRegDef(VirtReg.reg());
if (MI && TII->isTriviallyReMaterializable(*MI) &&
VirtReg.size() > HugeSizeForSplit)
return false;
@@ -532,6 +533,56 @@ TargetRegisterInfo::lookThruCopyLike(Register SrcReg,
}
}
+Register TargetRegisterInfo::lookThruSingleUseCopyChain(
+ Register SrcReg, const MachineRegisterInfo *MRI) const {
+ while (true) {
+ const MachineInstr *MI = MRI->getVRegDef(SrcReg);
+ // Found the real definition, return it if it has a single use.
+ if (!MI->isCopyLike())
+ return MRI->hasOneNonDBGUse(SrcReg) ? SrcReg : Register();
+
+ Register CopySrcReg;
+ if (MI->isCopy())
+ CopySrcReg = MI->getOperand(1).getReg();
+ else {
+ assert(MI->isSubregToReg() && "Bad opcode for lookThruCopyLike");
+ CopySrcReg = MI->getOperand(2).getReg();
+ }
+
+ // Continue only if the next definition in the chain is for a virtual
+ // register that has a single use.
+ if (!CopySrcReg.isVirtual() || !MRI->hasOneNonDBGUse(CopySrcReg))
+ return Register();
+
+ SrcReg = CopySrcReg;
+ }
+}
+
+void TargetRegisterInfo::getOffsetOpcodes(
+ const StackOffset &Offset, SmallVectorImpl<uint64_t> &Ops) const {
+ assert(!Offset.getScalable() && "Scalable offsets are not handled");
+ DIExpression::appendOffset(Ops, Offset.getFixed());
+}
+
+DIExpression *
+TargetRegisterInfo::prependOffsetExpression(const DIExpression *Expr,
+ unsigned PrependFlags,
+ const StackOffset &Offset) const {
+ assert((PrependFlags &
+ ~(DIExpression::DerefBefore | DIExpression::DerefAfter |
+ DIExpression::StackValue | DIExpression::EntryValue)) == 0 &&
+ "Unsupported prepend flag");
+ SmallVector<uint64_t, 16> OffsetExpr;
+ if (PrependFlags & DIExpression::DerefBefore)
+ OffsetExpr.push_back(dwarf::DW_OP_deref);
+ getOffsetOpcodes(Offset, OffsetExpr);
+ if (PrependFlags & DIExpression::DerefAfter)
+ OffsetExpr.push_back(dwarf::DW_OP_deref);
+ return DIExpression::prependOpcodes(Expr, OffsetExpr,
+ PrependFlags & DIExpression::StackValue,
+ PrependFlags & DIExpression::EntryValue);
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD
void TargetRegisterInfo::dumpReg(Register Reg, unsigned SubRegIndex,