26 typedef SmallDenseSet<unsigned> FusionOpSet;
29 #define FUSION_KIND(KIND) FK_##KIND
30 #define FUSION_FEATURE(KIND, HAS_FEATURE, DEP_OP_IDX, OPSET1, OPSET2) \
32 #include "PPCMacroFusion.def"
51 FusionFeature(FusionKind Kind,
bool HasFeature,
int Index,
52 const FusionOpSet &
First,
const FusionOpSet &Second) :
56 bool hasOp1(
unsigned Opc)
const {
return OpSet1.contains(
Opc); }
57 bool hasOp2(
unsigned Opc)
const {
return OpSet2.contains(
Opc); }
58 bool isSupported()
const {
return Supported; }
59 std::optional<unsigned> depOpIdx()
const {
65 FusionKind getKind()
const {
return Kd; }
71 int SecondMIOpIndex) {
83 unsigned ExtendFrom = 64) {
87 int64_t
Imm =
Op.getImm();
95static bool checkOpConstraints(FusionFeature::FusionKind Kd,
101 default:
return true;
103 case FusionFeature::FK_AddiLoad: {
109 return RA.getReg().isVirtual() ||
110 (
RA.getReg() != PPC::ZERO &&
RA.getReg() != PPC::ZERO8);
113 case FusionFeature::FK_AddisLoad: {
122 if (!matchingRegOps(SecondMI, 0, SecondMI, 2) ||
123 (RT.
getReg() == PPC::ZERO || RT.
getReg() == PPC::ZERO8))
130 int64_t
Imm =
SI.getImm();
131 if (((Imm & 0xFFF0) != 0) && ((Imm & 0xFFF0) != 0xFFF0))
136 if ((Imm & 0xFFF0) == 0xFFF0) {
146 return (
D.getImm() & (1ULL << MSB)) == 0;
151 case FusionFeature::FK_SldiAdd:
152 return (matchingImmOps(FirstMI, 2, 3) && matchingImmOps(FirstMI, 3, 60)) ||
153 (matchingImmOps(FirstMI, 2, 6) && matchingImmOps(FirstMI, 3, 57));
156 case FusionFeature::FK_RotateLeftXor:
157 return matchingImmOps(FirstMI, 2, 1) && matchingImmOps(FirstMI, 3, 0);
160 case FusionFeature::FK_RotateRightXor:
161 return matchingImmOps(FirstMI, 2, 1) && matchingImmOps(FirstMI, 3, 63);
167 case FusionFeature::FK_LoadCmp1:
170 case FusionFeature::FK_LoadCmp2: {
172 if (!
BT.isReg() || (!
BT.getReg().isVirtual() &&
BT.getReg() != PPC::CR0))
174 if (SecondMI.
getOpcode() == PPC::CMPDI &&
175 matchingImmOps(SecondMI, 2, -1, 16))
177 return matchingImmOps(SecondMI, 2, 0) || matchingImmOps(SecondMI, 2, 1);
181 case FusionFeature::FK_LoadCmp3: {
183 if (!
BT.isReg() || (!
BT.getReg().isVirtual() &&
BT.getReg() != PPC::CR0))
185 return matchingImmOps(SecondMI, 2, 0) || matchingImmOps(SecondMI, 2, 1) ||
186 matchingImmOps(SecondMI, 2, -1, 16);
190 case FusionFeature::FK_ZeroMoveCTR:
192 return (FirstMI.
getOpcode() != PPC::MTSPR &&
194 matchingImmOps(FirstMI, 0, 9);
197 case FusionFeature::FK_ZeroMoveLR:
199 return (FirstMI.
getOpcode() != PPC::MTSPR &&
201 matchingImmOps(FirstMI, 0, 8);
204 case FusionFeature::FK_AddisAddi: {
207 if (!
SI.isImm() || !
RA.isReg())
209 if (
RA.getReg() == PPC::ZERO ||
RA.getReg() == PPC::ZERO8)
215 case FusionFeature::FK_AddiAddis: {
218 if (!
SI.isImm() || !
RA.isReg())
220 if (
RA.getReg() == PPC::ZERO ||
RA.getReg() == PPC::ZERO8)
223 return ExtendedSI >= 2;
243 static const FusionFeature FusionFeatures[] = {
244 #define FUSION_FEATURE(KIND, HAS_FEATURE, DEP_OP_IDX, OPSET1, OPSET2) { \
245 FusionFeature::FUSION_KIND(KIND), ST.HAS_FEATURE(), DEP_OP_IDX, { OPSET1 },\
247 #include "PPCMacroFusion.def"
251 for (
auto &Feature : FusionFeatures) {
253 if (!Feature.isSupported())
258 if (Feature.hasOp2(SecondMI.
getOpcode())) {
265 if (!Feature.hasOp1(FirstMI->
getOpcode()))
268 auto DepOpIdx = Feature.depOpIdx();
272 if (!matchingRegOps(*FirstMI, 0, SecondMI, *DepOpIdx))
277 if (checkOpConstraints(Feature.getKind(), *FirstMI, SecondMI))
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file defines the DenseSet and SmallDenseSet classes.
const HexagonInstrInfo * TII
#define FUSION_KIND(KIND)
SI optimize exec mask operations pre RA
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
TargetInstrInfo - Interface to description of machine instruction set.
TargetSubtargetInfo - Generic base class for all target subtargets.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Define some predicates that are used for node matching.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::unique_ptr< ScheduleDAGMutation > createMacroFusionDAGMutation(ArrayRef< MacroFusionPredTy > Predicates, bool BranchOnly=false)
Create a DAG scheduling mutation to pair instructions back to back for instructions that benefit acco...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
DWARFExpression::Operation Op
std::unique_ptr< ScheduleDAGMutation > createPowerPCMacroFusionDAGMutation()
Note that you have to add: DAG.addMutation(createPowerPCMacroFusionDAGMutation()); to PPCTargetMachin...
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool shouldScheduleAdjacent(const TargetInstrInfo &TII, const TargetSubtargetInfo &TSI, const MachineInstr *FirstMI, const MachineInstr &SecondMI)
Check if the instr pair, FirstMI and SecondMI, should be fused together.