#include "PPCInstrInfo.h"
#include "MCTargetDesc/PPCPredicates.h"
#include "PPC.h"
#include "PPCHazardRecognizers.h"
#include "PPCInstrBuilder.h"
#include "PPCMachineFunctionInfo.h"
#include "PPCTargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineCombinerPattern.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/RegisterPressure.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/StackMaps.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
usingnamespacellvm;
#define DEBUG_TYPE …
#define GET_INSTRMAP_INFO
#define GET_INSTRINFO_CTOR_DTOR
#include "PPCGenInstrInfo.inc"
STATISTIC(NumStoreSPILLVSRRCAsVec,
"Number of spillvsrrc spilled to stack as vec");
STATISTIC(NumStoreSPILLVSRRCAsGpr,
"Number of spillvsrrc spilled to stack as gpr");
STATISTIC(NumGPRtoVSRSpill, "Number of gpr spills to spillvsrrc");
STATISTIC(CmpIselsConverted,
"Number of ISELs that depend on comparison of constants converted");
STATISTIC(MissedConvertibleImmediateInstrs,
"Number of compare-immediate instructions fed by constants");
STATISTIC(NumRcRotatesConvertedToRcAnd,
"Number of record-form rotates converted to record-form andi");
static cl::
opt<bool> DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden,
cl::desc("Disable analysis for CTR loops"));
static cl::opt<bool> DisableCmpOpt("disable-ppc-cmp-opt",
cl::desc("Disable compare instruction optimization"), cl::Hidden);
static cl::opt<bool> VSXSelfCopyCrash("crash-on-ppc-vsx-self-copy",
cl::desc("Causes the backend to crash instead of generating a nop VSX copy"),
cl::Hidden);
static cl::opt<bool>
UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden,
cl::desc("Use the old (incorrect) instruction latency calculation"));
static cl::opt<float>
FMARPFactor("ppc-fma-rp-factor", cl::Hidden, cl::init(1.5),
cl::desc("register pressure factor for the transformations."));
static cl::opt<bool> EnableFMARegPressureReduction(
"ppc-fma-rp-reduction", cl::Hidden, cl::init(true),
cl::desc("enable register pressure reduce in machine combiner pass."));
void PPCInstrInfo::anchor() { … }
PPCInstrInfo::PPCInstrInfo(PPCSubtarget &STI)
: … { … }
ScheduleHazardRecognizer *
PPCInstrInfo::CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,
const ScheduleDAG *DAG) const { … }
ScheduleHazardRecognizer *
PPCInstrInfo::CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
const ScheduleDAG *DAG) const { … }
unsigned PPCInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
const MachineInstr &MI,
unsigned *PredCost) const { … }
std::optional<unsigned> PPCInstrInfo::getOperandLatency(
const InstrItineraryData *ItinData, const MachineInstr &DefMI,
unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const { … }
void PPCInstrInfo::setSpecialOperandAttr(MachineInstr &MI,
uint32_t Flags) const { … }
bool PPCInstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst,
bool Invert) const { … }
#define InfoArrayIdxFMAInst …
#define InfoArrayIdxFAddInst …
#define InfoArrayIdxFMULInst …
#define InfoArrayIdxAddOpIdx …
#define InfoArrayIdxMULOpIdx …
#define InfoArrayIdxFSubInst …
static const uint16_t FMAOpIdxInfo[][6] = …;
int16_t PPCInstrInfo::getFMAOpIdxInfo(unsigned Opcode) const { … }
bool PPCInstrInfo::getFMAPatterns(MachineInstr &Root,
SmallVectorImpl<unsigned> &Patterns,
bool DoRegPressureReduce) const { … }
void PPCInstrInfo::finalizeInsInstrs(
MachineInstr &Root, unsigned &Pattern,
SmallVectorImpl<MachineInstr *> &InsInstrs) const { … }
bool PPCInstrInfo::shouldReduceRegisterPressure(
const MachineBasicBlock *MBB, const RegisterClassInfo *RegClassInfo) const { … }
bool PPCInstrInfo::isLoadFromConstantPool(MachineInstr *I) const { … }
Register PPCInstrInfo::generateLoadForNewConst(
unsigned Idx, MachineInstr *MI, Type *Ty,
SmallVectorImpl<MachineInstr *> &InsInstrs) const { … }
const Constant *
PPCInstrInfo::getConstantFromConstantPool(MachineInstr *I) const { … }
CombinerObjective PPCInstrInfo::getCombinerObjective(unsigned Pattern) const { … }
bool PPCInstrInfo::getMachineCombinerPatterns(
MachineInstr &Root, SmallVectorImpl<unsigned> &Patterns,
bool DoRegPressureReduce) const { … }
void PPCInstrInfo::genAlternativeCodeSequence(
MachineInstr &Root, unsigned Pattern,
SmallVectorImpl<MachineInstr *> &InsInstrs,
SmallVectorImpl<MachineInstr *> &DelInstrs,
DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const { … }
void PPCInstrInfo::reassociateFMA(
MachineInstr &Root, unsigned Pattern,
SmallVectorImpl<MachineInstr *> &InsInstrs,
SmallVectorImpl<MachineInstr *> &DelInstrs,
DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const { … }
bool PPCInstrInfo::isCoalescableExtInstr(const MachineInstr &MI,
Register &SrcReg, Register &DstReg,
unsigned &SubIdx) const { … }
Register PPCInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
int &FrameIndex) const { … }
bool PPCInstrInfo::isReallyTriviallyReMaterializable(
const MachineInstr &MI) const { … }
Register PPCInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
int &FrameIndex) const { … }
MachineInstr *PPCInstrInfo::commuteInstructionImpl(MachineInstr &MI, bool NewMI,
unsigned OpIdx1,
unsigned OpIdx2) const { … }
bool PPCInstrInfo::findCommutedOpIndices(const MachineInstr &MI,
unsigned &SrcOpIdx1,
unsigned &SrcOpIdx2) const { … }
void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const { … }
MCInst PPCInstrInfo::getNop() const { … }
bool PPCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const { … }
unsigned PPCInstrInfo::removeBranch(MachineBasicBlock &MBB,
int *BytesRemoved) const { … }
unsigned PPCInstrInfo::insertBranch(MachineBasicBlock &MBB,
MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
ArrayRef<MachineOperand> Cond,
const DebugLoc &DL,
int *BytesAdded) const { … }
bool PPCInstrInfo::canInsertSelect(const MachineBasicBlock &MBB,
ArrayRef<MachineOperand> Cond,
Register DstReg, Register TrueReg,
Register FalseReg, int &CondCycles,
int &TrueCycles, int &FalseCycles) const { … }
void PPCInstrInfo::insertSelect(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const DebugLoc &dl, Register DestReg,
ArrayRef<MachineOperand> Cond, Register TrueReg,
Register FalseReg) const { … }
static unsigned getCRBitValue(unsigned CRBit) { … }
void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
const DebugLoc &DL, MCRegister DestReg,
MCRegister SrcReg, bool KillSrc,
bool RenamableDest, bool RenamableSrc) const { … }
unsigned PPCInstrInfo::getSpillIndex(const TargetRegisterClass *RC) const { … }
unsigned
PPCInstrInfo::getStoreOpcodeForSpill(const TargetRegisterClass *RC) const { … }
unsigned
PPCInstrInfo::getLoadOpcodeForSpill(const TargetRegisterClass *RC) const { … }
void PPCInstrInfo::StoreRegToStackSlot(
MachineFunction &MF, unsigned SrcReg, bool isKill, int FrameIdx,
const TargetRegisterClass *RC,
SmallVectorImpl<MachineInstr *> &NewMIs) const { … }
void PPCInstrInfo::storeRegToStackSlotNoUpd(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg,
bool isKill, int FrameIdx, const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const { … }
void PPCInstrInfo::storeRegToStackSlot(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,
bool isKill, int FrameIdx, const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI, Register VReg) const { … }
void PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, const DebugLoc &DL,
unsigned DestReg, int FrameIdx,
const TargetRegisterClass *RC,
SmallVectorImpl<MachineInstr *> &NewMIs)
const { … }
void PPCInstrInfo::loadRegFromStackSlotNoUpd(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg,
int FrameIdx, const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const { … }
void PPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
Register DestReg, int FrameIdx,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI,
Register VReg) const { … }
bool PPCInstrInfo::
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { … }
bool PPCInstrInfo::onlyFoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
Register Reg) const { … }
bool PPCInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
Register Reg, MachineRegisterInfo *MRI) const { … }
static bool MBBDefinesCTR(MachineBasicBlock &MBB) { … }
bool PPCInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
unsigned NumT, unsigned ExtraT,
MachineBasicBlock &FMBB,
unsigned NumF, unsigned ExtraF,
BranchProbability Probability) const { … }
bool PPCInstrInfo::isPredicated(const MachineInstr &MI) const { … }
bool PPCInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const { … }
bool PPCInstrInfo::PredicateInstruction(MachineInstr &MI,
ArrayRef<MachineOperand> Pred) const { … }
bool PPCInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
ArrayRef<MachineOperand> Pred2) const { … }
bool PPCInstrInfo::ClobbersPredicate(MachineInstr &MI,
std::vector<MachineOperand> &Pred,
bool SkipDead) const { … }
bool PPCInstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,
Register &SrcReg2, int64_t &Mask,
int64_t &Value) const { … }
bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
Register SrcReg2, int64_t Mask,
int64_t Value,
const MachineRegisterInfo *MRI) const { … }
bool PPCInstrInfo::optimizeCmpPostRA(MachineInstr &CmpMI) const { … }
bool PPCInstrInfo::getMemOperandsWithOffsetWidth(
const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,
int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
const TargetRegisterInfo *TRI) const { … }
static bool isLdStSafeToCluster(const MachineInstr &LdSt,
const TargetRegisterInfo *TRI) { … }
static bool isClusterableLdStOpcPair(unsigned FirstOpc, unsigned SecondOpc,
const PPCSubtarget &Subtarget) { … }
bool PPCInstrInfo::shouldClusterMemOps(
ArrayRef<const MachineOperand *> BaseOps1, int64_t OpOffset1,
bool OffsetIsScalable1, ArrayRef<const MachineOperand *> BaseOps2,
int64_t OpOffset2, bool OffsetIsScalable2, unsigned ClusterSize,
unsigned NumBytes) const { … }
unsigned PPCInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { … }
std::pair<unsigned, unsigned>
PPCInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const { … }
ArrayRef<std::pair<unsigned, const char *>>
PPCInstrInfo::getSerializableDirectMachineOperandTargetFlags() const { … }
bool PPCInstrInfo::expandVSXMemPseudo(MachineInstr &MI) const { … }
static bool isAnImmediateOperand(const MachineOperand &MO) { … }
bool PPCInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { … }
static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc,
unsigned TrueReg, unsigned FalseReg,
unsigned CRSubReg) { … }
void PPCInstrInfo::replaceInstrOperandWithImm(MachineInstr &MI,
unsigned OpNo,
int64_t Imm) const { … }
void PPCInstrInfo::replaceInstrWithLI(MachineInstr &MI,
const LoadImmediateInfo &LII) const { … }
MachineInstr *PPCInstrInfo::getDefMIPostRA(unsigned Reg, MachineInstr &MI,
bool &SeenIntermediateUse) const { … }
void PPCInstrInfo::materializeImmPostRA(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, Register Reg,
int64_t Imm) const { … }
MachineInstr *PPCInstrInfo::getForwardingDefMI(
MachineInstr &MI,
unsigned &OpNoForForwarding,
bool &SeenIntermediateUse) const { … }
unsigned PPCInstrInfo::getSpillTarget() const { … }
ArrayRef<unsigned> PPCInstrInfo::getStoreOpcodesForSpillArray() const { … }
ArrayRef<unsigned> PPCInstrInfo::getLoadOpcodesForSpillArray() const { … }
bool PPCInstrInfo::foldFrameOffset(MachineInstr &MI) const { … }
bool PPCInstrInfo::isADDIInstrEligibleForFolding(MachineInstr &ADDIMI,
int64_t &Imm) const { … }
bool PPCInstrInfo::isADDInstrEligibleForFolding(MachineInstr &ADDMI) const { … }
bool PPCInstrInfo::isImmInstrEligibleForFolding(MachineInstr &MI,
unsigned &ToBeDeletedReg,
unsigned &XFormOpcode,
int64_t &OffsetImm,
ImmInstrInfo &III) const { … }
bool PPCInstrInfo::isValidToBeChangedReg(MachineInstr *ADDMI, unsigned Index,
MachineInstr *&ADDIMI,
int64_t &OffsetAddi,
int64_t OffsetImm) const { … }
bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
SmallSet<Register, 4> &RegsToUpdate,
MachineInstr **KilledDef) const { … }
bool PPCInstrInfo::combineRLWINM(MachineInstr &MI,
MachineInstr **ToErase) const { … }
bool PPCInstrInfo::instrHasImmForm(unsigned Opc, bool IsVFReg,
ImmInstrInfo &III, bool PostRA) const { … }
static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2) { … }
bool PPCInstrInfo::isUseMIElgibleForForwarding(MachineInstr &MI,
const ImmInstrInfo &III,
unsigned OpNoForForwarding
) const { … }
bool PPCInstrInfo::isDefMIElgibleForForwarding(MachineInstr &DefMI,
const ImmInstrInfo &III,
MachineOperand *&ImmMO,
MachineOperand *&RegMO) const { … }
bool PPCInstrInfo::isRegElgibleForForwarding(
const MachineOperand &RegMO, const MachineInstr &DefMI,
const MachineInstr &MI, bool KillDefMI,
bool &IsFwdFeederRegKilled, bool &SeenIntermediateUse) const { … }
bool PPCInstrInfo::isImmElgibleForForwarding(const MachineOperand &ImmMO,
const MachineInstr &DefMI,
const ImmInstrInfo &III,
int64_t &Imm,
int64_t BaseImm) const { … }
bool PPCInstrInfo::simplifyToLI(MachineInstr &MI, MachineInstr &DefMI,
unsigned OpNoForForwarding,
MachineInstr **KilledDef) const { … }
bool PPCInstrInfo::transformToNewImmFormFedByAdd(
MachineInstr &MI, MachineInstr &DefMI, unsigned OpNoForForwarding) const { … }
bool PPCInstrInfo::transformToImmFormFedByAdd(
MachineInstr &MI, const ImmInstrInfo &III, unsigned OpNoForForwarding,
MachineInstr &DefMI, bool KillDefMI) const { … }
bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,
const ImmInstrInfo &III,
unsigned ConstantOpNo,
MachineInstr &DefMI) const { … }
const TargetRegisterClass *
PPCInstrInfo::updatedRC(const TargetRegisterClass *RC) const { … }
int PPCInstrInfo::getRecordFormOpcode(unsigned Opcode) { … }
static bool isOpZeroOfSubwordPreincLoad(int Opcode) { … }
static bool definedBySignExtendingOp(const unsigned Reg,
const MachineRegisterInfo *MRI) { … }
static bool definedByZeroExtendingOp(const unsigned Reg,
const MachineRegisterInfo *MRI) { … }
bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const { … }
const unsigned MAX_BINOP_DEPTH = …;
std::pair<bool, bool>
PPCInstrInfo::isSignOrZeroExtended(const unsigned Reg,
const unsigned BinOpDepth,
const MachineRegisterInfo *MRI) const { … }
bool PPCInstrInfo::isBDNZ(unsigned Opcode) const { … }
namespace {
class PPCPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo { … };
}
std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
PPCInstrInfo::analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const { … }
MachineInstr *PPCInstrInfo::findLoopInstr(
MachineBasicBlock &PreHeader,
SmallPtrSet<MachineBasicBlock *, 8> &Visited) const { … }
bool PPCInstrInfo::getMemOperandWithOffsetWidth(
const MachineInstr &LdSt, const MachineOperand *&BaseReg, int64_t &Offset,
LocationSize &Width, const TargetRegisterInfo *TRI) const { … }
bool PPCInstrInfo::areMemAccessesTriviallyDisjoint(
const MachineInstr &MIa, const MachineInstr &MIb) const { … }