diff options
Diffstat (limited to 'llvm/lib/CodeGen/TargetInstrInfo.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetInstrInfo.cpp | 80 |
1 files changed, 62 insertions, 18 deletions
diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp index 6cae3b869501..a98c627dab09 100644 --- a/llvm/lib/CodeGen/TargetInstrInfo.cpp +++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp @@ -15,6 +15,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/MachineScheduler.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/CodeGen/ScoreboardHazardRecognizer.h" #include "llvm/CodeGen/StackMaps.h" @@ -1015,19 +1016,16 @@ CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, } // Default implementation of CreateTargetMIHazardRecognizer. -ScheduleHazardRecognizer *TargetInstrInfo:: -CreateTargetMIHazardRecognizer(const InstrItineraryData *II, - const ScheduleDAG *DAG) const { - return (ScheduleHazardRecognizer *) - new ScoreboardHazardRecognizer(II, DAG, "machine-scheduler"); +ScheduleHazardRecognizer *TargetInstrInfo::CreateTargetMIHazardRecognizer( + const InstrItineraryData *II, const ScheduleDAGMI *DAG) const { + return new ScoreboardHazardRecognizer(II, DAG, "machine-scheduler"); } // Default implementation of CreateTargetPostRAHazardRecognizer. ScheduleHazardRecognizer *TargetInstrInfo:: CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const { - return (ScheduleHazardRecognizer *) - new ScoreboardHazardRecognizer(II, DAG, "post-RA-sched"); + return new ScoreboardHazardRecognizer(II, DAG, "post-RA-sched"); } //===----------------------------------------------------------------------===// @@ -1121,18 +1119,64 @@ bool TargetInstrInfo::hasLowDefLatency(const TargetSchedModel &SchedModel, } Optional<ParamLoadedValue> -TargetInstrInfo::describeLoadedValue(const MachineInstr &MI) const { +TargetInstrInfo::describeLoadedValue(const MachineInstr &MI, + Register Reg) const { const MachineFunction *MF = MI.getMF(); - const MachineOperand *Op = nullptr; - DIExpression *Expr = DIExpression::get(MF->getFunction().getContext(), {});; - const MachineOperand *SrcRegOp, *DestRegOp; - - if (isCopyInstr(MI, SrcRegOp, DestRegOp)) { - Op = SrcRegOp; - return ParamLoadedValue(*Op, Expr); - } else if (MI.isMoveImmediate()) { - Op = &MI.getOperand(1); - return ParamLoadedValue(*Op, Expr); + const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); + DIExpression *Expr = DIExpression::get(MF->getFunction().getContext(), {}); + int64_t Offset; + + // To simplify the sub-register handling, verify that we only need to + // consider physical registers. + assert(MF->getProperties().hasProperty( + MachineFunctionProperties::Property::NoVRegs)); + + if (auto DestSrc = isCopyInstr(MI)) { + Register DestReg = DestSrc->Destination->getReg(); + + if (Reg == DestReg) + return ParamLoadedValue(*DestSrc->Source, Expr); + + // Cases where super- or sub-registers needs to be described should + // be handled by the target's hook implementation. + assert(!TRI->isSuperOrSubRegisterEq(Reg, DestReg) && + "TargetInstrInfo::describeLoadedValue can't describe super- or " + "sub-regs for copy instructions"); + return None; + } else if (auto RegImm = isAddImmediate(MI, Reg)) { + Register SrcReg = RegImm->Reg; + Offset = RegImm->Imm; + Expr = DIExpression::prepend(Expr, DIExpression::ApplyOffset, Offset); + return ParamLoadedValue(MachineOperand::CreateReg(SrcReg, false), Expr); + } else if (MI.hasOneMemOperand()) { + // Only describe memory which provably does not escape the function. As + // described in llvm.org/PR43343, escaped memory may be clobbered by the + // callee (or by another thread). + const auto &TII = MF->getSubtarget().getInstrInfo(); + const MachineFrameInfo &MFI = MF->getFrameInfo(); + const MachineMemOperand *MMO = MI.memoperands()[0]; + const PseudoSourceValue *PSV = MMO->getPseudoValue(); + + // If the address points to "special" memory (e.g. a spill slot), it's + // sufficient to check that it isn't aliased by any high-level IR value. + if (!PSV || PSV->mayAlias(&MFI)) + return None; + + const MachineOperand *BaseOp; + if (!TII->getMemOperandWithOffset(MI, BaseOp, Offset, TRI)) + return None; + + assert(MI.getNumExplicitDefs() == 1 && + "Can currently only handle mem instructions with a single define"); + + // TODO: In what way do we need to take Reg into consideration here? + + SmallVector<uint64_t, 8> Ops; + DIExpression::appendOffset(Ops, Offset); + Ops.push_back(dwarf::DW_OP_deref_size); + Ops.push_back(MMO->getSize()); + Expr = DIExpression::prependOpcodes(Expr, Ops); + return ParamLoadedValue(*BaseOp, Expr); } return None; |