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