795 lines · c
1//===-- PPCInstrInfo.h - PowerPC Instruction Information --------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the PowerPC implementation of the TargetInstrInfo class.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_TARGET_POWERPC_PPCINSTRINFO_H14#define LLVM_LIB_TARGET_POWERPC_PPCINSTRINFO_H15 16#include "MCTargetDesc/PPCMCTargetDesc.h"17#include "PPC.h"18#include "PPCRegisterInfo.h"19#include "llvm/ADT/SmallSet.h"20#include "llvm/CodeGen/LiveVariables.h"21#include "llvm/CodeGen/TargetInstrInfo.h"22 23#define GET_INSTRINFO_HEADER24#include "PPCGenInstrInfo.inc"25 26namespace llvm {27 28// Instructions that have an immediate form might be convertible to that29// form if the correct input is a result of a load immediate. In order to30// know whether the transformation is special, we might need to know some31// of the details of the two forms.32struct ImmInstrInfo {33 // Is the immediate field in the immediate form signed or unsigned?34 uint64_t SignedImm : 1;35 // Does the immediate need to be a multiple of some value?36 uint64_t ImmMustBeMultipleOf : 5;37 // Is R0/X0 treated specially by the original r+r instruction?38 // If so, in which operand?39 uint64_t ZeroIsSpecialOrig : 3;40 // Is R0/X0 treated specially by the new r+i instruction?41 // If so, in which operand?42 uint64_t ZeroIsSpecialNew : 3;43 // Is the operation commutative?44 uint64_t IsCommutative : 1;45 // The operand number to check for add-immediate def.46 uint64_t OpNoForForwarding : 3;47 // The operand number for the immediate.48 uint64_t ImmOpNo : 3;49 // The opcode of the new instruction.50 uint64_t ImmOpcode : 16;51 // The size of the immediate.52 uint64_t ImmWidth : 5;53 // The immediate should be truncated to N bits.54 uint64_t TruncateImmTo : 5;55 // Is the instruction summing the operand56 uint64_t IsSummingOperands : 1;57};58 59// Information required to convert an instruction to just a materialized60// immediate.61struct LoadImmediateInfo {62 unsigned Imm : 16;63 unsigned Is64Bit : 1;64 unsigned SetCR : 1;65};66 67// Index into the OpcodesForSpill array.68enum SpillOpcodeKey {69 SOK_Int4Spill,70 SOK_Int8Spill,71 SOK_Float8Spill,72 SOK_Float4Spill,73 SOK_CRSpill,74 SOK_CRBitSpill,75 SOK_VRVectorSpill,76 SOK_VSXVectorSpill,77 SOK_VectorFloat8Spill,78 SOK_VectorFloat4Spill,79 SOK_SpillToVSR,80 SOK_PairedVecSpill,81 SOK_AccumulatorSpill,82 SOK_UAccumulatorSpill,83 SOK_WAccumulatorSpill,84 SOK_DMRpSpill,85 SOK_DMRSpill,86 SOK_SPESpill,87 SOK_PairedG8Spill,88 SOK_LastOpcodeSpill // This must be last on the enum.89};90 91// PPC MachineCombiner patterns92enum PPCMachineCombinerPattern : unsigned {93 // These are patterns matched by the PowerPC to reassociate FMA chains.94 REASSOC_XY_AMM_BMM = MachineCombinerPattern::TARGET_PATTERN_START,95 REASSOC_XMM_AMM_BMM,96 97 // These are patterns matched by the PowerPC to reassociate FMA and FSUB to98 // reduce register pressure.99 REASSOC_XY_BCA,100 REASSOC_XY_BAC,101 102};103 104// Define list of load and store spill opcodes.105#define NoInstr PPC::INSTRUCTION_LIST_END106#define Pwr8LoadOpcodes \107 {PPC::LWZ, \108 PPC::LD, \109 PPC::LFD, \110 PPC::LFS, \111 PPC::RESTORE_CR, \112 PPC::RESTORE_CRBIT, \113 PPC::LVX, \114 PPC::LXVD2X, \115 PPC::LXSDX, \116 PPC::LXSSPX, \117 PPC::SPILLTOVSR_LD, \118 NoInstr, \119 NoInstr, \120 NoInstr, \121 NoInstr, \122 NoInstr, \123 NoInstr, \124 PPC::EVLDD, \125 PPC::RESTORE_QUADWORD}126 127#define Pwr9LoadOpcodes \128 {PPC::LWZ, \129 PPC::LD, \130 PPC::LFD, \131 PPC::LFS, \132 PPC::RESTORE_CR, \133 PPC::RESTORE_CRBIT, \134 PPC::LVX, \135 PPC::LXV, \136 PPC::DFLOADf64, \137 PPC::DFLOADf32, \138 PPC::SPILLTOVSR_LD, \139 NoInstr, \140 NoInstr, \141 NoInstr, \142 NoInstr, \143 NoInstr, \144 NoInstr, \145 NoInstr, \146 PPC::RESTORE_QUADWORD}147 148#define Pwr10LoadOpcodes \149 {PPC::LWZ, \150 PPC::LD, \151 PPC::LFD, \152 PPC::LFS, \153 PPC::RESTORE_CR, \154 PPC::RESTORE_CRBIT, \155 PPC::LVX, \156 PPC::LXV, \157 PPC::DFLOADf64, \158 PPC::DFLOADf32, \159 PPC::SPILLTOVSR_LD, \160 PPC::LXVP, \161 PPC::RESTORE_ACC, \162 PPC::RESTORE_UACC, \163 NoInstr, \164 NoInstr, \165 NoInstr, \166 NoInstr, \167 PPC::RESTORE_QUADWORD}168 169#define FutureLoadOpcodes \170 {PPC::LWZ, \171 PPC::LD, \172 PPC::LFD, \173 PPC::LFS, \174 PPC::RESTORE_CR, \175 PPC::RESTORE_CRBIT, \176 PPC::LVX, \177 PPC::LXV, \178 PPC::DFLOADf64, \179 PPC::DFLOADf32, \180 PPC::SPILLTOVSR_LD, \181 PPC::LXVP, \182 PPC::RESTORE_ACC, \183 PPC::RESTORE_UACC, \184 PPC::RESTORE_WACC, \185 PPC::RESTORE_DMRP, \186 PPC::RESTORE_DMR, \187 NoInstr, \188 PPC::RESTORE_QUADWORD}189 190#define Pwr8StoreOpcodes \191 {PPC::STW, \192 PPC::STD, \193 PPC::STFD, \194 PPC::STFS, \195 PPC::SPILL_CR, \196 PPC::SPILL_CRBIT, \197 PPC::STVX, \198 PPC::STXVD2X, \199 PPC::STXSDX, \200 PPC::STXSSPX, \201 PPC::SPILLTOVSR_ST, \202 NoInstr, \203 NoInstr, \204 NoInstr, \205 NoInstr, \206 NoInstr, \207 NoInstr, \208 PPC::EVSTDD, \209 PPC::SPILL_QUADWORD}210 211#define Pwr9StoreOpcodes \212 {PPC::STW, \213 PPC::STD, \214 PPC::STFD, \215 PPC::STFS, \216 PPC::SPILL_CR, \217 PPC::SPILL_CRBIT, \218 PPC::STVX, \219 PPC::STXV, \220 PPC::DFSTOREf64, \221 PPC::DFSTOREf32, \222 PPC::SPILLTOVSR_ST, \223 NoInstr, \224 NoInstr, \225 NoInstr, \226 NoInstr, \227 NoInstr, \228 NoInstr, \229 NoInstr, \230 PPC::SPILL_QUADWORD}231 232#define Pwr10StoreOpcodes \233 {PPC::STW, \234 PPC::STD, \235 PPC::STFD, \236 PPC::STFS, \237 PPC::SPILL_CR, \238 PPC::SPILL_CRBIT, \239 PPC::STVX, \240 PPC::STXV, \241 PPC::DFSTOREf64, \242 PPC::DFSTOREf32, \243 PPC::SPILLTOVSR_ST, \244 PPC::STXVP, \245 PPC::SPILL_ACC, \246 PPC::SPILL_UACC, \247 NoInstr, \248 NoInstr, \249 NoInstr, \250 NoInstr, \251 PPC::SPILL_QUADWORD}252 253#define FutureStoreOpcodes \254 {PPC::STW, \255 PPC::STD, \256 PPC::STFD, \257 PPC::STFS, \258 PPC::SPILL_CR, \259 PPC::SPILL_CRBIT, \260 PPC::STVX, \261 PPC::STXV, \262 PPC::DFSTOREf64, \263 PPC::DFSTOREf32, \264 PPC::SPILLTOVSR_ST, \265 PPC::STXVP, \266 PPC::SPILL_ACC, \267 PPC::SPILL_UACC, \268 PPC::SPILL_WACC, \269 PPC::SPILL_DMRP, \270 PPC::SPILL_DMR, \271 NoInstr, \272 PPC::SPILL_QUADWORD}273 274// Initialize arrays for load and store spill opcodes on supported subtargets.275#define StoreOpcodesForSpill \276 { Pwr8StoreOpcodes, Pwr9StoreOpcodes, Pwr10StoreOpcodes, FutureStoreOpcodes }277#define LoadOpcodesForSpill \278 { Pwr8LoadOpcodes, Pwr9LoadOpcodes, Pwr10LoadOpcodes, FutureLoadOpcodes }279 280class PPCSubtarget;281class PPCInstrInfo : public PPCGenInstrInfo {282 const PPCSubtarget &Subtarget;283 const PPCRegisterInfo RI;284 const unsigned StoreSpillOpcodesArray[4][SOK_LastOpcodeSpill] =285 StoreOpcodesForSpill;286 const unsigned LoadSpillOpcodesArray[4][SOK_LastOpcodeSpill] =287 LoadOpcodesForSpill;288 289 void StoreRegToStackSlot(MachineFunction &MF, unsigned SrcReg, bool isKill,290 int FrameIdx, const TargetRegisterClass *RC,291 SmallVectorImpl<MachineInstr *> &NewMIs) const;292 void LoadRegFromStackSlot(MachineFunction &MF, const DebugLoc &DL,293 unsigned DestReg, int FrameIdx,294 const TargetRegisterClass *RC,295 SmallVectorImpl<MachineInstr *> &NewMIs) const;296 297 // Replace the instruction with single LI if possible. \p DefMI must be LI or298 // LI8.299 bool simplifyToLI(MachineInstr &MI, MachineInstr &DefMI,300 unsigned OpNoForForwarding, MachineInstr **KilledDef) const;301 // If the inst is imm-form and its register operand is produced by a ADDI, put302 // the imm into the inst directly and remove the ADDI if possible.303 bool transformToNewImmFormFedByAdd(MachineInstr &MI, MachineInstr &DefMI,304 unsigned OpNoForForwarding) const;305 // If the inst is x-form and has imm-form and one of its operand is produced306 // by a LI, put the imm into the inst directly and remove the LI if possible.307 bool transformToImmFormFedByLI(MachineInstr &MI, const ImmInstrInfo &III,308 unsigned ConstantOpNo,309 MachineInstr &DefMI) const;310 // If the inst is x-form and has imm-form and one of its operand is produced311 // by an add-immediate, try to transform it when possible.312 bool transformToImmFormFedByAdd(MachineInstr &MI, const ImmInstrInfo &III,313 unsigned ConstantOpNo, MachineInstr &DefMI,314 bool KillDefMI) const;315 // Try to find that, if the instruction 'MI' contains any operand that316 // could be forwarded from some inst that feeds it. If yes, return the317 // Def of that operand. And OpNoForForwarding is the operand index in318 // the 'MI' for that 'Def'. If we see another use of this Def between319 // the Def and the MI, SeenIntermediateUse becomes 'true'.320 MachineInstr *getForwardingDefMI(MachineInstr &MI,321 unsigned &OpNoForForwarding,322 bool &SeenIntermediateUse) const;323 324 // Can the user MI have it's source at index \p OpNoForForwarding325 // forwarded from an add-immediate that feeds it?326 bool isUseMIElgibleForForwarding(MachineInstr &MI, const ImmInstrInfo &III,327 unsigned OpNoForForwarding) const;328 bool isDefMIElgibleForForwarding(MachineInstr &DefMI,329 const ImmInstrInfo &III,330 MachineOperand *&ImmMO,331 MachineOperand *&RegMO) const;332 bool isImmElgibleForForwarding(const MachineOperand &ImmMO,333 const MachineInstr &DefMI,334 const ImmInstrInfo &III,335 int64_t &Imm,336 int64_t BaseImm = 0) const;337 bool isRegElgibleForForwarding(const MachineOperand &RegMO,338 const MachineInstr &DefMI,339 const MachineInstr &MI, bool KillDefMI,340 bool &IsFwdFeederRegKilled,341 bool &SeenIntermediateUse) const;342 unsigned getSpillTarget() const;343 ArrayRef<unsigned> getStoreOpcodesForSpillArray() const;344 ArrayRef<unsigned> getLoadOpcodesForSpillArray() const;345 unsigned getSpillIndex(const TargetRegisterClass *RC) const;346 int16_t getFMAOpIdxInfo(unsigned Opcode) const;347 void reassociateFMA(MachineInstr &Root, unsigned Pattern,348 SmallVectorImpl<MachineInstr *> &InsInstrs,349 SmallVectorImpl<MachineInstr *> &DelInstrs,350 DenseMap<Register, unsigned> &InstrIdxForVirtReg) const;351 Register352 generateLoadForNewConst(unsigned Idx, MachineInstr *MI, Type *Ty,353 SmallVectorImpl<MachineInstr *> &InsInstrs) const;354 virtual void anchor();355 356protected:357 /// Commutes the operands in the given instruction.358 /// The commutable operands are specified by their indices OpIdx1 and OpIdx2.359 ///360 /// Do not call this method for a non-commutable instruction or for361 /// non-commutable pair of operand indices OpIdx1 and OpIdx2.362 /// Even though the instruction is commutable, the method may still363 /// fail to commute the operands, null pointer is returned in such cases.364 ///365 /// For example, we can commute rlwimi instructions, but only if the366 /// rotate amt is zero. We also have to munge the immediates a bit.367 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,368 unsigned OpIdx1,369 unsigned OpIdx2) const override;370 371public:372 explicit PPCInstrInfo(const PPCSubtarget &STI);373 374 bool isLoadFromConstantPool(MachineInstr *I) const;375 const Constant *getConstantFromConstantPool(MachineInstr *I) const;376 377 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As378 /// such, whenever a client has an instance of instruction info, it should379 /// always be able to get register info as well (through this method).380 ///381 const PPCRegisterInfo &getRegisterInfo() const { return RI; }382 383 bool isXFormMemOp(unsigned Opcode) const {384 return get(Opcode).TSFlags & PPCII::XFormMemOp;385 }386 bool isPrefixed(unsigned Opcode) const {387 return get(Opcode).TSFlags & PPCII::Prefixed;388 }389 bool isSExt32To64(unsigned Opcode) const {390 return get(Opcode).TSFlags & PPCII::SExt32To64;391 }392 bool isZExt32To64(unsigned Opcode) const {393 return get(Opcode).TSFlags & PPCII::ZExt32To64;394 }395 bool isMemriOp(unsigned Opcode) const {396 return get(Opcode).TSFlags & PPCII::MemriOp;397 }398 399 static bool isSameClassPhysRegCopy(unsigned Opcode) {400 unsigned CopyOpcodes[] = {PPC::OR, PPC::OR8, PPC::FMR,401 PPC::VOR, PPC::XXLOR, PPC::XXLORf,402 PPC::XSCPSGNDP, PPC::MCRF, PPC::CROR,403 PPC::EVOR, -1U};404 for (int i = 0; CopyOpcodes[i] != -1U; i++)405 if (Opcode == CopyOpcodes[i])406 return true;407 return false;408 }409 410 static bool hasPCRelFlag(unsigned TF) {411 return TF == PPCII::MO_PCREL_FLAG || TF == PPCII::MO_GOT_TLSGD_PCREL_FLAG ||412 TF == PPCII::MO_GOT_TLSLD_PCREL_FLAG ||413 TF == PPCII::MO_GOT_TPREL_PCREL_FLAG ||414 TF == PPCII::MO_TPREL_PCREL_FLAG || TF == PPCII::MO_TLS_PCREL_FLAG ||415 TF == PPCII::MO_GOT_PCREL_FLAG;416 }417 418 static bool hasGOTFlag(unsigned TF) {419 return TF == PPCII::MO_GOT_FLAG || TF == PPCII::MO_GOT_TLSGD_PCREL_FLAG ||420 TF == PPCII::MO_GOT_TLSLD_PCREL_FLAG ||421 TF == PPCII::MO_GOT_TPREL_PCREL_FLAG ||422 TF == PPCII::MO_GOT_PCREL_FLAG;423 }424 425 static bool hasTLSFlag(unsigned TF) {426 return TF == PPCII::MO_TLSGD_FLAG || TF == PPCII::MO_TPREL_FLAG ||427 TF == PPCII::MO_TLSLD_FLAG || TF == PPCII::MO_TLSGDM_FLAG ||428 TF == PPCII::MO_GOT_TLSGD_PCREL_FLAG ||429 TF == PPCII::MO_GOT_TLSLD_PCREL_FLAG ||430 TF == PPCII::MO_GOT_TPREL_PCREL_FLAG || TF == PPCII::MO_TPREL_LO ||431 TF == PPCII::MO_TPREL_HA || TF == PPCII::MO_DTPREL_LO ||432 TF == PPCII::MO_TLSLD_LO || TF == PPCII::MO_TLS ||433 TF == PPCII::MO_TPREL_PCREL_FLAG || TF == PPCII::MO_TLS_PCREL_FLAG;434 }435 436 ScheduleHazardRecognizer *437 CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,438 const ScheduleDAG *DAG) const override;439 ScheduleHazardRecognizer *440 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,441 const ScheduleDAG *DAG) const override;442 443 unsigned getInstrLatency(const InstrItineraryData *ItinData,444 const MachineInstr &MI,445 unsigned *PredCost = nullptr) const override;446 447 std::optional<unsigned> getOperandLatency(const InstrItineraryData *ItinData,448 const MachineInstr &DefMI,449 unsigned DefIdx,450 const MachineInstr &UseMI,451 unsigned UseIdx) const override;452 std::optional<unsigned> getOperandLatency(const InstrItineraryData *ItinData,453 SDNode *DefNode, unsigned DefIdx,454 SDNode *UseNode,455 unsigned UseIdx) const override {456 return PPCGenInstrInfo::getOperandLatency(ItinData, DefNode, DefIdx,457 UseNode, UseIdx);458 }459 460 bool hasLowDefLatency(const TargetSchedModel &SchedModel,461 const MachineInstr &DefMI,462 unsigned DefIdx) const override {463 // Machine LICM should hoist all instructions in low-register-pressure464 // situations; none are sufficiently free to justify leaving in a loop465 // body.466 return false;467 }468 469 bool useMachineCombiner() const override {470 return true;471 }472 473 /// When getMachineCombinerPatterns() finds patterns, this function generates474 /// the instructions that could replace the original code sequence475 void genAlternativeCodeSequence(476 MachineInstr &Root, unsigned Pattern,477 SmallVectorImpl<MachineInstr *> &InsInstrs,478 SmallVectorImpl<MachineInstr *> &DelInstrs,479 DenseMap<Register, unsigned> &InstrIdxForVirtReg) const override;480 481 /// Return true when there is potentially a faster code sequence for a fma482 /// chain ending in \p Root. All potential patterns are output in the \p483 /// P array.484 bool getFMAPatterns(MachineInstr &Root, SmallVectorImpl<unsigned> &Patterns,485 bool DoRegPressureReduce) const;486 487 CombinerObjective getCombinerObjective(unsigned Pattern) const override;488 489 /// Return true when there is potentially a faster code sequence490 /// for an instruction chain ending in <Root>. All potential patterns are491 /// output in the <Pattern> array.492 bool getMachineCombinerPatterns(MachineInstr &Root,493 SmallVectorImpl<unsigned> &Patterns,494 bool DoRegPressureReduce) const override;495 496 /// On PowerPC, we leverage machine combiner pass to reduce register pressure497 /// when the register pressure is high for one BB.498 /// Return true if register pressure for \p MBB is high and ABI is supported499 /// to reduce register pressure. Otherwise return false.500 bool shouldReduceRegisterPressure(501 const MachineBasicBlock *MBB,502 const RegisterClassInfo *RegClassInfo) const override;503 504 /// Fixup the placeholders we put in genAlternativeCodeSequence() for505 /// MachineCombiner.506 void507 finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern,508 SmallVectorImpl<MachineInstr *> &InsInstrs) const override;509 510 bool isAssociativeAndCommutative(const MachineInstr &Inst,511 bool Invert) const override;512 513 /// On PowerPC, we try to reassociate FMA chain which will increase514 /// instruction size. Set extension resource length limit to 1 for edge case.515 /// Resource Length is calculated by scaled resource usage in getCycles().516 /// Because of the division in getCycles(), it returns different cycles due to517 /// legacy scaled resource usage. So new resource length may be same with518 /// legacy or 1 bigger than legacy.519 /// We need to execlude the 1 bigger case even the resource length is not520 /// perserved for more FMA chain reassociations on PowerPC.521 int getExtendResourceLenLimit() const override { return 1; }522 523 // PowerPC specific version of setSpecialOperandAttr that copies Flags to MI524 // and clears nuw, nsw, and exact flags.525 using TargetInstrInfo::setSpecialOperandAttr;526 void setSpecialOperandAttr(MachineInstr &MI, uint32_t Flags) const;527 528 bool isCoalescableExtInstr(const MachineInstr &MI,529 Register &SrcReg, Register &DstReg,530 unsigned &SubIdx) const override;531 Register isLoadFromStackSlot(const MachineInstr &MI,532 int &FrameIndex) const override;533 bool isReMaterializableImpl(const MachineInstr &MI) const override;534 Register isStoreToStackSlot(const MachineInstr &MI,535 int &FrameIndex) const override;536 537 bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1,538 unsigned &SrcOpIdx2) const override;539 540 void insertNoop(MachineBasicBlock &MBB,541 MachineBasicBlock::iterator MI) const override;542 543 544 // Branch analysis.545 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,546 MachineBasicBlock *&FBB,547 SmallVectorImpl<MachineOperand> &Cond,548 bool AllowModify) const override;549 unsigned removeBranch(MachineBasicBlock &MBB,550 int *BytesRemoved = nullptr) const override;551 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,552 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,553 const DebugLoc &DL,554 int *BytesAdded = nullptr) const override;555 556 // Select analysis.557 bool canInsertSelect(const MachineBasicBlock &, ArrayRef<MachineOperand> Cond,558 Register, Register, Register, int &, int &,559 int &) const override;560 void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,561 const DebugLoc &DL, Register DstReg,562 ArrayRef<MachineOperand> Cond, Register TrueReg,563 Register FalseReg) const override;564 565 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,566 const DebugLoc &DL, Register DestReg, Register SrcReg,567 bool KillSrc, bool RenamableDest = false,568 bool RenamableSrc = false) const override;569 570 void storeRegToStackSlot(571 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg,572 bool isKill, int FrameIndex, const TargetRegisterClass *RC,573 574 Register VReg,575 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;576 577 // Emits a register spill without updating the register class for vector578 // registers. This ensures that when we spill a vector register the579 // element order in the register is the same as it was in memory.580 void storeRegToStackSlotNoUpd(MachineBasicBlock &MBB,581 MachineBasicBlock::iterator MBBI,582 unsigned SrcReg, bool isKill, int FrameIndex,583 const TargetRegisterClass *RC) const;584 585 void loadRegFromStackSlot(586 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,587 Register DestReg, int FrameIndex, const TargetRegisterClass *RC,588 589 Register VReg,590 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;591 592 // Emits a register reload without updating the register class for vector593 // registers. This ensures that when we reload a vector register the594 // element order in the register is the same as it was in memory.595 void loadRegFromStackSlotNoUpd(MachineBasicBlock &MBB,596 MachineBasicBlock::iterator MBBI,597 unsigned DestReg, int FrameIndex,598 const TargetRegisterClass *RC) const;599 600 unsigned getStoreOpcodeForSpill(const TargetRegisterClass *RC) const;601 602 unsigned getLoadOpcodeForSpill(const TargetRegisterClass *RC) const;603 604 bool605 reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;606 607 bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg,608 MachineRegisterInfo *MRI) const override;609 610 bool onlyFoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,611 Register Reg) const;612 613 // If conversion by predication (only supported by some branch instructions).614 // All of the profitability checks always return true; it is always615 // profitable to use the predicated branches.616 bool isProfitableToIfCvt(MachineBasicBlock &MBB,617 unsigned NumCycles, unsigned ExtraPredCycles,618 BranchProbability Probability) const override {619 return true;620 }621 622 bool isProfitableToIfCvt(MachineBasicBlock &TMBB,623 unsigned NumT, unsigned ExtraT,624 MachineBasicBlock &FMBB,625 unsigned NumF, unsigned ExtraF,626 BranchProbability Probability) const override;627 628 bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,629 BranchProbability Probability) const override {630 return true;631 }632 633 bool isProfitableToUnpredicate(MachineBasicBlock &TMBB,634 MachineBasicBlock &FMBB) const override {635 return false;636 }637 638 // Predication support.639 bool isPredicated(const MachineInstr &MI) const override;640 641 bool isSchedulingBoundary(const MachineInstr &MI,642 const MachineBasicBlock *MBB,643 const MachineFunction &MF) const override;644 645 bool PredicateInstruction(MachineInstr &MI,646 ArrayRef<MachineOperand> Pred) const override;647 648 bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,649 ArrayRef<MachineOperand> Pred2) const override;650 651 bool ClobbersPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred,652 bool SkipDead) const override;653 654 // Comparison optimization.655 656 bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,657 Register &SrcReg2, int64_t &Mask,658 int64_t &Value) const override;659 660 bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,661 Register SrcReg2, int64_t Mask, int64_t Value,662 const MachineRegisterInfo *MRI) const override;663 664 665 /// Return true if get the base operand, byte offset of an instruction and666 /// the memory width. Width is the size of memory that is being667 /// loaded/stored (e.g. 1, 2, 4, 8).668 bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt,669 const MachineOperand *&BaseOp,670 int64_t &Offset, LocationSize &Width,671 const TargetRegisterInfo *TRI) const;672 673 bool optimizeCmpPostRA(MachineInstr &MI) const;674 675 /// Get the base operand and byte offset of an instruction that reads/writes676 /// memory.677 bool getMemOperandsWithOffsetWidth(678 const MachineInstr &LdSt,679 SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset,680 bool &OffsetIsScalable, LocationSize &Width,681 const TargetRegisterInfo *TRI) const override;682 683 /// Returns true if the two given memory operations should be scheduled684 /// adjacent.685 bool shouldClusterMemOps(ArrayRef<const MachineOperand *> BaseOps1,686 int64_t Offset1, bool OffsetIsScalable1,687 ArrayRef<const MachineOperand *> BaseOps2,688 int64_t Offset2, bool OffsetIsScalable2,689 unsigned ClusterSize,690 unsigned NumBytes) const override;691 692 /// Return true if two MIs access different memory addresses and false693 /// otherwise694 bool695 areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,696 const MachineInstr &MIb) const override;697 698 /// GetInstSize - Return the number of bytes of code the specified699 /// instruction may be. This returns the maximum number of bytes.700 ///701 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;702 703 MCInst getNop() const override;704 705 std::pair<unsigned, unsigned>706 decomposeMachineOperandsTargetFlags(unsigned TF) const override;707 708 ArrayRef<std::pair<unsigned, const char *>>709 getSerializableDirectMachineOperandTargetFlags() const override;710 711 // Expand VSX Memory Pseudo instruction to either a VSX or a FP instruction.712 bool expandVSXMemPseudo(MachineInstr &MI) const;713 714 // Lower pseudo instructions after register allocation.715 bool expandPostRAPseudo(MachineInstr &MI) const override;716 717 const TargetRegisterClass *updatedRC(const TargetRegisterClass *RC) const;718 static int getRecordFormOpcode(unsigned Opcode);719 720 bool isTOCSaveMI(const MachineInstr &MI) const;721 722 std::pair<bool, bool>723 isSignOrZeroExtended(const unsigned Reg, const unsigned BinOpDepth,724 const MachineRegisterInfo *MRI) const;725 726 // Return true if the register is sign-extended from 32 to 64 bits.727 bool isSignExtended(const unsigned Reg,728 const MachineRegisterInfo *MRI) const {729 return isSignOrZeroExtended(Reg, 0, MRI).first;730 }731 732 // Return true if the register is zero-extended from 32 to 64 bits.733 bool isZeroExtended(const unsigned Reg,734 const MachineRegisterInfo *MRI) const {735 return isSignOrZeroExtended(Reg, 0, MRI).second;736 }737 void promoteInstr32To64ForElimEXTSW(const Register &Reg,738 MachineRegisterInfo *MRI,739 unsigned BinOpDepth,740 LiveVariables *LV) const;741 742 bool convertToImmediateForm(MachineInstr &MI,743 SmallSet<Register, 4> &RegsToUpdate,744 MachineInstr **KilledDef = nullptr) const;745 bool foldFrameOffset(MachineInstr &MI) const;746 bool combineRLWINM(MachineInstr &MI, MachineInstr **ToErase = nullptr) const;747 bool isADDIInstrEligibleForFolding(MachineInstr &ADDIMI, int64_t &Imm) const;748 bool isADDInstrEligibleForFolding(MachineInstr &ADDMI) const;749 bool isImmInstrEligibleForFolding(MachineInstr &MI, unsigned &BaseReg,750 unsigned &XFormOpcode,751 int64_t &OffsetOfImmInstr,752 ImmInstrInfo &III) const;753 bool isValidToBeChangedReg(MachineInstr *ADDMI, unsigned Index,754 MachineInstr *&ADDIMI, int64_t &OffsetAddi,755 int64_t OffsetImm) const;756 757 void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const;758 void replaceInstrOperandWithImm(MachineInstr &MI, unsigned OpNo,759 int64_t Imm) const;760 761 bool instrHasImmForm(unsigned Opc, bool IsVFReg, ImmInstrInfo &III,762 bool PostRA) const;763 764 // In PostRA phase, try to find instruction defines \p Reg before \p MI.765 // \p SeenIntermediate is set to true if uses between DefMI and \p MI exist.766 MachineInstr *getDefMIPostRA(unsigned Reg, MachineInstr &MI,767 bool &SeenIntermediateUse) const;768 769 // Materialize immediate after RA.770 void materializeImmPostRA(MachineBasicBlock &MBB,771 MachineBasicBlock::iterator MBBI,772 const DebugLoc &DL, Register Reg,773 int64_t Imm) const;774 775 /// Check \p Opcode is BDNZ (Decrement CTR and branch if it is still nonzero).776 bool isBDNZ(unsigned Opcode) const;777 778 /// Find the hardware loop instruction used to set-up the specified loop.779 /// On PPC, we have two instructions used to set-up the hardware loop780 /// (MTCTRloop, MTCTR8loop) with corresponding endloop (BDNZ, BDNZ8)781 /// instructions to indicate the end of a loop.782 MachineInstr *783 findLoopInstr(MachineBasicBlock &PreHeader,784 SmallPtrSet<MachineBasicBlock *, 8> &Visited) const;785 786 /// Analyze loop L, which must be a single-basic-block loop, and if the787 /// conditions can be understood enough produce a PipelinerLoopInfo object.788 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>789 analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override;790};791 792}793 794#endif795