10b57cec5SDimitry Andric //===-- SystemZShortenInst.cpp - Instruction-shortening pass --------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This pass tries to replace instructions with shorter forms. For example, 100b57cec5SDimitry Andric // IILF can be replaced with LLILL or LLILH if the constant fits and if the 110b57cec5SDimitry Andric // other 32 bits of the GR64 destination are not live. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "SystemZTargetMachine.h" 16*0fca6ea1SDimitry Andric #include "llvm/CodeGen/LiveRegUnits.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric using namespace llvm; 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric #define DEBUG_TYPE "systemz-shorten-inst" 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric namespace { 260b57cec5SDimitry Andric class SystemZShortenInst : public MachineFunctionPass { 270b57cec5SDimitry Andric public: 280b57cec5SDimitry Andric static char ID; 2904eeddc0SDimitry Andric SystemZShortenInst(); 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric bool processBlock(MachineBasicBlock &MBB); 320b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &F) override; 330b57cec5SDimitry Andric MachineFunctionProperties getRequiredProperties() const override { 340b57cec5SDimitry Andric return MachineFunctionProperties().set( 350b57cec5SDimitry Andric MachineFunctionProperties::Property::NoVRegs); 360b57cec5SDimitry Andric } 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric private: 390b57cec5SDimitry Andric bool shortenIIF(MachineInstr &MI, unsigned LLIxL, unsigned LLIxH); 400b57cec5SDimitry Andric bool shortenOn0(MachineInstr &MI, unsigned Opcode); 410b57cec5SDimitry Andric bool shortenOn01(MachineInstr &MI, unsigned Opcode); 420b57cec5SDimitry Andric bool shortenOn001(MachineInstr &MI, unsigned Opcode); 430b57cec5SDimitry Andric bool shortenOn001AddCC(MachineInstr &MI, unsigned Opcode); 440b57cec5SDimitry Andric bool shortenFPConv(MachineInstr &MI, unsigned Opcode); 455ffd83dbSDimitry Andric bool shortenFusedFPOp(MachineInstr &MI, unsigned Opcode); 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric const SystemZInstrInfo *TII; 480b57cec5SDimitry Andric const TargetRegisterInfo *TRI; 49*0fca6ea1SDimitry Andric LiveRegUnits LiveRegs; 500b57cec5SDimitry Andric }; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric char SystemZShortenInst::ID = 0; 530b57cec5SDimitry Andric } // end anonymous namespace 540b57cec5SDimitry Andric 5504eeddc0SDimitry Andric INITIALIZE_PASS(SystemZShortenInst, DEBUG_TYPE, 5604eeddc0SDimitry Andric "SystemZ Instruction Shortening", false, false) 5704eeddc0SDimitry Andric 580b57cec5SDimitry Andric FunctionPass *llvm::createSystemZShortenInstPass(SystemZTargetMachine &TM) { 5904eeddc0SDimitry Andric return new SystemZShortenInst(); 600b57cec5SDimitry Andric } 610b57cec5SDimitry Andric 6204eeddc0SDimitry Andric SystemZShortenInst::SystemZShortenInst() 6304eeddc0SDimitry Andric : MachineFunctionPass(ID), TII(nullptr) { 6404eeddc0SDimitry Andric initializeSystemZShortenInstPass(*PassRegistry::getPassRegistry()); 6504eeddc0SDimitry Andric } 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric // Tie operands if MI has become a two-address instruction. 680b57cec5SDimitry Andric static void tieOpsIfNeeded(MachineInstr &MI) { 695ffd83dbSDimitry Andric if (MI.getDesc().getOperandConstraint(1, MCOI::TIED_TO) == 0 && 700b57cec5SDimitry Andric !MI.getOperand(0).isTied()) 710b57cec5SDimitry Andric MI.tieOperands(0, 1); 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric // MI loads one word of a GPR using an IIxF instruction and LLIxL and LLIxH 750b57cec5SDimitry Andric // are the halfword immediate loads for the same word. Try to use one of them 760b57cec5SDimitry Andric // instead of IIxF. 770b57cec5SDimitry Andric bool SystemZShortenInst::shortenIIF(MachineInstr &MI, unsigned LLIxL, 780b57cec5SDimitry Andric unsigned LLIxH) { 798bcb0991SDimitry Andric Register Reg = MI.getOperand(0).getReg(); 800b57cec5SDimitry Andric // The new opcode will clear the other half of the GR64 reg, so 810b57cec5SDimitry Andric // cancel if that is live. 820b57cec5SDimitry Andric unsigned thisSubRegIdx = 830b57cec5SDimitry Andric (SystemZ::GRH32BitRegClass.contains(Reg) ? SystemZ::subreg_h32 840b57cec5SDimitry Andric : SystemZ::subreg_l32); 850b57cec5SDimitry Andric unsigned otherSubRegIdx = 860b57cec5SDimitry Andric (thisSubRegIdx == SystemZ::subreg_l32 ? SystemZ::subreg_h32 870b57cec5SDimitry Andric : SystemZ::subreg_l32); 880b57cec5SDimitry Andric unsigned GR64BitReg = 890b57cec5SDimitry Andric TRI->getMatchingSuperReg(Reg, thisSubRegIdx, &SystemZ::GR64BitRegClass); 908bcb0991SDimitry Andric Register OtherReg = TRI->getSubReg(GR64BitReg, otherSubRegIdx); 91*0fca6ea1SDimitry Andric if (!LiveRegs.available(OtherReg)) 920b57cec5SDimitry Andric return false; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric uint64_t Imm = MI.getOperand(1).getImm(); 950b57cec5SDimitry Andric if (SystemZ::isImmLL(Imm)) { 960b57cec5SDimitry Andric MI.setDesc(TII->get(LLIxL)); 970b57cec5SDimitry Andric MI.getOperand(0).setReg(SystemZMC::getRegAsGR64(Reg)); 980b57cec5SDimitry Andric return true; 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric if (SystemZ::isImmLH(Imm)) { 1010b57cec5SDimitry Andric MI.setDesc(TII->get(LLIxH)); 1020b57cec5SDimitry Andric MI.getOperand(0).setReg(SystemZMC::getRegAsGR64(Reg)); 1030b57cec5SDimitry Andric MI.getOperand(1).setImm(Imm >> 16); 1040b57cec5SDimitry Andric return true; 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric return false; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric // Change MI's opcode to Opcode if register operand 0 has a 4-bit encoding. 1100b57cec5SDimitry Andric bool SystemZShortenInst::shortenOn0(MachineInstr &MI, unsigned Opcode) { 1110b57cec5SDimitry Andric if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16) { 1120b57cec5SDimitry Andric MI.setDesc(TII->get(Opcode)); 1130b57cec5SDimitry Andric return true; 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric return false; 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric // Change MI's opcode to Opcode if register operands 0 and 1 have a 1190b57cec5SDimitry Andric // 4-bit encoding. 1200b57cec5SDimitry Andric bool SystemZShortenInst::shortenOn01(MachineInstr &MI, unsigned Opcode) { 1210b57cec5SDimitry Andric if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 && 1220b57cec5SDimitry Andric SystemZMC::getFirstReg(MI.getOperand(1).getReg()) < 16) { 1230b57cec5SDimitry Andric MI.setDesc(TII->get(Opcode)); 1240b57cec5SDimitry Andric return true; 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric return false; 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric // Change MI's opcode to Opcode if register operands 0, 1 and 2 have a 1300b57cec5SDimitry Andric // 4-bit encoding and if operands 0 and 1 are tied. Also ties op 0 1310b57cec5SDimitry Andric // with op 1, if MI becomes 2-address. 1320b57cec5SDimitry Andric bool SystemZShortenInst::shortenOn001(MachineInstr &MI, unsigned Opcode) { 1330b57cec5SDimitry Andric if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 && 1340b57cec5SDimitry Andric MI.getOperand(1).getReg() == MI.getOperand(0).getReg() && 1350b57cec5SDimitry Andric SystemZMC::getFirstReg(MI.getOperand(2).getReg()) < 16) { 1360b57cec5SDimitry Andric MI.setDesc(TII->get(Opcode)); 1370b57cec5SDimitry Andric tieOpsIfNeeded(MI); 1380b57cec5SDimitry Andric return true; 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric return false; 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric // Calls shortenOn001 if CCLive is false. CC def operand is added in 1440b57cec5SDimitry Andric // case of success. 1450b57cec5SDimitry Andric bool SystemZShortenInst::shortenOn001AddCC(MachineInstr &MI, unsigned Opcode) { 146*0fca6ea1SDimitry Andric if (LiveRegs.available(SystemZ::CC) && shortenOn001(MI, Opcode)) { 1470b57cec5SDimitry Andric MachineInstrBuilder(*MI.getParent()->getParent(), &MI) 1480b57cec5SDimitry Andric .addReg(SystemZ::CC, RegState::ImplicitDefine | RegState::Dead); 1490b57cec5SDimitry Andric return true; 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric return false; 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric // MI is a vector-style conversion instruction with the operand order: 1550b57cec5SDimitry Andric // destination, source, exact-suppress, rounding-mode. If both registers 1560b57cec5SDimitry Andric // have a 4-bit encoding then change it to Opcode, which has operand order: 1570b57cec5SDimitry Andric // destination, rouding-mode, source, exact-suppress. 1580b57cec5SDimitry Andric bool SystemZShortenInst::shortenFPConv(MachineInstr &MI, unsigned Opcode) { 1590b57cec5SDimitry Andric if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 && 1600b57cec5SDimitry Andric SystemZMC::getFirstReg(MI.getOperand(1).getReg()) < 16) { 1610b57cec5SDimitry Andric MachineOperand Dest(MI.getOperand(0)); 1620b57cec5SDimitry Andric MachineOperand Src(MI.getOperand(1)); 1630b57cec5SDimitry Andric MachineOperand Suppress(MI.getOperand(2)); 1640b57cec5SDimitry Andric MachineOperand Mode(MI.getOperand(3)); 16581ad6265SDimitry Andric MI.removeOperand(3); 16681ad6265SDimitry Andric MI.removeOperand(2); 16781ad6265SDimitry Andric MI.removeOperand(1); 16881ad6265SDimitry Andric MI.removeOperand(0); 1690b57cec5SDimitry Andric MI.setDesc(TII->get(Opcode)); 1700b57cec5SDimitry Andric MachineInstrBuilder(*MI.getParent()->getParent(), &MI) 1710b57cec5SDimitry Andric .add(Dest) 1720b57cec5SDimitry Andric .add(Mode) 1730b57cec5SDimitry Andric .add(Src) 1740b57cec5SDimitry Andric .add(Suppress); 1750b57cec5SDimitry Andric return true; 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric return false; 1780b57cec5SDimitry Andric } 1790b57cec5SDimitry Andric 1805ffd83dbSDimitry Andric bool SystemZShortenInst::shortenFusedFPOp(MachineInstr &MI, unsigned Opcode) { 1815ffd83dbSDimitry Andric MachineOperand &DstMO = MI.getOperand(0); 1825ffd83dbSDimitry Andric MachineOperand &LHSMO = MI.getOperand(1); 1835ffd83dbSDimitry Andric MachineOperand &RHSMO = MI.getOperand(2); 1845ffd83dbSDimitry Andric MachineOperand &AccMO = MI.getOperand(3); 1855ffd83dbSDimitry Andric if (SystemZMC::getFirstReg(DstMO.getReg()) < 16 && 1865ffd83dbSDimitry Andric SystemZMC::getFirstReg(LHSMO.getReg()) < 16 && 1875ffd83dbSDimitry Andric SystemZMC::getFirstReg(RHSMO.getReg()) < 16 && 1885ffd83dbSDimitry Andric SystemZMC::getFirstReg(AccMO.getReg()) < 16 && 1895ffd83dbSDimitry Andric DstMO.getReg() == AccMO.getReg()) { 1905ffd83dbSDimitry Andric MachineOperand Lhs(LHSMO); 1915ffd83dbSDimitry Andric MachineOperand Rhs(RHSMO); 1925ffd83dbSDimitry Andric MachineOperand Src(AccMO); 19381ad6265SDimitry Andric MI.removeOperand(3); 19481ad6265SDimitry Andric MI.removeOperand(2); 19581ad6265SDimitry Andric MI.removeOperand(1); 1965ffd83dbSDimitry Andric MI.setDesc(TII->get(Opcode)); 1975ffd83dbSDimitry Andric MachineInstrBuilder(*MI.getParent()->getParent(), &MI) 1985ffd83dbSDimitry Andric .add(Src) 1995ffd83dbSDimitry Andric .add(Lhs) 2005ffd83dbSDimitry Andric .add(Rhs); 2015ffd83dbSDimitry Andric return true; 2025ffd83dbSDimitry Andric } 2035ffd83dbSDimitry Andric return false; 2045ffd83dbSDimitry Andric } 2055ffd83dbSDimitry Andric 2060b57cec5SDimitry Andric // Process all instructions in MBB. Return true if something changed. 2070b57cec5SDimitry Andric bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) { 2080b57cec5SDimitry Andric bool Changed = false; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric // Set up the set of live registers at the end of MBB (live out) 2110b57cec5SDimitry Andric LiveRegs.clear(); 2120b57cec5SDimitry Andric LiveRegs.addLiveOuts(MBB); 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric // Iterate backwards through the block looking for instructions to change. 215349cc55cSDimitry Andric for (MachineInstr &MI : llvm::reverse(MBB)) { 2160b57cec5SDimitry Andric switch (MI.getOpcode()) { 2170b57cec5SDimitry Andric case SystemZ::IILF: 2180b57cec5SDimitry Andric Changed |= shortenIIF(MI, SystemZ::LLILL, SystemZ::LLILH); 2190b57cec5SDimitry Andric break; 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric case SystemZ::IIHF: 2220b57cec5SDimitry Andric Changed |= shortenIIF(MI, SystemZ::LLIHL, SystemZ::LLIHH); 2230b57cec5SDimitry Andric break; 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric case SystemZ::WFADB: 2260b57cec5SDimitry Andric Changed |= shortenOn001AddCC(MI, SystemZ::ADBR); 2270b57cec5SDimitry Andric break; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric case SystemZ::WFASB: 2300b57cec5SDimitry Andric Changed |= shortenOn001AddCC(MI, SystemZ::AEBR); 2310b57cec5SDimitry Andric break; 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric case SystemZ::WFDDB: 2340b57cec5SDimitry Andric Changed |= shortenOn001(MI, SystemZ::DDBR); 2350b57cec5SDimitry Andric break; 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric case SystemZ::WFDSB: 2380b57cec5SDimitry Andric Changed |= shortenOn001(MI, SystemZ::DEBR); 2390b57cec5SDimitry Andric break; 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric case SystemZ::WFIDB: 2420b57cec5SDimitry Andric Changed |= shortenFPConv(MI, SystemZ::FIDBRA); 2430b57cec5SDimitry Andric break; 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric case SystemZ::WFISB: 2460b57cec5SDimitry Andric Changed |= shortenFPConv(MI, SystemZ::FIEBRA); 2470b57cec5SDimitry Andric break; 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric case SystemZ::WLDEB: 2500b57cec5SDimitry Andric Changed |= shortenOn01(MI, SystemZ::LDEBR); 2510b57cec5SDimitry Andric break; 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric case SystemZ::WLEDB: 2540b57cec5SDimitry Andric Changed |= shortenFPConv(MI, SystemZ::LEDBRA); 2550b57cec5SDimitry Andric break; 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric case SystemZ::WFMDB: 2580b57cec5SDimitry Andric Changed |= shortenOn001(MI, SystemZ::MDBR); 2590b57cec5SDimitry Andric break; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric case SystemZ::WFMSB: 2620b57cec5SDimitry Andric Changed |= shortenOn001(MI, SystemZ::MEEBR); 2630b57cec5SDimitry Andric break; 2640b57cec5SDimitry Andric 2655ffd83dbSDimitry Andric case SystemZ::WFMADB: 2665ffd83dbSDimitry Andric Changed |= shortenFusedFPOp(MI, SystemZ::MADBR); 2675ffd83dbSDimitry Andric break; 2685ffd83dbSDimitry Andric 2695ffd83dbSDimitry Andric case SystemZ::WFMASB: 2705ffd83dbSDimitry Andric Changed |= shortenFusedFPOp(MI, SystemZ::MAEBR); 2715ffd83dbSDimitry Andric break; 2725ffd83dbSDimitry Andric 2735ffd83dbSDimitry Andric case SystemZ::WFMSDB: 2745ffd83dbSDimitry Andric Changed |= shortenFusedFPOp(MI, SystemZ::MSDBR); 2755ffd83dbSDimitry Andric break; 2765ffd83dbSDimitry Andric 2775ffd83dbSDimitry Andric case SystemZ::WFMSSB: 2785ffd83dbSDimitry Andric Changed |= shortenFusedFPOp(MI, SystemZ::MSEBR); 2795ffd83dbSDimitry Andric break; 2805ffd83dbSDimitry Andric 2810b57cec5SDimitry Andric case SystemZ::WFLCDB: 2820b57cec5SDimitry Andric Changed |= shortenOn01(MI, SystemZ::LCDFR); 2830b57cec5SDimitry Andric break; 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric case SystemZ::WFLCSB: 2860b57cec5SDimitry Andric Changed |= shortenOn01(MI, SystemZ::LCDFR_32); 2870b57cec5SDimitry Andric break; 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric case SystemZ::WFLNDB: 2900b57cec5SDimitry Andric Changed |= shortenOn01(MI, SystemZ::LNDFR); 2910b57cec5SDimitry Andric break; 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric case SystemZ::WFLNSB: 2940b57cec5SDimitry Andric Changed |= shortenOn01(MI, SystemZ::LNDFR_32); 2950b57cec5SDimitry Andric break; 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric case SystemZ::WFLPDB: 2980b57cec5SDimitry Andric Changed |= shortenOn01(MI, SystemZ::LPDFR); 2990b57cec5SDimitry Andric break; 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric case SystemZ::WFLPSB: 3020b57cec5SDimitry Andric Changed |= shortenOn01(MI, SystemZ::LPDFR_32); 3030b57cec5SDimitry Andric break; 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric case SystemZ::WFSQDB: 3060b57cec5SDimitry Andric Changed |= shortenOn01(MI, SystemZ::SQDBR); 3070b57cec5SDimitry Andric break; 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric case SystemZ::WFSQSB: 3100b57cec5SDimitry Andric Changed |= shortenOn01(MI, SystemZ::SQEBR); 3110b57cec5SDimitry Andric break; 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric case SystemZ::WFSDB: 3140b57cec5SDimitry Andric Changed |= shortenOn001AddCC(MI, SystemZ::SDBR); 3150b57cec5SDimitry Andric break; 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric case SystemZ::WFSSB: 3180b57cec5SDimitry Andric Changed |= shortenOn001AddCC(MI, SystemZ::SEBR); 3190b57cec5SDimitry Andric break; 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric case SystemZ::WFCDB: 3220b57cec5SDimitry Andric Changed |= shortenOn01(MI, SystemZ::CDBR); 3230b57cec5SDimitry Andric break; 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric case SystemZ::WFCSB: 3260b57cec5SDimitry Andric Changed |= shortenOn01(MI, SystemZ::CEBR); 3270b57cec5SDimitry Andric break; 3280b57cec5SDimitry Andric 329480093f4SDimitry Andric case SystemZ::WFKDB: 330480093f4SDimitry Andric Changed |= shortenOn01(MI, SystemZ::KDBR); 331480093f4SDimitry Andric break; 332480093f4SDimitry Andric 333480093f4SDimitry Andric case SystemZ::WFKSB: 334480093f4SDimitry Andric Changed |= shortenOn01(MI, SystemZ::KEBR); 335480093f4SDimitry Andric break; 336480093f4SDimitry Andric 3370b57cec5SDimitry Andric case SystemZ::VL32: 3380b57cec5SDimitry Andric // For z13 we prefer LDE over LE to avoid partial register dependencies. 3390b57cec5SDimitry Andric Changed |= shortenOn0(MI, SystemZ::LDE32); 3400b57cec5SDimitry Andric break; 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric case SystemZ::VST32: 3430b57cec5SDimitry Andric Changed |= shortenOn0(MI, SystemZ::STE); 3440b57cec5SDimitry Andric break; 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric case SystemZ::VL64: 3470b57cec5SDimitry Andric Changed |= shortenOn0(MI, SystemZ::LD); 3480b57cec5SDimitry Andric break; 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric case SystemZ::VST64: 3510b57cec5SDimitry Andric Changed |= shortenOn0(MI, SystemZ::STD); 3520b57cec5SDimitry Andric break; 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric default: { 3550b57cec5SDimitry Andric int TwoOperandOpcode = SystemZ::getTwoOperandOpcode(MI.getOpcode()); 3560b57cec5SDimitry Andric if (TwoOperandOpcode == -1) 3570b57cec5SDimitry Andric break; 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric if ((MI.getOperand(0).getReg() != MI.getOperand(1).getReg()) && 3600b57cec5SDimitry Andric (!MI.isCommutable() || 3610b57cec5SDimitry Andric MI.getOperand(0).getReg() != MI.getOperand(2).getReg() || 3620b57cec5SDimitry Andric !TII->commuteInstruction(MI, false, 1, 2))) 3630b57cec5SDimitry Andric break; 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric MI.setDesc(TII->get(TwoOperandOpcode)); 3660b57cec5SDimitry Andric MI.tieOperands(0, 1); 3670b57cec5SDimitry Andric if (TwoOperandOpcode == SystemZ::SLL || 3680b57cec5SDimitry Andric TwoOperandOpcode == SystemZ::SLA || 3690b57cec5SDimitry Andric TwoOperandOpcode == SystemZ::SRL || 3700b57cec5SDimitry Andric TwoOperandOpcode == SystemZ::SRA) { 3710b57cec5SDimitry Andric // These shifts only use the low 6 bits of the shift count. 3720b57cec5SDimitry Andric MachineOperand &ImmMO = MI.getOperand(3); 3730b57cec5SDimitry Andric ImmMO.setImm(ImmMO.getImm() & 0xfff); 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric Changed = true; 3760b57cec5SDimitry Andric break; 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric LiveRegs.stepBackward(MI); 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric return Changed; 3840b57cec5SDimitry Andric } 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric bool SystemZShortenInst::runOnMachineFunction(MachineFunction &F) { 3870b57cec5SDimitry Andric if (skipFunction(F.getFunction())) 3880b57cec5SDimitry Andric return false; 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric const SystemZSubtarget &ST = F.getSubtarget<SystemZSubtarget>(); 3910b57cec5SDimitry Andric TII = ST.getInstrInfo(); 3920b57cec5SDimitry Andric TRI = ST.getRegisterInfo(); 3930b57cec5SDimitry Andric LiveRegs.init(*TRI); 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric bool Changed = false; 3960b57cec5SDimitry Andric for (auto &MBB : F) 3970b57cec5SDimitry Andric Changed |= processBlock(MBB); 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric return Changed; 4000b57cec5SDimitry Andric } 401