108084145c652afdec1b21404ead287fb79964a14Chris Lattner//===-- TargetInstrInfo.cpp - Target Instruction Information --------------===//
2f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman//
3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//                     The LLVM Compiler Infrastructure
4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman//
8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===//
993fa70598c88fe14ebe4b3752daab4ea265233e1Chris Lattner//
10167b10cba4eff57718feeb30f567e324b96a9263Chris Lattner// This file implements the TargetInstrInfo class.
1193fa70598c88fe14ebe4b3752daab4ea265233e1Chris Lattner//
1293fa70598c88fe14ebe4b3752daab4ea265233e1Chris Lattner//===----------------------------------------------------------------------===//
1393fa70598c88fe14ebe4b3752daab4ea265233e1Chris Lattner
143501feab811c86c9659248a4875fc31a3165f84dChris Lattner#include "llvm/Target/TargetInstrInfo.h"
15fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen#include "llvm/CodeGen/MachineFrameInfo.h"
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineInstrBuilder.h"
17fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen#include "llvm/CodeGen/MachineMemOperand.h"
18fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen#include "llvm/CodeGen/MachineRegisterInfo.h"
19fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen#include "llvm/CodeGen/PseudoSourceValue.h"
20fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen#include "llvm/CodeGen/ScoreboardHazardRecognizer.h"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/StackMaps.h"
22bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick#include "llvm/IR/DataLayout.h"
23a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng#include "llvm/MC/MCAsmInfo.h"
24ab8be96fd30ca9396e6b84fdddf1ac6208984cadEvan Cheng#include "llvm/MC/MCInstrItineraries.h"
25fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen#include "llvm/Support/CommandLine.h"
26b6bbfebdc683a6a123410bca1175e14d264d4bc2Chris Lattner#include "llvm/Support/ErrorHandling.h"
27fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen#include "llvm/Support/raw_ostream.h"
28fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen#include "llvm/Target/TargetLowering.h"
29fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen#include "llvm/Target/TargetMachine.h"
30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetRegisterInfo.h"
31476b242fe7a61e5f9ac6214b0bc5c680d24f152eNick Lewycky#include <cctype>
32167b10cba4eff57718feeb30f567e324b96a9263Chris Lattnerusing namespace llvm;
3393fa70598c88fe14ebe4b3752daab4ea265233e1Chris Lattner
34fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenstatic cl::opt<bool> DisableHazardRecognizer(
35fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  "disable-sched-hazard", cl::Hidden, cl::init(false),
36fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  cl::desc("Disable hazard detection during preRA scheduling"));
37d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner
38cc22a7a2adfea3fc318a6d8ca0c692a8e892105bEvan ChengTargetInstrInfo::~TargetInstrInfo() {
39cc22a7a2adfea3fc318a6d8ca0c692a8e892105bEvan Cheng}
40cc22a7a2adfea3fc318a6d8ca0c692a8e892105bEvan Cheng
4115993f83a419950f06d2879d6701530ae6449317Evan Chengconst TargetRegisterClass*
42e837dead3c8dc3445ef6a0e2322179c57e264a13Evan ChengTargetInstrInfo::getRegClass(const MCInstrDesc &MCID, unsigned OpNum,
43397fc4874efe9c17e737d4c5c50bd19dc3bf27f5Jakob Stoklund Olesen                             const TargetRegisterInfo *TRI,
44397fc4874efe9c17e737d4c5c50bd19dc3bf27f5Jakob Stoklund Olesen                             const MachineFunction &MF) const {
45e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (OpNum >= MCID.getNumOperands())
46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
4715993f83a419950f06d2879d6701530ae6449317Evan Cheng
48e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  short RegClass = MCID.OpInfo[OpNum].RegClass;
49e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.OpInfo[OpNum].isLookupPtrRegClass())
50397fc4874efe9c17e737d4c5c50bd19dc3bf27f5Jakob Stoklund Olesen    return TRI->getPointerRegClass(MF, RegClass);
5115993f83a419950f06d2879d6701530ae6449317Evan Cheng
5215993f83a419950f06d2879d6701530ae6449317Evan Cheng  // Instructions like INSERT_SUBREG do not have fixed register classes.
5315993f83a419950f06d2879d6701530ae6449317Evan Cheng  if (RegClass < 0)
54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
5515993f83a419950f06d2879d6701530ae6449317Evan Cheng
5615993f83a419950f06d2879d6701530ae6449317Evan Cheng  // Otherwise just look it up normally.
5715993f83a419950f06d2879d6701530ae6449317Evan Cheng  return TRI->getRegClass(RegClass);
5815993f83a419950f06d2879d6701530ae6449317Evan Cheng}
5915993f83a419950f06d2879d6701530ae6449317Evan Cheng
60b6bbfebdc683a6a123410bca1175e14d264d4bc2Chris Lattner/// insertNoop - Insert a noop into the instruction stream at the specified
61b6bbfebdc683a6a123410bca1175e14d264d4bc2Chris Lattner/// point.
626e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trickvoid TargetInstrInfo::insertNoop(MachineBasicBlock &MBB,
63b6bbfebdc683a6a123410bca1175e14d264d4bc2Chris Lattner                                 MachineBasicBlock::iterator MI) const {
64b6bbfebdc683a6a123410bca1175e14d264d4bc2Chris Lattner  llvm_unreachable("Target didn't implement insertNoop!");
65b6bbfebdc683a6a123410bca1175e14d264d4bc2Chris Lattner}
66b6bbfebdc683a6a123410bca1175e14d264d4bc2Chris Lattner
67d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner/// Measure the specified inline asm to determine an approximation of its
68d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner/// length.
69d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach/// Comments (which run till the next SeparatorString or newline) do not
70d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner/// count as an instruction.
71d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner/// Any other non-whitespace text is considered an instruction, with
72d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach/// multiple instructions separated by SeparatorString or newlines.
73d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner/// Variable-length instructions are not handled here; this function
74d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner/// may be overloaded in the target code to do that.
75d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattnerunsigned TargetInstrInfo::getInlineAsmLength(const char *Str,
7633adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner                                             const MCAsmInfo &MAI) const {
776e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
786e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
79d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner  // Count the number of instructions in the asm.
80d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner  bool atInsnStart = true;
81d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner  unsigned Length = 0;
82d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner  for (; *Str; ++Str) {
83d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach    if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
84d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach                                strlen(MAI.getSeparatorString())) == 0)
85d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner      atInsnStart = true;
8687d0b9ed1462705dd9bf1cb7f67d0bf03af776c8Guy Benyei    if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) {
8733adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner      Length += MAI.getMaxInstLength();
88d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner      atInsnStart = false;
89d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner    }
9033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner    if (atInsnStart && strncmp(Str, MAI.getCommentString(),
9133adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner                               strlen(MAI.getCommentString())) == 0)
92d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner      atInsnStart = false;
93d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner  }
946e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
95d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner  return Length;
96d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattner}
97fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
98fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// ReplaceTailWithBranchTo - Delete the instruction OldInst and everything
99fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// after it, replacing it with an unconditional branch to NewDest.
100fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenvoid
101fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenTargetInstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
102fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                         MachineBasicBlock *NewDest) const {
103fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MachineBasicBlock *MBB = Tail->getParent();
104fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
105fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Remove all the old successors of MBB from the CFG.
106fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  while (!MBB->succ_empty())
107fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    MBB->removeSuccessor(MBB->succ_begin());
108fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
109fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Remove all the dead instructions from the end of MBB.
110fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MBB->erase(Tail, MBB->end());
111fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
112fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // If MBB isn't immediately before MBB, insert a branch to it.
113fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (++MachineFunction::iterator(MBB) != MachineFunction::iterator(NewDest))
114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    InsertBranch(*MBB, NewDest, nullptr, SmallVector<MachineOperand, 0>(),
115fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                 Tail->getDebugLoc());
116fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MBB->addSuccessor(NewDest);
117fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
118fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
119fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen// commuteInstruction - The default implementation of this method just exchanges
120fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen// the two operands returned by findCommutedOpIndices.
121fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenMachineInstr *TargetInstrInfo::commuteInstruction(MachineInstr *MI,
122fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                                  bool NewMI) const {
123fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const MCInstrDesc &MCID = MI->getDesc();
124fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  bool HasDef = MCID.getNumDefs();
125fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (HasDef && !MI->getOperand(0).isReg())
126fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    // No idea how to commute this instruction. Target should implement its own.
127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
128fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned Idx1, Idx2;
129fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!findCommutedOpIndices(MI, Idx1, Idx2)) {
130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MI->isCommutable() && "Precondition violation: MI must be commutable.");
131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
132fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  }
133fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
134fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  assert(MI->getOperand(Idx1).isReg() && MI->getOperand(Idx2).isReg() &&
135fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen         "This only knows how to commute register operands so far");
136fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned Reg0 = HasDef ? MI->getOperand(0).getReg() : 0;
137fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned Reg1 = MI->getOperand(Idx1).getReg();
138fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned Reg2 = MI->getOperand(Idx2).getReg();
139fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned SubReg0 = HasDef ? MI->getOperand(0).getSubReg() : 0;
140fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned SubReg1 = MI->getOperand(Idx1).getSubReg();
141fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned SubReg2 = MI->getOperand(Idx2).getSubReg();
142fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  bool Reg1IsKill = MI->getOperand(Idx1).isKill();
143fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  bool Reg2IsKill = MI->getOperand(Idx2).isKill();
144fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // If destination is tied to either of the commuted source register, then
145fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // it must be updated.
146fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (HasDef && Reg0 == Reg1 &&
147fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      MI->getDesc().getOperandConstraint(Idx1, MCOI::TIED_TO) == 0) {
148fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    Reg2IsKill = false;
149fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    Reg0 = Reg2;
150fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    SubReg0 = SubReg2;
151fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  } else if (HasDef && Reg0 == Reg2 &&
152fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen             MI->getDesc().getOperandConstraint(Idx2, MCOI::TIED_TO) == 0) {
153fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    Reg1IsKill = false;
154fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    Reg0 = Reg1;
155fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    SubReg0 = SubReg1;
156fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  }
157fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
158fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (NewMI) {
159fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    // Create a new instruction.
160fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    MachineFunction &MF = *MI->getParent()->getParent();
161fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    MI = MF.CloneMachineInstr(MI);
162fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  }
163fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
164fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (HasDef) {
165fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    MI->getOperand(0).setReg(Reg0);
166fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    MI->getOperand(0).setSubReg(SubReg0);
167fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  }
168fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MI->getOperand(Idx2).setReg(Reg1);
169fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MI->getOperand(Idx1).setReg(Reg2);
170fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MI->getOperand(Idx2).setSubReg(SubReg1);
171fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MI->getOperand(Idx1).setSubReg(SubReg2);
172fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MI->getOperand(Idx2).setIsKill(Reg1IsKill);
173fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MI->getOperand(Idx1).setIsKill(Reg2IsKill);
174fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return MI;
175fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
176fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
177fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// findCommutedOpIndices - If specified MI is commutable, return the two
178fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// operand indices that would swap value. Return true if the instruction
179fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// is not in a form which this routine understands.
180fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenbool TargetInstrInfo::findCommutedOpIndices(MachineInstr *MI,
181fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                            unsigned &SrcOpIdx1,
182fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                            unsigned &SrcOpIdx2) const {
183fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  assert(!MI->isBundle() &&
184fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen         "TargetInstrInfo::findCommutedOpIndices() can't handle bundles");
185fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
186fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const MCInstrDesc &MCID = MI->getDesc();
187fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!MCID.isCommutable())
188fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return false;
189fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // This assumes v0 = op v1, v2 and commuting would swap v1 and v2. If this
190fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // is not true, then the target must implement this.
191fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  SrcOpIdx1 = MCID.getNumDefs();
192fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  SrcOpIdx2 = SrcOpIdx1 + 1;
193fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!MI->getOperand(SrcOpIdx1).isReg() ||
194fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      !MI->getOperand(SrcOpIdx2).isReg())
195fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    // No idea.
196fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return false;
197fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return true;
198fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
199fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
200fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
201fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenbool
202fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenTargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
203fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!MI->isTerminator()) return false;
204fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
205fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Conditional branch is a special case.
206fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (MI->isBranch() && !MI->isBarrier())
207fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return true;
208fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!MI->isPredicable())
209fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return true;
210fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return !isPredicated(MI);
211fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
212fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
213fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
214fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenbool TargetInstrInfo::PredicateInstruction(MachineInstr *MI,
215fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                            const SmallVectorImpl<MachineOperand> &Pred) const {
216fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  bool MadeChange = false;
217fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
218fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  assert(!MI->isBundle() &&
219fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen         "TargetInstrInfo::PredicateInstruction() can't handle bundles");
220fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
221fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const MCInstrDesc &MCID = MI->getDesc();
222fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!MI->isPredicable())
223fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return false;
224fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
225fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  for (unsigned j = 0, i = 0, e = MI->getNumOperands(); i != e; ++i) {
226fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    if (MCID.OpInfo[i].isPredicate()) {
227fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      MachineOperand &MO = MI->getOperand(i);
228fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      if (MO.isReg()) {
229fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        MO.setReg(Pred[j].getReg());
230fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        MadeChange = true;
231fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      } else if (MO.isImm()) {
232fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        MO.setImm(Pred[j].getImm());
233fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        MadeChange = true;
234fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      } else if (MO.isMBB()) {
235fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        MO.setMBB(Pred[j].getMBB());
236fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        MadeChange = true;
237fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      }
238fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      ++j;
239fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    }
240fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  }
241fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return MadeChange;
242fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
243fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
244fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenbool TargetInstrInfo::hasLoadFromStackSlot(const MachineInstr *MI,
245fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                           const MachineMemOperand *&MMO,
246fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                           int &FrameIndex) const {
247fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  for (MachineInstr::mmo_iterator o = MI->memoperands_begin(),
248fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen         oe = MI->memoperands_end();
249fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen       o != oe;
250fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen       ++o) {
251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if ((*o)->isLoad()) {
252fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      if (const FixedStackPseudoSourceValue *Value =
253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          dyn_cast_or_null<FixedStackPseudoSourceValue>(
254dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              (*o)->getPseudoValue())) {
255fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        FrameIndex = Value->getFrameIndex();
256fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        MMO = *o;
257fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        return true;
258fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      }
259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
260fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  }
261fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return false;
262fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
263fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
264fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenbool TargetInstrInfo::hasStoreToStackSlot(const MachineInstr *MI,
265fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                          const MachineMemOperand *&MMO,
266fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                          int &FrameIndex) const {
267fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  for (MachineInstr::mmo_iterator o = MI->memoperands_begin(),
268fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen         oe = MI->memoperands_end();
269fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen       o != oe;
270fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen       ++o) {
271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if ((*o)->isStore()) {
272fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      if (const FixedStackPseudoSourceValue *Value =
273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          dyn_cast_or_null<FixedStackPseudoSourceValue>(
274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              (*o)->getPseudoValue())) {
275fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        FrameIndex = Value->getFrameIndex();
276fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        MMO = *o;
277fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        return true;
278fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      }
279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
280fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  }
281fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return false;
282fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
283fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
284bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trickbool TargetInstrInfo::getStackSlotRange(const TargetRegisterClass *RC,
285bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick                                        unsigned SubIdx, unsigned &Size,
286bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick                                        unsigned &Offset,
287bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick                                        const TargetMachine *TM) const {
288bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  if (!SubIdx) {
289bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick    Size = RC->getSize();
290bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick    Offset = 0;
291bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick    return true;
292bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  }
293bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  unsigned BitSize = TM->getRegisterInfo()->getSubRegIdxSize(SubIdx);
294bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  // Convert bit size to byte size to be consistent with
295bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  // MCRegisterClass::getSize().
296bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  if (BitSize % 8)
297bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick    return false;
298bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick
299bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  int BitOffset = TM->getRegisterInfo()->getSubRegIdxOffset(SubIdx);
300bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  if (BitOffset < 0 || BitOffset % 8)
301bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick    return false;
302bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick
303bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  Size = BitSize /= 8;
304bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  Offset = (unsigned)BitOffset / 8;
305bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick
306bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  assert(RC->getSize() >= (Offset + Size) && "bad subregister range");
307bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick
308bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  if (!TM->getDataLayout()->isLittleEndian()) {
309bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick    Offset = RC->getSize() - (Offset + Size);
310bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  }
311bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick  return true;
312bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick}
313bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick
314fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenvoid TargetInstrInfo::reMaterialize(MachineBasicBlock &MBB,
315fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                    MachineBasicBlock::iterator I,
316fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                    unsigned DestReg,
317fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                    unsigned SubIdx,
318fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                    const MachineInstr *Orig,
319fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                    const TargetRegisterInfo &TRI) const {
320fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
321fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MI->substituteRegister(MI->getOperand(0).getReg(), DestReg, SubIdx, TRI);
322fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MBB.insert(I, MI);
323fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
324fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
325fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenbool
326fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenTargetInstrInfo::produceSameValue(const MachineInstr *MI0,
327fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                  const MachineInstr *MI1,
328fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                  const MachineRegisterInfo *MRI) const {
329fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return MI0->isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs);
330fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
331fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
332fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenMachineInstr *TargetInstrInfo::duplicate(MachineInstr *Orig,
333fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                         MachineFunction &MF) const {
334fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  assert(!Orig->isNotDuplicable() &&
335fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen         "Instruction cannot be duplicated");
336fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return MF.CloneMachineInstr(Orig);
337fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
338fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
339fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen// If the COPY instruction in MI can be folded to a stack operation, return
340fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen// the register class to use.
341fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenstatic const TargetRegisterClass *canFoldCopy(const MachineInstr *MI,
342fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                              unsigned FoldIdx) {
343fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  assert(MI->isCopy() && "MI must be a COPY instruction");
344fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (MI->getNumOperands() != 2)
345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
346fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  assert(FoldIdx<2 && "FoldIdx refers no nonexistent operand");
347fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
348fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const MachineOperand &FoldOp = MI->getOperand(FoldIdx);
349fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const MachineOperand &LiveOp = MI->getOperand(1-FoldIdx);
350fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
351fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (FoldOp.getSubReg() || LiveOp.getSubReg())
352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
353fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
354fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned FoldReg = FoldOp.getReg();
355fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned LiveReg = LiveOp.getReg();
356fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
357fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  assert(TargetRegisterInfo::isVirtualRegister(FoldReg) &&
358fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen         "Cannot fold physregs");
359fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
360fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
361fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const TargetRegisterClass *RC = MRI.getRegClass(FoldReg);
362fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
363fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (TargetRegisterInfo::isPhysicalRegister(LiveOp.getReg()))
364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return RC->contains(LiveOp.getReg()) ? RC : nullptr;
365fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
366fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (RC->hasSubClassEq(MRI.getRegClass(LiveReg)))
367fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return RC;
368fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
369fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // FIXME: Allow folding when register classes are memory compatible.
370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
371fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
372fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
373fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenbool TargetInstrInfo::
374fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesencanFoldMemoryOperand(const MachineInstr *MI,
375fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                     const SmallVectorImpl<unsigned> &Ops) const {
376fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return MI->isCopy() && Ops.size() == 1 && canFoldCopy(MI, Ops[0]);
377fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
378fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic MachineInstr* foldPatchpoint(MachineFunction &MF,
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    MachineInstr *MI,
38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    const SmallVectorImpl<unsigned> &Ops,
38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    int FrameIndex,
38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    const TargetInstrInfo &TII) {
38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned StartIdx = 0;
38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (MI->getOpcode()) {
38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case TargetOpcode::STACKMAP:
38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StartIdx = 2; // Skip ID, nShadowBytes.
38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case TargetOpcode::PATCHPOINT: {
39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // For PatchPoint, the call args are not foldable.
39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    PatchPointOpers opers(MI);
39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StartIdx = opers.getVarIdx();
39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("unexpected stackmap opcode");
39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Return false if any operands requested for folding are not foldable (not
40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // part of the stackmap's live values).
40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (SmallVectorImpl<unsigned>::const_iterator I = Ops.begin(), E = Ops.end();
40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       I != E; ++I) {
40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (*I < StartIdx)
404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return nullptr;
40536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachineInstr *NewMI =
40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MF.CreateMachineInstr(TII.get(MI->getOpcode()), MI->getDebugLoc(), true);
40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachineInstrBuilder MIB(MF, NewMI);
41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // No need to fold return, the meta data, and function arguments
41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0; i < StartIdx; ++i)
41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MIB.addOperand(MI->getOperand(i));
41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = StartIdx; i < MI->getNumOperands(); ++i) {
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MachineOperand &MO = MI->getOperand(i);
41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (std::find(Ops.begin(), Ops.end(), i) != Ops.end()) {
41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned SpillSize;
41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned SpillOffset;
42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Compute the spill slot size and offset.
42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const TargetRegisterClass *RC =
42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MF.getRegInfo().getRegClass(MO.getReg());
42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      bool Valid = TII.getStackSlotRange(RC, MO.getSubReg(), SpillSize,
42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                         SpillOffset, &MF.getTarget());
42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!Valid)
42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        report_fatal_error("cannot spill patchpoint subregister operand");
42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MIB.addImm(StackMaps::IndirectMemRefOp);
42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MIB.addImm(SpillSize);
42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MIB.addFrameIndex(FrameIndex);
43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MIB.addImm(SpillOffset);
43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MIB.addOperand(MO);
43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return NewMI;
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
438fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// foldMemoryOperand - Attempt to fold a load or store of the specified stack
439fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// slot into the specified machine instruction for the specified operand(s).
440fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// If this is possible, a new instruction is returned with the specified
441fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// operand folded, otherwise NULL is returned. The client is responsible for
442fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// removing the old instruction and adding the new one in the instruction
443fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// stream.
444fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenMachineInstr*
445fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenTargetInstrInfo::foldMemoryOperand(MachineBasicBlock::iterator MI,
446fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                   const SmallVectorImpl<unsigned> &Ops,
447fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                   int FI) const {
448fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned Flags = 0;
449fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  for (unsigned i = 0, e = Ops.size(); i != e; ++i)
450fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    if (MI->getOperand(Ops[i]).isDef())
451fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      Flags |= MachineMemOperand::MOStore;
452fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    else
453fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      Flags |= MachineMemOperand::MOLoad;
454fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
455fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MachineBasicBlock *MBB = MI->getParent();
456fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  assert(MBB && "foldMemoryOperand needs an inserted instruction");
457fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MachineFunction &MF = *MBB->getParent();
458fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
459dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineInstr *NewMI = nullptr;
46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (MI->getOpcode() == TargetOpcode::STACKMAP ||
46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MI->getOpcode() == TargetOpcode::PATCHPOINT) {
46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Fold stackmap/patchpoint.
46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NewMI = foldPatchpoint(MF, MI, Ops, FI, *this);
46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Ask the target to do the actual folding.
46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NewMI =foldMemoryOperandImpl(MF, MI, Ops, FI);
46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (NewMI) {
471849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick    NewMI->setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
472fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    // Add a memory operand, foldMemoryOperandImpl doesn't do that.
473fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    assert((!(Flags & MachineMemOperand::MOStore) ||
474fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen            NewMI->mayStore()) &&
475fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen           "Folded a def to a non-store!");
476fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    assert((!(Flags & MachineMemOperand::MOLoad) ||
477fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen            NewMI->mayLoad()) &&
478fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen           "Folded a use to a non-load!");
479fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    const MachineFrameInfo &MFI = *MF.getFrameInfo();
480fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    assert(MFI.getObjectOffset(FI) != -1);
481fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    MachineMemOperand *MMO =
482fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI),
483fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                              Flags, MFI.getObjectSize(FI),
484fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                              MFI.getObjectAlignment(FI));
485fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    NewMI->addMemOperand(MF, MMO);
486fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
487fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    // FIXME: change foldMemoryOperandImpl semantics to also insert NewMI.
488fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return MBB->insert(MI, NewMI);
489fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  }
490fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
491fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Straight COPY may fold as load/store.
492fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!MI->isCopy() || Ops.size() != 1)
493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
494fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
495fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const TargetRegisterClass *RC = canFoldCopy(MI, Ops[0]);
496fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!RC)
497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
498fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
499fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const MachineOperand &MO = MI->getOperand(1-Ops[0]);
500fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MachineBasicBlock::iterator Pos = MI;
501fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo();
502fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
503fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (Flags == MachineMemOperand::MOStore)
504fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    storeRegToStackSlot(*MBB, Pos, MO.getReg(), MO.isKill(), FI, RC, TRI);
505fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  else
506fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    loadRegFromStackSlot(*MBB, Pos, MO.getReg(), FI, RC, TRI);
507fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return --Pos;
508fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
509fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
510fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// foldMemoryOperand - Same as the previous version except it allows folding
511fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// of any load and store from / to any address, not just from a specific
512fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// stack slot.
513fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenMachineInstr*
514fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenTargetInstrInfo::foldMemoryOperand(MachineBasicBlock::iterator MI,
515fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                   const SmallVectorImpl<unsigned> &Ops,
516fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                   MachineInstr* LoadMI) const {
517fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  assert(LoadMI->canFoldAsLoad() && "LoadMI isn't foldable!");
518fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen#ifndef NDEBUG
519fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  for (unsigned i = 0, e = Ops.size(); i != e; ++i)
520fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    assert(MI->getOperand(Ops[i]).isUse() && "Folding load into def!");
521fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen#endif
522fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MachineBasicBlock &MBB = *MI->getParent();
523fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  MachineFunction &MF = *MBB.getParent();
524fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
525fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Ask the target to do the actual folding.
526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineInstr *NewMI = nullptr;
52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int FrameIndex = 0;
52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
52936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((MI->getOpcode() == TargetOpcode::STACKMAP ||
53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       MI->getOpcode() == TargetOpcode::PATCHPOINT) &&
53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      isLoadFromStackSlot(LoadMI, FrameIndex)) {
53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Fold stackmap/patchpoint.
53336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NewMI = foldPatchpoint(MF, MI, Ops, FrameIndex, *this);
53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
53536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Ask the target to do the actual folding.
53636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NewMI = foldMemoryOperandImpl(MF, MI, Ops, LoadMI);
53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!NewMI) return nullptr;
540fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
541fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  NewMI = MBB.insert(MI, NewMI);
542fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
543fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Copy the memoperands from the load to the folded instruction.
544849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick  if (MI->memoperands_empty()) {
545849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick    NewMI->setMemRefs(LoadMI->memoperands_begin(),
546849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick                      LoadMI->memoperands_end());
547849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick  }
548849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick  else {
549849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick    // Handle the rare case of folding multiple loads.
550849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick    NewMI->setMemRefs(MI->memoperands_begin(),
551849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick                      MI->memoperands_end());
552849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick    for (MachineInstr::mmo_iterator I = LoadMI->memoperands_begin(),
553849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick           E = LoadMI->memoperands_end(); I != E; ++I) {
554849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick      NewMI->addMemOperand(MF, *I);
555849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick    }
556849596ced42f2760c5b63f7676e16829b808b5c9Andrew Trick  }
557fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return NewMI;
558fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
559fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
560fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenbool TargetInstrInfo::
561fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenisReallyTriviallyReMaterializableGeneric(const MachineInstr *MI,
562fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                         AliasAnalysis *AA) const {
563fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const MachineFunction &MF = *MI->getParent()->getParent();
564fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const MachineRegisterInfo &MRI = MF.getRegInfo();
565fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const TargetMachine &TM = MF.getTarget();
566fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const TargetInstrInfo &TII = *TM.getInstrInfo();
567fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
568fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Remat clients assume operand 0 is the defined register.
569fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!MI->getNumOperands() || !MI->getOperand(0).isReg())
570fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return false;
571fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned DefReg = MI->getOperand(0).getReg();
572fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
573fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // A sub-register definition can only be rematerialized if the instruction
574fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // doesn't read the other parts of the register.  Otherwise it is really a
575fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // read-modify-write operation on the full virtual register which cannot be
576fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // moved safely.
577fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (TargetRegisterInfo::isVirtualRegister(DefReg) &&
578fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      MI->getOperand(0).getSubReg() && MI->readsVirtualRegister(DefReg))
579fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return false;
580fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
581fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // A load from a fixed stack slot can be rematerialized. This may be
582fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // redundant with subsequent checks, but it's target-independent,
583fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // simple, and a common case.
584fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  int FrameIdx = 0;
585fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (TII.isLoadFromStackSlot(MI, FrameIdx) &&
586fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      MF.getFrameInfo()->isImmutableObjectIndex(FrameIdx))
587fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return true;
588fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
589fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Avoid instructions obviously unsafe for remat.
590fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (MI->isNotDuplicable() || MI->mayStore() ||
591fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      MI->hasUnmodeledSideEffects())
592fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return false;
593fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
594fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Don't remat inline asm. We have no idea how expensive it is
595fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // even if it's side effect free.
596fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (MI->isInlineAsm())
597fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return false;
598fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
599fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Avoid instructions which load from potentially varying memory.
600fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (MI->mayLoad() && !MI->isInvariantLoad(AA))
601fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return false;
602fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
603fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // If any of the registers accessed are non-constant, conservatively assume
604fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // the instruction is not rematerializable.
605fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
606fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    const MachineOperand &MO = MI->getOperand(i);
607fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    if (!MO.isReg()) continue;
608fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    unsigned Reg = MO.getReg();
609fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    if (Reg == 0)
610fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      continue;
611fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
612fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    // Check for a well-behaved physical register.
613fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
614fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      if (MO.isUse()) {
615fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        // If the physreg has no defs anywhere, it's just an ambient register
616fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        // and we can freely move its uses. Alternatively, if it's allocatable,
617fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        // it could get allocated to something with a def during allocation.
618fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        if (!MRI.isConstantPhysReg(Reg, MF))
619fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen          return false;
620fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      } else {
621fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        // A physreg def. We can't remat it.
622fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen        return false;
623fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      }
624fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      continue;
625fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    }
626fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
627fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    // Only allow one virtual-register def.  There may be multiple defs of the
628fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    // same virtual register, though.
629fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    if (MO.isDef() && Reg != DefReg)
630fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      return false;
631fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
632fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    // Don't allow any virtual-register uses. Rematting an instruction with
633fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    // virtual register uses would length the live ranges of the uses, which
634fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    // is not necessarily a good idea, certainly not "trivial".
635fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    if (MO.isUse())
636fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen      return false;
637fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  }
638fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
639fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Everything checked out.
640fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return true;
641fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
642fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
643fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// isSchedulingBoundary - Test if the given instruction should be
644fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// considered a scheduling boundary. This primarily includes labels
645fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// and terminators.
646fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenbool TargetInstrInfo::isSchedulingBoundary(const MachineInstr *MI,
647fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                           const MachineBasicBlock *MBB,
648fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                           const MachineFunction &MF) const {
649fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Terminators and labels can't be scheduled around.
65036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (MI->isTerminator() || MI->isPosition())
651fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return true;
652fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
653fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Don't attempt to schedule around any instruction that defines
654fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // a stack-oriented pointer, as it's unlikely to be profitable. This
655fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // saves compile time, because it doesn't require every single
656fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // stack slot reference to depend on the instruction that does the
657fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // modification.
658fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const TargetLowering &TLI = *MF.getTarget().getTargetLowering();
659fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo();
660fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (MI->modifiesRegister(TLI.getStackPointerRegisterToSaveRestore(), TRI))
661fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return true;
662fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
663fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return false;
664fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
665fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
666fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen// Provide a global flag for disabling the PreRA hazard recognizer that targets
667fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen// may choose to honor.
668fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenbool TargetInstrInfo::usePreRAHazardRecognizer() const {
669fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return !DisableHazardRecognizer;
670fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
671fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
672fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen// Default implementation of CreateTargetRAHazardRecognizer.
673fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenScheduleHazardRecognizer *TargetInstrInfo::
674cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesCreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,
675fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                             const ScheduleDAG *DAG) const {
676fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Dummy hazard recognizer allows all instructions to issue.
677fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return new ScheduleHazardRecognizer();
678fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
679fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
680fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen// Default implementation of CreateTargetMIHazardRecognizer.
681fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenScheduleHazardRecognizer *TargetInstrInfo::
682fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenCreateTargetMIHazardRecognizer(const InstrItineraryData *II,
683fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                               const ScheduleDAG *DAG) const {
684fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return (ScheduleHazardRecognizer *)
685fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    new ScoreboardHazardRecognizer(II, DAG, "misched");
686fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
687fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
688fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen// Default implementation of CreateTargetPostRAHazardRecognizer.
689fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenScheduleHazardRecognizer *TargetInstrInfo::
690fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenCreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
691fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                   const ScheduleDAG *DAG) const {
692fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return (ScheduleHazardRecognizer *)
693fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    new ScoreboardHazardRecognizer(II, DAG, "post-RA-sched");
694fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
695fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
696fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen//===----------------------------------------------------------------------===//
697fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen//  SelectionDAG latency interface.
698fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen//===----------------------------------------------------------------------===//
699fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
700fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenint
701fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenTargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
702fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                   SDNode *DefNode, unsigned DefIdx,
703fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                   SDNode *UseNode, unsigned UseIdx) const {
704fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!ItinData || ItinData->isEmpty())
705fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return -1;
706fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
707fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!DefNode->isMachineOpcode())
708fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return -1;
709fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
710fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned DefClass = get(DefNode->getMachineOpcode()).getSchedClass();
711fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!UseNode->isMachineOpcode())
712fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return ItinData->getOperandCycle(DefClass, DefIdx);
713fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned UseClass = get(UseNode->getMachineOpcode()).getSchedClass();
714fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
715fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
716fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
717fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenint TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
718fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                     SDNode *N) const {
719fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!ItinData || ItinData->isEmpty())
720fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return 1;
721fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
722fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!N->isMachineOpcode())
723fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return 1;
724fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
725fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return ItinData->getStageLatency(get(N->getMachineOpcode()).getSchedClass());
726fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
727fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
728fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen//===----------------------------------------------------------------------===//
729fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen//  MachineInstr latency interface.
730fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen//===----------------------------------------------------------------------===//
731fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
732fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenunsigned
733fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesenTargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData,
734fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                const MachineInstr *MI) const {
735fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!ItinData || ItinData->isEmpty())
736fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return 1;
737fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
738fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned Class = MI->getDesc().getSchedClass();
739fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  int UOps = ItinData->Itineraries[Class].NumMicroOps;
740fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (UOps >= 0)
741fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return UOps;
742fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
743fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // The # of u-ops is dynamically determined. The specific target should
744fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // override this function to return the right number.
745fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return 1;
746fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
747fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
748fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// Return the default expected latency for a def based on it's opcode.
749fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenunsigned TargetInstrInfo::defaultDefLatency(const MCSchedModel *SchedModel,
750fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                            const MachineInstr *DefMI) const {
751fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (DefMI->isTransient())
752fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return 0;
753fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (DefMI->mayLoad())
754fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return SchedModel->LoadLatency;
755fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (isHighLatencyDef(DefMI->getOpcode()))
756fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return SchedModel->HighLatency;
757fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return 1;
758fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
759fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
760d42730dc712026cbfb1322a979e0ac72cd31a19eArnold Schwaighoferunsigned TargetInstrInfo::getPredicationCost(const MachineInstr *) const {
761d42730dc712026cbfb1322a979e0ac72cd31a19eArnold Schwaighofer  return 0;
762d42730dc712026cbfb1322a979e0ac72cd31a19eArnold Schwaighofer}
763d42730dc712026cbfb1322a979e0ac72cd31a19eArnold Schwaighofer
764fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenunsigned TargetInstrInfo::
765fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesengetInstrLatency(const InstrItineraryData *ItinData,
766fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                const MachineInstr *MI,
767fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                unsigned *PredCost) const {
768fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Default to one cycle for no itinerary. However, an "empty" itinerary may
769fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // still have a MinLatency property, which getStageLatency checks.
770fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!ItinData)
771fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return MI->mayLoad() ? 2 : 1;
772fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
773fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return ItinData->getStageLatency(MI->getDesc().getSchedClass());
774fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
775fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
776fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenbool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData,
777fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                       const MachineInstr *DefMI,
778fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                                       unsigned DefIdx) const {
779fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!ItinData || ItinData->isEmpty())
780fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return false;
781fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
782fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned DefClass = DefMI->getDesc().getSchedClass();
783fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
784fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return (DefCycle != -1 && DefCycle <= 1);
785fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
786fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
787fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// Both DefMI and UseMI must be valid.  By default, call directly to the
788fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// itinerary. This may be overriden by the target.
789fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenint TargetInstrInfo::
790fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesengetOperandLatency(const InstrItineraryData *ItinData,
791fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                  const MachineInstr *DefMI, unsigned DefIdx,
792fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                  const MachineInstr *UseMI, unsigned UseIdx) const {
793fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned DefClass = DefMI->getDesc().getSchedClass();
794fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned UseClass = UseMI->getDesc().getSchedClass();
795fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
796fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
797fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
798fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// If we can determine the operand latency from the def only, without itinerary
799fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// lookup, do so. Otherwise return -1.
800fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenint TargetInstrInfo::computeDefOperandLatency(
801fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  const InstrItineraryData *ItinData,
802b86a0cdb674549d8493043331cecd9cbf53b80daAndrew Trick  const MachineInstr *DefMI) const {
803fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
804fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Let the target hook getInstrLatency handle missing itineraries.
805fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (!ItinData)
806fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return getInstrLatency(ItinData, DefMI);
807fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
808b86a0cdb674549d8493043331cecd9cbf53b80daAndrew Trick  if(ItinData->isEmpty())
809fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return defaultDefLatency(ItinData->SchedModel, DefMI);
810fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
811fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // ...operand lookup required
812fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return -1;
813fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
814fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
815fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// computeOperandLatency - Compute and return the latency of the given data
816fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// dependent def and use when the operand indices are already known. UseMI may
817fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// be NULL for an unknown use.
818fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen///
819fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// FindMin may be set to get the minimum vs. expected latency. Minimum
820fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// latency is used for scheduling groups, while expected latency is for
821fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// instruction cost and critical path.
822fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen///
823fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// Depending on the subtarget's itinerary properties, this may or may not need
824fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// to call getOperandLatency(). For most subtargets, we don't need DefIdx or
825fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen/// UseIdx to compute min latency.
826fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesenunsigned TargetInstrInfo::
827fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund OlesencomputeOperandLatency(const InstrItineraryData *ItinData,
828fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen                      const MachineInstr *DefMI, unsigned DefIdx,
829b86a0cdb674549d8493043331cecd9cbf53b80daAndrew Trick                      const MachineInstr *UseMI, unsigned UseIdx) const {
830fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
831b86a0cdb674549d8493043331cecd9cbf53b80daAndrew Trick  int DefLatency = computeDefOperandLatency(ItinData, DefMI);
832fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (DefLatency >= 0)
833fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return DefLatency;
834fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
835fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  assert(ItinData && !ItinData->isEmpty() && "computeDefOperandLatency fail");
836fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
837fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  int OperLatency = 0;
838fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (UseMI)
839fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    OperLatency = getOperandLatency(ItinData, DefMI, DefIdx, UseMI, UseIdx);
840fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  else {
841fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    unsigned DefClass = DefMI->getDesc().getSchedClass();
842fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    OperLatency = ItinData->getOperandCycle(DefClass, DefIdx);
843fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  }
844fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  if (OperLatency >= 0)
845fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen    return OperLatency;
846fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
847fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // No operand latency was found.
848fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  unsigned InstrLatency = getInstrLatency(ItinData, DefMI);
849fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen
850fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  // Expected latency is the max of the stage latency and itinerary props.
851b86a0cdb674549d8493043331cecd9cbf53b80daAndrew Trick  InstrLatency = std::max(InstrLatency,
852b86a0cdb674549d8493043331cecd9cbf53b80daAndrew Trick                          defaultDefLatency(ItinData->SchedModel, DefMI));
853fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen  return InstrLatency;
854fa2d98632c77e5d9c305e97e5fa25d06f579127bJakob Stoklund Olesen}
855