Index: lib/Target/AArch64/AArch64InstrInfo.h =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.h +++ lib/Target/AArch64/AArch64InstrInfo.h @@ -70,9 +70,6 @@ /// value is non-zero. static bool hasExtendedReg(const MachineInstr &MI); - /// Does this instruction set its full destination register to zero? - static bool isGPRZero(const MachineInstr &MI); - /// Does this instruction rename a GPR without modifying bits? static bool isGPRCopy(const MachineInstr &MI); Index: lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.cpp +++ lib/Target/AArch64/AArch64InstrInfo.cpp @@ -1713,30 +1713,6 @@ return false; } -// Return true if this instruction simply sets its single destination register -// to zero. This is equivalent to a register rename of the zero-register. -bool AArch64InstrInfo::isGPRZero(const MachineInstr &MI) { - switch (MI.getOpcode()) { - default: - break; - case AArch64::MOVZWi: - case AArch64::MOVZXi: // movz Rd, #0 (LSL #0) - if (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) { - assert(MI.getDesc().getNumOperands() == 3 && - MI.getOperand(2).getImm() == 0 && "invalid MOVZi operands"); - return true; - } - break; - case AArch64::ANDWri: // and Rd, Rzr, #imm - return MI.getOperand(1).getReg() == AArch64::WZR; - case AArch64::ANDXri: - return MI.getOperand(1).getReg() == AArch64::XZR; - case TargetOpcode::COPY: - return MI.getOperand(1).getReg() == AArch64::WZR; - } - return false; -} - // Return true if this instruction simply renames a general register without // modifying bits. bool AArch64InstrInfo::isGPRCopy(const MachineInstr &MI) { Index: lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.td +++ lib/Target/AArch64/AArch64InstrInfo.td @@ -6324,3 +6324,5 @@ include "AArch64InstrAtomics.td" include "AArch64SVEInstrInfo.td" + +include "AArch64InstrInfoPredicates.td" Index: lib/Target/AArch64/AArch64InstrInfoPredicates.td =================================================================== --- lib/Target/AArch64/AArch64InstrInfoPredicates.td +++ lib/Target/AArch64/AArch64InstrInfoPredicates.td @@ -0,0 +1,33 @@ +// IsGPRZero. + +def CheckMOVZ : CheckAllOf<[ + CheckOpcode<[MOVZWi, MOVZXi]>, + CheckNumOperands<3>, + CheckImmOperand<1>, + CheckZeroOperand<1>, + CheckImmOperand<2>, + CheckZeroOperand<2> +]>; + +def CheckANDW : CheckAllOf<[ + CheckOpcode<[ANDWri]>, + CheckRegOperand<1>, + CheckRegOperandValue<1, WZR> +]>; + +def CheckANDX : CheckAllOf<[ + CheckOpcode<[ANDXri]>, + CheckRegOperand<1>, + CheckRegOperandValue<1, XZR> +]>; + +def CheckCOPY : CheckAllOf<[ + CheckPseudo<[COPY]>, + CheckRegOperand<1>, + CheckRegOperandValue<1, WZR> +]>; + +// Return true if this instruction simply sets its single destination register +// to zero. This is equivalent to a register rename of the zero-register. +def IsGPRZero : TIIPredicate<"AArch64", "isGPRZero", + CheckAnyOf<[CheckMOVZ, CheckANDW, CheckANDX, CheckCOPY]>>; Index: lib/Target/AArch64/AArch64SchedCyclone.td =================================================================== --- lib/Target/AArch64/AArch64SchedCyclone.td +++ lib/Target/AArch64/AArch64SchedCyclone.td @@ -110,10 +110,13 @@ // The move is replaced by a single nop micro-op. // MOVZ Rd, #0 // AND Rd, Rzr, #imm -def WriteZPred : SchedPredicate<[{TII->isGPRZero(*MI)}]>; -def WriteImmZ : SchedWriteVariant<[ - SchedVar, - SchedVar]>; + +def WriteZPred : MCSchedPredicate; + +def WriteImmZ : SchedWriteVariant<[ + SchedVar, + SchedVar]>; + def : InstRW<[WriteImmZ], (instrs MOVZWi,MOVZXi,ANDWri,ANDXri)>; // Move GPR is a register rename and single nop micro-op. Index: lib/Target/AArch64/AArch64SchedExynosM3.td =================================================================== --- lib/Target/AArch64/AArch64SchedExynosM3.td +++ lib/Target/AArch64/AArch64SchedExynosM3.td @@ -109,9 +109,13 @@ //===----------------------------------------------------------------------===// // Predicates. -def M3BranchLinkFastPred : SchedPredicate<[{MI->getOpcode() == AArch64::BLR && - MI->getOperand(0).isReg() && - MI->getOperand(0).getReg() != AArch64::LR}]>; +def M3BranchLinkFastPred : MCSchedPredicate< + CheckAllOf<[ + CheckOpcode<[BLR]>, + CheckRegOperand<0>, + CheckNot>]> + >; + def M3ResetFastPred : SchedPredicate<[{TII->isExynosResetFast(*MI)}]>; def M3RotateRightFastPred : SchedPredicate<[{(MI->getOpcode() == AArch64::EXTRWrri || MI->getOpcode() == AArch64::EXTRXrri) && @@ -148,7 +152,7 @@ def M3WriteB1 : SchedWriteRes<[M3UnitB]> { let Latency = 1; } def M3WriteBX : SchedWriteVariant<[SchedVar, - SchedVar]>; + SchedVar]>; def M3WriteL4 : SchedWriteRes<[M3UnitL]> { let Latency = 4; } def M3WriteL5 : SchedWriteRes<[M3UnitL]> { let Latency = 5; } Index: lib/Target/AArch64/AArch64Schedule.td =================================================================== --- lib/Target/AArch64/AArch64Schedule.td +++ lib/Target/AArch64/AArch64Schedule.td @@ -104,3 +104,6 @@ // Store a shuffled vector. def WriteVSTShuffle : WriteSequence<[WriteV, WriteVST]>; def WriteVSTPairShuffle : WriteSequence<[WriteV, WriteV, WriteVST]>; + +// Predicates that are common to all AArch64 processor models. +def SchedDefault : MCSchedPredicate; Index: lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h +++ lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h @@ -89,6 +89,9 @@ #define GET_INSTRINFO_ENUM #include "AArch64GenInstrInfo.inc" +#define GET_GENINSTRINFO_MC_DECL +#include "AArch64GenInstrInfo.inc" + #define GET_SUBTARGETINFO_ENUM #include "AArch64GenSubtargetInfo.inc" Index: lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp @@ -31,6 +31,9 @@ #define GET_INSTRINFO_MC_DESC #include "AArch64GenInstrInfo.inc" +#define GET_GENINSTRINFO_MC_HELPERS +#include "AArch64GenInstrInfo.inc" + #define GET_SUBTARGETINFO_MC_DESC #include "AArch64GenSubtargetInfo.inc"