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 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.
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
This class represents an Operation in the Expression.
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.
Implements a dense probed hash-table based set with some number of buckets stored inline.
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.
This is an optimization pass for GlobalISel generic memory operations.
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.
std::unique_ptr< ScheduleDAGMutation > createPowerPCMacroFusionDAGMutation()
Note that you have to add: DAG.addMutation(createPowerPCMacroFusionDAGMutation()); to PPCPassConfig::...
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.