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