003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/Target/PowerPC
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
Target
/
PowerPC
/
📁
..
📁
AsmParser
📁
Disassembler
📁
MCTargetDesc
📄
P9InstrResources.td
(37.36 KB)
📄
PPC.h
(4.69 KB)
📄
PPC.td
(32.37 KB)
📄
PPCAsmPrinter.cpp
(70.77 KB)
📄
PPCBoolRetToInt.cpp
(9.97 KB)
📄
PPCBranchCoalescing.cpp
(30.16 KB)
📄
PPCBranchSelector.cpp
(15.97 KB)
📄
PPCCCState.cpp
(1.08 KB)
📄
PPCCCState.h
(1.19 KB)
📄
PPCCTRLoops.cpp
(6.68 KB)
📄
PPCCallingConv.cpp
(6.19 KB)
📄
PPCCallingConv.h
(1.97 KB)
📄
PPCCallingConv.td
(16.32 KB)
📄
PPCEarlyReturn.cpp
(7.14 KB)
📄
PPCExpandISEL.cpp
(17.93 KB)
📄
PPCFastISel.cpp
(85.51 KB)
📄
PPCFrameLowering.cpp
(98.6 KB)
📄
PPCFrameLowering.h
(7.46 KB)
📄
PPCHazardRecognizers.cpp
(14.02 KB)
📄
PPCHazardRecognizers.h
(3.83 KB)
📄
PPCISelDAGToDAG.cpp
(256.88 KB)
📄
PPCISelLowering.cpp
(669.73 KB)
📄
PPCISelLowering.h
(55.9 KB)
📄
PPCInstr64Bit.td
(75.68 KB)
📄
PPCInstrAltivec.td
(77.68 KB)
📄
PPCInstrBuilder.h
(1.5 KB)
📄
PPCInstrFormats.td
(57.38 KB)
📄
PPCInstrHTM.td
(5.48 KB)
📄
PPCInstrInfo.cpp
(171.06 KB)
📄
PPCInstrInfo.h
(29.06 KB)
📄
PPCInstrInfo.td
(233.39 KB)
📄
PPCInstrPrefix.td
(41.72 KB)
📄
PPCInstrQPX.td
(57.56 KB)
📄
PPCInstrSPE.td
(49.71 KB)
📄
PPCInstrVSX.td
(223.48 KB)
📄
PPCLoopInstrFormPrep.cpp
(33.45 KB)
📄
PPCLowerMASSVEntries.cpp
(6.42 KB)
📄
PPCMCInstLower.cpp
(6.62 KB)
📄
PPCMIPeephole.cpp
(63.48 KB)
📄
PPCMachineFunctionInfo.cpp
(2.59 KB)
📄
PPCMachineFunctionInfo.h
(9.15 KB)
📄
PPCMachineScheduler.cpp
(4.03 KB)
📄
PPCMachineScheduler.h
(1.81 KB)
📄
PPCMacroFusion.cpp
(6.68 KB)
📄
PPCMacroFusion.def
(1.8 KB)
📄
PPCMacroFusion.h
(886 B)
📄
PPCPerfectShuffle.h
(397.57 KB)
📄
PPCPfmCounters.td
(705 B)
📄
PPCPreEmitPeephole.cpp
(13.36 KB)
📄
PPCQPXLoadSplat.cpp
(5.31 KB)
📄
PPCReduceCRLogicals.cpp
(28.66 KB)
📄
PPCRegisterInfo.cpp
(51.93 KB)
📄
PPCRegisterInfo.h
(6.61 KB)
📄
PPCRegisterInfo.td
(14.24 KB)
📄
PPCSchedule.td
(5.21 KB)
📄
PPCSchedule440.td
(34.57 KB)
📄
PPCScheduleA2.td
(7.85 KB)
📄
PPCScheduleE500.td
(16.59 KB)
📄
PPCScheduleE500mc.td
(20.89 KB)
📄
PPCScheduleE5500.td
(23.62 KB)
📄
PPCScheduleG3.td
(4.49 KB)
📄
PPCScheduleG4.td
(5.42 KB)
📄
PPCScheduleG4Plus.td
(6.45 KB)
📄
PPCScheduleG5.td
(7.1 KB)
📄
PPCScheduleP7.td
(22.26 KB)
📄
PPCScheduleP8.td
(23.96 KB)
📄
PPCScheduleP9.td
(12.27 KB)
📄
PPCSubtarget.cpp
(7.58 KB)
📄
PPCSubtarget.h
(13.21 KB)
📄
PPCTLSDynamicCall.cpp
(6.53 KB)
📄
PPCTOCRegDeps.cpp
(5.3 KB)
📄
PPCTargetMachine.cpp
(18.94 KB)
📄
PPCTargetMachine.h
(2.2 KB)
📄
PPCTargetObjectFile.cpp
(2.45 KB)
📄
PPCTargetObjectFile.h
(1.19 KB)
📄
PPCTargetStreamer.h
(1.02 KB)
📄
PPCTargetTransformInfo.cpp
(38.72 KB)
📄
PPCTargetTransformInfo.h
(5.6 KB)
📄
PPCVSXCopy.cpp
(5.68 KB)
📄
PPCVSXFMAMutate.cpp
(15.12 KB)
📄
PPCVSXSwapRemoval.cpp
(36.78 KB)
📄
README_P9.txt
(22.25 KB)
📁
TargetInfo
Editing: PPCMacroFusion.cpp
//===- PPCMacroFusion.cpp - PowerPC Macro Fusion --------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // /// \file This file contains the PowerPC implementation of the DAG scheduling /// mutation to pair instructions back to back. // //===----------------------------------------------------------------------===// #include "PPC.h" #include "PPCSubtarget.h" #include "llvm/ADT/DenseSet.h" #include "llvm/CodeGen/MacroFusion.h" using namespace llvm; namespace { class FusionFeature { public: typedef SmallDenseSet<unsigned> FusionOpSet; enum FusionKind { #define FUSION_KIND(KIND) FK_##KIND #define FUSION_FEATURE(KIND, HAS_FEATURE, DEP_OP_IDX, OPSET1, OPSET2) \ FUSION_KIND(KIND), #include "PPCMacroFusion.def" FUSION_KIND(END) }; private: // Each fusion feature is assigned with one fusion kind. All the // instructions with the same fusion kind have the same fusion characteristic. FusionKind Kd; // True if this feature is enabled. bool Supported; // li rx, si // load rt, ra, rx // The dependent operand index in the second op(load). And the negative means // it could be any one. int DepOpIdx; // The first fusion op set. FusionOpSet OpSet1; // The second fusion op set. FusionOpSet OpSet2; public: FusionFeature(FusionKind Kind, bool HasFeature, int Index, const FusionOpSet &First, const FusionOpSet &Second) : Kd(Kind), Supported(HasFeature), DepOpIdx(Index), OpSet1(First), OpSet2(Second) {} bool hasOp1(unsigned Opc) const { return OpSet1.count(Opc) != 0; } bool hasOp2(unsigned Opc) const { return OpSet2.count(Opc) != 0; } bool isSupported() const { return Supported; } Optional<unsigned> depOpIdx() const { if (DepOpIdx < 0) return None; return DepOpIdx; } FusionKind getKind() const { return Kd; } }; static bool matchingRegOps(const MachineInstr &FirstMI, int FirstMIOpIndex, const MachineInstr &SecondMI, int SecondMIOpIndex) { const MachineOperand &Op1 = FirstMI.getOperand(FirstMIOpIndex); const MachineOperand &Op2 = SecondMI.getOperand(SecondMIOpIndex); if (!Op1.isReg() || !Op2.isReg()) return false; return Op1.getReg() == Op2.getReg(); } // Return true if the FirstMI meets the constraints of SecondMI according to // fusion specification. static bool checkOpConstraints(FusionFeature::FusionKind Kd, const MachineInstr &FirstMI, const MachineInstr &SecondMI) { switch (Kd) { // The hardware didn't require any specific check for the fused instructions' // operands. Therefore, return true to indicate that, it is fusable. default: return true; // [addi rt,ra,si - lxvd2x xt,ra,rb] etc. case FusionFeature::FK_AddiLoad: { // lxvd2x(ra) cannot be zero const MachineOperand &RA = SecondMI.getOperand(1); if (!RA.isReg()) return true; return Register::isVirtualRegister(RA.getReg()) || (RA.getReg() != PPC::ZERO && RA.getReg() != PPC::ZERO8); } // [addis rt,ra,si - ld rt,ds(ra)] etc. case FusionFeature::FK_AddisLoad: { const MachineOperand &RT = SecondMI.getOperand(0); if (!RT.isReg()) return true; // Only check it for non-virtual register. if (!Register::isVirtualRegister(RT.getReg())) // addis(rt) = ld(ra) = ld(rt) // ld(rt) cannot be zero if (!matchingRegOps(SecondMI, 0, SecondMI, 2) || (RT.getReg() == PPC::ZERO || RT.getReg() == PPC::ZERO8)) return false; // addis(si) first 12 bits must be all 1s or all 0s const MachineOperand &SI = FirstMI.getOperand(2); if (!SI.isImm()) return true; int64_t Imm = SI.getImm(); if (((Imm & 0xFFF0) != 0) && ((Imm & 0xFFF0) != 0xFFF0)) return false; // If si = 1111111111110000 and the msb of the d/ds field of the load equals // 1, then fusion does not occur. if ((Imm & 0xFFF0) == 0xFFF0) { const MachineOperand &D = SecondMI.getOperand(1); if (!D.isImm()) return true; // 14 bit for DS field, while 16 bit for D field. int MSB = 15; if (SecondMI.getOpcode() == PPC::LD) MSB = 13; return (D.getImm() & (1ULL << MSB)) == 0; } return true; } } llvm_unreachable("All the cases should have been handled"); return true; } /// Check if the instr pair, FirstMI and SecondMI, should be fused together. /// Given SecondMI, when FirstMI is unspecified, then check if SecondMI may be /// part of a fused pair at all. static bool shouldScheduleAdjacent(const TargetInstrInfo &TII, const TargetSubtargetInfo &TSI, const MachineInstr *FirstMI, const MachineInstr &SecondMI) { // We use the PPC namespace to avoid the need to prefix opcodes with PPC:: in // the def file. using namespace PPC; const PPCSubtarget &ST = static_cast<const PPCSubtarget&>(TSI); static const FusionFeature FusionFeatures[] = { #define FUSION_FEATURE(KIND, HAS_FEATURE, DEP_OP_IDX, OPSET1, OPSET2) { \ FusionFeature::FUSION_KIND(KIND), ST.HAS_FEATURE(), DEP_OP_IDX, { OPSET1 },\ { OPSET2 } }, #include "PPCMacroFusion.def" }; #undef FUSION_KIND for (auto &Feature : FusionFeatures) { // Skip if the feature is not supported. if (!Feature.isSupported()) continue; // Only when the SecondMI is fusable, we are starting to look for the // fusable FirstMI. if (Feature.hasOp2(SecondMI.getOpcode())) { // If FirstMI == nullptr, that means, we're only checking whether SecondMI // can be fused at all. if (!FirstMI) return true; // Checking if the FirstMI is fusable with the SecondMI. if (!Feature.hasOp1(FirstMI->getOpcode())) continue; auto DepOpIdx = Feature.depOpIdx(); if (DepOpIdx.hasValue()) { // Checking if the result of the FirstMI is the desired operand of the // SecondMI if the DepOpIdx is set. Otherwise, ignore it. if (!matchingRegOps(*FirstMI, 0, SecondMI, *DepOpIdx)) return false; } // Checking more on the instruction operands. if (checkOpConstraints(Feature.getKind(), *FirstMI, SecondMI)) return true; } } return false; } } // end anonymous namespace namespace llvm { std::unique_ptr<ScheduleDAGMutation> createPowerPCMacroFusionDAGMutation () { return createMacroFusionDAGMutation(shouldScheduleAdjacent); } } // end namespace llvm
Upload File
Create Folder