1c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford//===-- SystemZShortenInst.cpp - Instruction-shortening pass --------------===// 2c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// 3c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// The LLVM Compiler Infrastructure 4c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// 5c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// This file is distributed under the University of Illinois Open Source 6c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// License. See LICENSE.TXT for details. 7c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// 8c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford//===----------------------------------------------------------------------===// 9c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// 10c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// This pass tries to replace instructions with shorter forms. For example, 11c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// IILF can be replaced with LLILL or LLILH if the constant fits and if the 12c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// other 32 bits of the GR64 destination are not live. 13c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// 14c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford//===----------------------------------------------------------------------===// 15c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 16c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford#include "SystemZTargetMachine.h" 17c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford#include "llvm/CodeGen/MachineFunctionPass.h" 18c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 19c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandifordusing namespace llvm; 20c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "systemz-shorten-inst" 22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 23c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandifordnamespace { 2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass SystemZShortenInst : public MachineFunctionPass { 2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic: 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static char ID; 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SystemZShortenInst(const SystemZTargetMachine &tm); 28c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getPassName() const override { 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "SystemZ Instruction Shortening"; 3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 32c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool processBlock(MachineBasicBlock &MBB); 34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool runOnMachineFunction(MachineFunction &F) override; 35c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesprivate: 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool shortenIIF(MachineInstr &MI, unsigned *GPRMap, unsigned LiveOther, 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned LLIxL, unsigned LLIxH); 39c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SystemZInstrInfo *TII; 41c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // LowGPRs[I] has bit N set if LLVM register I includes the low 4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // word of GPR N. HighGPRs is the same for the high word. 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned LowGPRs[SystemZ::NUM_TARGET_REGS]; 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned HighGPRs[SystemZ::NUM_TARGET_REGS]; 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 47c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineschar SystemZShortenInst::ID = 0; 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // end anonymous namespace 50c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 51c2b840cb7c58e59c68aaa589841c41fb272df66dRichard SandifordFunctionPass *llvm::createSystemZShortenInstPass(SystemZTargetMachine &TM) { 52c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford return new SystemZShortenInst(TM); 53c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford} 54c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 55c2b840cb7c58e59c68aaa589841c41fb272df66dRichard SandifordSystemZShortenInst::SystemZShortenInst(const SystemZTargetMachine &tm) 56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : MachineFunctionPass(ID), TII(nullptr), LowGPRs(), HighGPRs() { 57c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford // Set up LowGPRs and HighGPRs. 58c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford for (unsigned I = 0; I < 16; ++I) { 59c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford LowGPRs[SystemZMC::GR32Regs[I]] |= 1 << I; 60c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford LowGPRs[SystemZMC::GR64Regs[I]] |= 1 << I; 614c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford HighGPRs[SystemZMC::GRH32Regs[I]] |= 1 << I; 62c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford HighGPRs[SystemZMC::GR64Regs[I]] |= 1 << I; 63c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford if (unsigned GR128 = SystemZMC::GR128Regs[I]) { 64c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford LowGPRs[GR128] |= 3 << I; 65c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford HighGPRs[GR128] |= 3 << I; 66c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } 67c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } 68c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford} 69c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 70c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// MI loads one word of a GPR using an IIxF instruction and LLIxL and LLIxH 71c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// are the halfword immediate loads for the same word. Try to use one of them 72c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// instead of IIxF. If MI loads the high word, GPRMap[X] is the set of high 73c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// words referenced by LLVM register X while LiveOther is the mask of low 74c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// words that are currently live, and vice versa. 75c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandifordbool SystemZShortenInst::shortenIIF(MachineInstr &MI, unsigned *GPRMap, 76c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford unsigned LiveOther, unsigned LLIxL, 77c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford unsigned LLIxH) { 78c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford unsigned Reg = MI.getOperand(0).getReg(); 79c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford assert(Reg < SystemZ::NUM_TARGET_REGS && "Invalid register number"); 80c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford unsigned GPRs = GPRMap[Reg]; 81c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford assert(GPRs != 0 && "Register must be a GPR"); 82c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford if (GPRs & LiveOther) 83c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford return false; 84c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 85c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford uint64_t Imm = MI.getOperand(1).getImm(); 86c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford if (SystemZ::isImmLL(Imm)) { 87c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford MI.setDesc(TII->get(LLIxL)); 88c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford MI.getOperand(0).setReg(SystemZMC::getRegAsGR64(Reg)); 89c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford return true; 90c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } 91c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford if (SystemZ::isImmLH(Imm)) { 92c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford MI.setDesc(TII->get(LLIxH)); 93c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford MI.getOperand(0).setReg(SystemZMC::getRegAsGR64(Reg)); 94c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford MI.getOperand(1).setImm(Imm >> 16); 95c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford return true; 96c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } 97c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford return false; 98c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford} 99c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 100c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford// Process all instructions in MBB. Return true if something changed. 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) { 102c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford bool Changed = false; 103c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 104c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford // Work out which words are live on exit from the block. 105c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford unsigned LiveLow = 0; 106c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford unsigned LiveHigh = 0; 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto SI = MBB.succ_begin(), SE = MBB.succ_end(); SI != SE; ++SI) { 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto LI = (*SI)->livein_begin(), LE = (*SI)->livein_end(); 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LI != LE; ++LI) { 110c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford unsigned Reg = *LI; 111c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford assert(Reg < SystemZ::NUM_TARGET_REGS && "Invalid register number"); 112c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford LiveLow |= LowGPRs[Reg]; 113c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford LiveHigh |= HighGPRs[Reg]; 114c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } 115c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } 116c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 117c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford // Iterate backwards through the block looking for instructions to change. 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto MBBI = MBB.rbegin(), MBBE = MBB.rend(); MBBI != MBBE; ++MBBI) { 119c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford MachineInstr &MI = *MBBI; 120c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford unsigned Opcode = MI.getOpcode(); 121259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford if (Opcode == SystemZ::IILF) 122c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford Changed |= shortenIIF(MI, LowGPRs, LiveHigh, SystemZ::LLILL, 123c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford SystemZ::LLILH); 1244c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford else if (Opcode == SystemZ::IIHF) 1254c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford Changed |= shortenIIF(MI, HighGPRs, LiveLow, SystemZ::LLIHL, 1264c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford SystemZ::LLIHH); 127c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford unsigned UsedLow = 0; 128c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford unsigned UsedHigh = 0; 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto MOI = MI.operands_begin(), MOE = MI.operands_end(); 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MOI != MOE; ++MOI) { 131c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford MachineOperand &MO = *MOI; 132c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford if (MO.isReg()) { 133c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford if (unsigned Reg = MO.getReg()) { 134c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford assert(Reg < SystemZ::NUM_TARGET_REGS && "Invalid register number"); 135c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford if (MO.isDef()) { 136c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford LiveLow &= ~LowGPRs[Reg]; 137c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford LiveHigh &= ~HighGPRs[Reg]; 138c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } else if (!MO.isUndef()) { 139c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford UsedLow |= LowGPRs[Reg]; 140c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford UsedHigh |= HighGPRs[Reg]; 141c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } 142c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } 143c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } 144c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } 145c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford LiveLow |= UsedLow; 146c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford LiveHigh |= UsedHigh; 147c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford } 148c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 149c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford return Changed; 150c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford} 151c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 152c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandifordbool SystemZShortenInst::runOnMachineFunction(MachineFunction &F) { 153c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford TII = static_cast<const SystemZInstrInfo *>(F.getTarget().getInstrInfo()); 154c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 155c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford bool Changed = false; 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto &MBB : F) 15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Changed |= processBlock(MBB); 158c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford 159c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford return Changed; 160c2b840cb7c58e59c68aaa589841c41fb272df66dRichard Sandiford} 161