2013-09-25 18:11:07 +08:00
|
|
|
//===-- SystemZShortenInst.cpp - Instruction-shortening pass --------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2013-09-25 18:11:07 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This pass tries to replace instructions with shorter forms. For example,
|
|
|
|
// IILF can be replaced with LLILL or LLILH if the constant fits and if the
|
|
|
|
// other 32 bits of the GR64 destination are not live.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "SystemZTargetMachine.h"
|
2017-06-06 19:49:48 +08:00
|
|
|
#include "llvm/CodeGen/LivePhysRegs.h"
|
2013-09-25 18:11:07 +08:00
|
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
2015-05-06 03:28:34 +08:00
|
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
2017-11-17 09:07:10 +08:00
|
|
|
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
2013-09-25 18:11:07 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2014-04-22 10:41:26 +08:00
|
|
|
#define DEBUG_TYPE "systemz-shorten-inst"
|
|
|
|
|
2013-09-25 18:11:07 +08:00
|
|
|
namespace {
|
2014-03-06 18:38:30 +08:00
|
|
|
class SystemZShortenInst : public MachineFunctionPass {
|
|
|
|
public:
|
|
|
|
static char ID;
|
|
|
|
SystemZShortenInst(const SystemZTargetMachine &tm);
|
2013-09-25 18:11:07 +08:00
|
|
|
|
2016-10-01 10:56:57 +08:00
|
|
|
StringRef getPassName() const override {
|
2014-03-06 18:38:30 +08:00
|
|
|
return "SystemZ Instruction Shortening";
|
|
|
|
}
|
2013-09-25 18:11:07 +08:00
|
|
|
|
2014-03-06 19:00:15 +08:00
|
|
|
bool processBlock(MachineBasicBlock &MBB);
|
2014-04-29 15:58:41 +08:00
|
|
|
bool runOnMachineFunction(MachineFunction &F) override;
|
2016-04-05 01:09:25 +08:00
|
|
|
MachineFunctionProperties getRequiredProperties() const override {
|
|
|
|
return MachineFunctionProperties().set(
|
2016-08-25 09:27:13 +08:00
|
|
|
MachineFunctionProperties::Property::NoVRegs);
|
2016-04-05 01:09:25 +08:00
|
|
|
}
|
2013-09-25 18:11:07 +08:00
|
|
|
|
2014-03-06 18:38:30 +08:00
|
|
|
private:
|
2015-10-20 23:05:58 +08:00
|
|
|
bool shortenIIF(MachineInstr &MI, unsigned LLIxL, unsigned LLIxH);
|
2015-05-06 03:28:34 +08:00
|
|
|
bool shortenOn0(MachineInstr &MI, unsigned Opcode);
|
|
|
|
bool shortenOn01(MachineInstr &MI, unsigned Opcode);
|
|
|
|
bool shortenOn001(MachineInstr &MI, unsigned Opcode);
|
2015-10-20 23:05:58 +08:00
|
|
|
bool shortenOn001AddCC(MachineInstr &MI, unsigned Opcode);
|
2015-05-06 03:28:34 +08:00
|
|
|
bool shortenFPConv(MachineInstr &MI, unsigned Opcode);
|
2020-03-18 23:41:32 +08:00
|
|
|
bool shortenFusedFPOp(MachineInstr &MI, unsigned Opcode);
|
2013-09-25 18:11:07 +08:00
|
|
|
|
2014-03-06 18:38:30 +08:00
|
|
|
const SystemZInstrInfo *TII;
|
2015-10-20 23:05:58 +08:00
|
|
|
const TargetRegisterInfo *TRI;
|
|
|
|
LivePhysRegs LiveRegs;
|
2014-03-06 18:38:30 +08:00
|
|
|
};
|
2013-09-25 18:11:07 +08:00
|
|
|
|
2014-03-06 18:38:30 +08:00
|
|
|
char SystemZShortenInst::ID = 0;
|
|
|
|
} // end anonymous namespace
|
2013-09-25 18:11:07 +08:00
|
|
|
|
|
|
|
FunctionPass *llvm::createSystemZShortenInstPass(SystemZTargetMachine &TM) {
|
|
|
|
return new SystemZShortenInst(TM);
|
|
|
|
}
|
|
|
|
|
|
|
|
SystemZShortenInst::SystemZShortenInst(const SystemZTargetMachine &tm)
|
2015-10-20 23:05:58 +08:00
|
|
|
: MachineFunctionPass(ID), TII(nullptr) {}
|
2013-09-25 18:11:07 +08:00
|
|
|
|
2015-10-26 23:03:07 +08:00
|
|
|
// Tie operands if MI has become a two-address instruction.
|
|
|
|
static void tieOpsIfNeeded(MachineInstr &MI) {
|
2020-03-26 19:22:14 +08:00
|
|
|
if (MI.getDesc().getOperandConstraint(1, MCOI::TIED_TO) == 0 &&
|
2015-10-26 23:03:07 +08:00
|
|
|
!MI.getOperand(0).isTied())
|
|
|
|
MI.tieOperands(0, 1);
|
|
|
|
}
|
|
|
|
|
2013-09-25 18:11:07 +08:00
|
|
|
// MI loads one word of a GPR using an IIxF instruction and LLIxL and LLIxH
|
|
|
|
// are the halfword immediate loads for the same word. Try to use one of them
|
2016-06-20 08:49:20 +08:00
|
|
|
// instead of IIxF.
|
|
|
|
bool SystemZShortenInst::shortenIIF(MachineInstr &MI, unsigned LLIxL,
|
|
|
|
unsigned LLIxH) {
|
Apply llvm-prefer-register-over-unsigned from clang-tidy to LLVM
Summary:
This clang-tidy check is looking for unsigned integer variables whose initializer
starts with an implicit cast from llvm::Register and changes the type of the
variable to llvm::Register (dropping the llvm:: where possible).
Partial reverts in:
X86FrameLowering.cpp - Some functions return unsigned and arguably should be MCRegister
X86FixupLEAs.cpp - Some functions return unsigned and arguably should be MCRegister
X86FrameLowering.cpp - Some functions return unsigned and arguably should be MCRegister
HexagonBitSimplify.cpp - Function takes BitTracker::RegisterRef which appears to be unsigned&
MachineVerifier.cpp - Ambiguous operator==() given MCRegister and const Register
PPCFastISel.cpp - No Register::operator-=()
PeepholeOptimizer.cpp - TargetInstrInfo::optimizeLoadInstr() takes an unsigned&
MachineTraceMetrics.cpp - MachineTraceMetrics lacks a suitable constructor
Manual fixups in:
ARMFastISel.cpp - ARMEmitLoad() now takes a Register& instead of unsigned&
HexagonSplitDouble.cpp - Ternary operator was ambiguous between unsigned/Register
HexagonConstExtenders.cpp - Has a local class named Register, used llvm::Register instead of Register.
PPCFastISel.cpp - PPCEmitLoad() now takes a Register& instead of unsigned&
Depends on D65919
Reviewers: arsenm, bogner, craig.topper, RKSimon
Reviewed By: arsenm
Subscribers: RKSimon, craig.topper, lenary, aemerson, wuzish, jholewinski, MatzeB, qcolombet, dschuff, jyknight, dylanmckay, sdardis, nemanjai, jvesely, wdng, nhaehnle, sbc100, jgravelle-google, kristof.beyls, hiraditya, aheejin, kbarton, fedor.sergeev, javed.absar, asb, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, jrtc27, MaskRay, zzheng, edward-jones, atanasyan, rogfer01, MartinMosbeck, brucehoult, the_o, tpr, PkmX, jocewei, jsji, Petar.Avramovic, asbirlea, Jim, s.egerton, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65962
llvm-svn: 369041
2019-08-16 03:22:08 +08:00
|
|
|
Register Reg = MI.getOperand(0).getReg();
|
2015-10-20 23:05:58 +08:00
|
|
|
// The new opcode will clear the other half of the GR64 reg, so
|
|
|
|
// cancel if that is live.
|
2016-06-20 08:37:41 +08:00
|
|
|
unsigned thisSubRegIdx =
|
|
|
|
(SystemZ::GRH32BitRegClass.contains(Reg) ? SystemZ::subreg_h32
|
|
|
|
: SystemZ::subreg_l32);
|
|
|
|
unsigned otherSubRegIdx =
|
|
|
|
(thisSubRegIdx == SystemZ::subreg_l32 ? SystemZ::subreg_h32
|
|
|
|
: SystemZ::subreg_l32);
|
|
|
|
unsigned GR64BitReg =
|
|
|
|
TRI->getMatchingSuperReg(Reg, thisSubRegIdx, &SystemZ::GR64BitRegClass);
|
Apply llvm-prefer-register-over-unsigned from clang-tidy to LLVM
Summary:
This clang-tidy check is looking for unsigned integer variables whose initializer
starts with an implicit cast from llvm::Register and changes the type of the
variable to llvm::Register (dropping the llvm:: where possible).
Partial reverts in:
X86FrameLowering.cpp - Some functions return unsigned and arguably should be MCRegister
X86FixupLEAs.cpp - Some functions return unsigned and arguably should be MCRegister
X86FrameLowering.cpp - Some functions return unsigned and arguably should be MCRegister
HexagonBitSimplify.cpp - Function takes BitTracker::RegisterRef which appears to be unsigned&
MachineVerifier.cpp - Ambiguous operator==() given MCRegister and const Register
PPCFastISel.cpp - No Register::operator-=()
PeepholeOptimizer.cpp - TargetInstrInfo::optimizeLoadInstr() takes an unsigned&
MachineTraceMetrics.cpp - MachineTraceMetrics lacks a suitable constructor
Manual fixups in:
ARMFastISel.cpp - ARMEmitLoad() now takes a Register& instead of unsigned&
HexagonSplitDouble.cpp - Ternary operator was ambiguous between unsigned/Register
HexagonConstExtenders.cpp - Has a local class named Register, used llvm::Register instead of Register.
PPCFastISel.cpp - PPCEmitLoad() now takes a Register& instead of unsigned&
Depends on D65919
Reviewers: arsenm, bogner, craig.topper, RKSimon
Reviewed By: arsenm
Subscribers: RKSimon, craig.topper, lenary, aemerson, wuzish, jholewinski, MatzeB, qcolombet, dschuff, jyknight, dylanmckay, sdardis, nemanjai, jvesely, wdng, nhaehnle, sbc100, jgravelle-google, kristof.beyls, hiraditya, aheejin, kbarton, fedor.sergeev, javed.absar, asb, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, jrtc27, MaskRay, zzheng, edward-jones, atanasyan, rogfer01, MartinMosbeck, brucehoult, the_o, tpr, PkmX, jocewei, jsji, Petar.Avramovic, asbirlea, Jim, s.egerton, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65962
llvm-svn: 369041
2019-08-16 03:22:08 +08:00
|
|
|
Register OtherReg = TRI->getSubReg(GR64BitReg, otherSubRegIdx);
|
2015-10-20 23:05:58 +08:00
|
|
|
if (LiveRegs.contains(OtherReg))
|
2013-09-25 18:11:07 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
uint64_t Imm = MI.getOperand(1).getImm();
|
|
|
|
if (SystemZ::isImmLL(Imm)) {
|
|
|
|
MI.setDesc(TII->get(LLIxL));
|
|
|
|
MI.getOperand(0).setReg(SystemZMC::getRegAsGR64(Reg));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (SystemZ::isImmLH(Imm)) {
|
|
|
|
MI.setDesc(TII->get(LLIxH));
|
|
|
|
MI.getOperand(0).setReg(SystemZMC::getRegAsGR64(Reg));
|
|
|
|
MI.getOperand(1).setImm(Imm >> 16);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-05-06 03:28:34 +08:00
|
|
|
// Change MI's opcode to Opcode if register operand 0 has a 4-bit encoding.
|
|
|
|
bool SystemZShortenInst::shortenOn0(MachineInstr &MI, unsigned Opcode) {
|
|
|
|
if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16) {
|
|
|
|
MI.setDesc(TII->get(Opcode));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change MI's opcode to Opcode if register operands 0 and 1 have a
|
|
|
|
// 4-bit encoding.
|
|
|
|
bool SystemZShortenInst::shortenOn01(MachineInstr &MI, unsigned Opcode) {
|
|
|
|
if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 &&
|
|
|
|
SystemZMC::getFirstReg(MI.getOperand(1).getReg()) < 16) {
|
|
|
|
MI.setDesc(TII->get(Opcode));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change MI's opcode to Opcode if register operands 0, 1 and 2 have a
|
2015-10-26 23:03:07 +08:00
|
|
|
// 4-bit encoding and if operands 0 and 1 are tied. Also ties op 0
|
|
|
|
// with op 1, if MI becomes 2-address.
|
2015-05-06 03:28:34 +08:00
|
|
|
bool SystemZShortenInst::shortenOn001(MachineInstr &MI, unsigned Opcode) {
|
|
|
|
if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 &&
|
|
|
|
MI.getOperand(1).getReg() == MI.getOperand(0).getReg() &&
|
|
|
|
SystemZMC::getFirstReg(MI.getOperand(2).getReg()) < 16) {
|
|
|
|
MI.setDesc(TII->get(Opcode));
|
2015-10-26 23:03:07 +08:00
|
|
|
tieOpsIfNeeded(MI);
|
2015-05-06 03:28:34 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-10-08 15:40:19 +08:00
|
|
|
// Calls shortenOn001 if CCLive is false. CC def operand is added in
|
|
|
|
// case of success.
|
2016-06-20 08:37:41 +08:00
|
|
|
bool SystemZShortenInst::shortenOn001AddCC(MachineInstr &MI, unsigned Opcode) {
|
2015-10-20 23:05:58 +08:00
|
|
|
if (!LiveRegs.contains(SystemZ::CC) && shortenOn001(MI, Opcode)) {
|
2015-10-08 15:40:19 +08:00
|
|
|
MachineInstrBuilder(*MI.getParent()->getParent(), &MI)
|
2016-05-02 17:37:40 +08:00
|
|
|
.addReg(SystemZ::CC, RegState::ImplicitDefine | RegState::Dead);
|
2015-10-08 15:40:19 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-05-06 03:28:34 +08:00
|
|
|
// MI is a vector-style conversion instruction with the operand order:
|
|
|
|
// destination, source, exact-suppress, rounding-mode. If both registers
|
|
|
|
// have a 4-bit encoding then change it to Opcode, which has operand order:
|
|
|
|
// destination, rouding-mode, source, exact-suppress.
|
|
|
|
bool SystemZShortenInst::shortenFPConv(MachineInstr &MI, unsigned Opcode) {
|
|
|
|
if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 &&
|
|
|
|
SystemZMC::getFirstReg(MI.getOperand(1).getReg()) < 16) {
|
|
|
|
MachineOperand Dest(MI.getOperand(0));
|
|
|
|
MachineOperand Src(MI.getOperand(1));
|
|
|
|
MachineOperand Suppress(MI.getOperand(2));
|
|
|
|
MachineOperand Mode(MI.getOperand(3));
|
|
|
|
MI.RemoveOperand(3);
|
|
|
|
MI.RemoveOperand(2);
|
|
|
|
MI.RemoveOperand(1);
|
|
|
|
MI.RemoveOperand(0);
|
|
|
|
MI.setDesc(TII->get(Opcode));
|
|
|
|
MachineInstrBuilder(*MI.getParent()->getParent(), &MI)
|
2017-01-13 17:58:52 +08:00
|
|
|
.add(Dest)
|
|
|
|
.add(Mode)
|
|
|
|
.add(Src)
|
|
|
|
.add(Suppress);
|
2015-05-06 03:28:34 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-03-18 23:41:32 +08:00
|
|
|
bool SystemZShortenInst::shortenFusedFPOp(MachineInstr &MI, unsigned Opcode) {
|
|
|
|
MachineOperand &DstMO = MI.getOperand(0);
|
|
|
|
MachineOperand &LHSMO = MI.getOperand(1);
|
|
|
|
MachineOperand &RHSMO = MI.getOperand(2);
|
|
|
|
MachineOperand &AccMO = MI.getOperand(3);
|
|
|
|
if (SystemZMC::getFirstReg(DstMO.getReg()) < 16 &&
|
|
|
|
SystemZMC::getFirstReg(LHSMO.getReg()) < 16 &&
|
|
|
|
SystemZMC::getFirstReg(RHSMO.getReg()) < 16 &&
|
|
|
|
SystemZMC::getFirstReg(AccMO.getReg()) < 16 &&
|
|
|
|
DstMO.getReg() == AccMO.getReg()) {
|
|
|
|
MachineOperand Lhs(LHSMO);
|
|
|
|
MachineOperand Rhs(RHSMO);
|
|
|
|
MachineOperand Src(AccMO);
|
|
|
|
MI.RemoveOperand(3);
|
|
|
|
MI.RemoveOperand(2);
|
|
|
|
MI.RemoveOperand(1);
|
|
|
|
MI.setDesc(TII->get(Opcode));
|
|
|
|
MachineInstrBuilder(*MI.getParent()->getParent(), &MI)
|
|
|
|
.add(Src)
|
|
|
|
.add(Lhs)
|
|
|
|
.add(Rhs);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-09-25 18:11:07 +08:00
|
|
|
// Process all instructions in MBB. Return true if something changed.
|
2014-03-06 19:00:15 +08:00
|
|
|
bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) {
|
2013-09-25 18:11:07 +08:00
|
|
|
bool Changed = false;
|
|
|
|
|
2015-10-20 23:05:58 +08:00
|
|
|
// Set up the set of live registers at the end of MBB (live out)
|
|
|
|
LiveRegs.clear();
|
2016-05-03 08:24:32 +08:00
|
|
|
LiveRegs.addLiveOuts(MBB);
|
2013-09-25 18:11:07 +08:00
|
|
|
|
|
|
|
// Iterate backwards through the block looking for instructions to change.
|
2014-03-06 19:00:15 +08:00
|
|
|
for (auto MBBI = MBB.rbegin(), MBBE = MBB.rend(); MBBI != MBBE; ++MBBI) {
|
2013-09-25 18:11:07 +08:00
|
|
|
MachineInstr &MI = *MBBI;
|
2015-05-06 03:28:34 +08:00
|
|
|
switch (MI.getOpcode()) {
|
|
|
|
case SystemZ::IILF:
|
2015-10-20 23:05:58 +08:00
|
|
|
Changed |= shortenIIF(MI, SystemZ::LLILL, SystemZ::LLILH);
|
2015-05-06 03:28:34 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SystemZ::IIHF:
|
2015-10-20 23:05:58 +08:00
|
|
|
Changed |= shortenIIF(MI, SystemZ::LLIHL, SystemZ::LLIHH);
|
2015-05-06 03:28:34 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SystemZ::WFADB:
|
2015-10-20 23:05:58 +08:00
|
|
|
Changed |= shortenOn001AddCC(MI, SystemZ::ADBR);
|
2015-05-06 03:28:34 +08:00
|
|
|
break;
|
|
|
|
|
2017-07-18 01:42:48 +08:00
|
|
|
case SystemZ::WFASB:
|
|
|
|
Changed |= shortenOn001AddCC(MI, SystemZ::AEBR);
|
|
|
|
break;
|
|
|
|
|
2015-05-06 03:28:34 +08:00
|
|
|
case SystemZ::WFDDB:
|
|
|
|
Changed |= shortenOn001(MI, SystemZ::DDBR);
|
|
|
|
break;
|
|
|
|
|
2017-07-18 01:42:48 +08:00
|
|
|
case SystemZ::WFDSB:
|
|
|
|
Changed |= shortenOn001(MI, SystemZ::DEBR);
|
|
|
|
break;
|
|
|
|
|
2015-05-06 03:28:34 +08:00
|
|
|
case SystemZ::WFIDB:
|
|
|
|
Changed |= shortenFPConv(MI, SystemZ::FIDBRA);
|
|
|
|
break;
|
|
|
|
|
2017-07-18 01:42:48 +08:00
|
|
|
case SystemZ::WFISB:
|
|
|
|
Changed |= shortenFPConv(MI, SystemZ::FIEBRA);
|
|
|
|
break;
|
|
|
|
|
2015-05-06 03:28:34 +08:00
|
|
|
case SystemZ::WLDEB:
|
|
|
|
Changed |= shortenOn01(MI, SystemZ::LDEBR);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SystemZ::WLEDB:
|
|
|
|
Changed |= shortenFPConv(MI, SystemZ::LEDBRA);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SystemZ::WFMDB:
|
|
|
|
Changed |= shortenOn001(MI, SystemZ::MDBR);
|
|
|
|
break;
|
|
|
|
|
2017-07-18 01:42:48 +08:00
|
|
|
case SystemZ::WFMSB:
|
|
|
|
Changed |= shortenOn001(MI, SystemZ::MEEBR);
|
|
|
|
break;
|
|
|
|
|
2020-03-18 23:41:32 +08:00
|
|
|
case SystemZ::WFMADB:
|
|
|
|
Changed |= shortenFusedFPOp(MI, SystemZ::MADBR);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SystemZ::WFMASB:
|
|
|
|
Changed |= shortenFusedFPOp(MI, SystemZ::MAEBR);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SystemZ::WFMSDB:
|
|
|
|
Changed |= shortenFusedFPOp(MI, SystemZ::MSDBR);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SystemZ::WFMSSB:
|
|
|
|
Changed |= shortenFusedFPOp(MI, SystemZ::MSEBR);
|
|
|
|
break;
|
|
|
|
|
2015-05-06 03:28:34 +08:00
|
|
|
case SystemZ::WFLCDB:
|
2015-10-02 02:12:28 +08:00
|
|
|
Changed |= shortenOn01(MI, SystemZ::LCDFR);
|
2015-05-06 03:28:34 +08:00
|
|
|
break;
|
|
|
|
|
2017-07-18 01:42:48 +08:00
|
|
|
case SystemZ::WFLCSB:
|
|
|
|
Changed |= shortenOn01(MI, SystemZ::LCDFR_32);
|
|
|
|
break;
|
|
|
|
|
2015-05-06 03:28:34 +08:00
|
|
|
case SystemZ::WFLNDB:
|
2015-10-02 02:12:28 +08:00
|
|
|
Changed |= shortenOn01(MI, SystemZ::LNDFR);
|
2015-05-06 03:28:34 +08:00
|
|
|
break;
|
|
|
|
|
2017-07-18 01:42:48 +08:00
|
|
|
case SystemZ::WFLNSB:
|
|
|
|
Changed |= shortenOn01(MI, SystemZ::LNDFR_32);
|
|
|
|
break;
|
|
|
|
|
2015-05-06 03:28:34 +08:00
|
|
|
case SystemZ::WFLPDB:
|
2015-10-02 02:12:28 +08:00
|
|
|
Changed |= shortenOn01(MI, SystemZ::LPDFR);
|
2015-05-06 03:28:34 +08:00
|
|
|
break;
|
|
|
|
|
2017-07-18 01:42:48 +08:00
|
|
|
case SystemZ::WFLPSB:
|
|
|
|
Changed |= shortenOn01(MI, SystemZ::LPDFR_32);
|
|
|
|
break;
|
|
|
|
|
2015-05-06 03:28:34 +08:00
|
|
|
case SystemZ::WFSQDB:
|
|
|
|
Changed |= shortenOn01(MI, SystemZ::SQDBR);
|
|
|
|
break;
|
|
|
|
|
2017-07-18 01:42:48 +08:00
|
|
|
case SystemZ::WFSQSB:
|
|
|
|
Changed |= shortenOn01(MI, SystemZ::SQEBR);
|
|
|
|
break;
|
|
|
|
|
2015-10-09 15:19:20 +08:00
|
|
|
case SystemZ::WFSDB:
|
2015-10-20 23:05:58 +08:00
|
|
|
Changed |= shortenOn001AddCC(MI, SystemZ::SDBR);
|
2015-05-06 03:28:34 +08:00
|
|
|
break;
|
2015-10-09 15:19:20 +08:00
|
|
|
|
2017-07-18 01:42:48 +08:00
|
|
|
case SystemZ::WFSSB:
|
|
|
|
Changed |= shortenOn001AddCC(MI, SystemZ::SEBR);
|
|
|
|
break;
|
|
|
|
|
2015-05-06 03:28:34 +08:00
|
|
|
case SystemZ::WFCDB:
|
|
|
|
Changed |= shortenOn01(MI, SystemZ::CDBR);
|
|
|
|
break;
|
|
|
|
|
2017-07-18 01:42:48 +08:00
|
|
|
case SystemZ::WFCSB:
|
|
|
|
Changed |= shortenOn01(MI, SystemZ::CEBR);
|
|
|
|
break;
|
|
|
|
|
[FPEnv] Constrained FCmp intrinsics
This adds support for constrained floating-point comparison intrinsics.
Specifically, we add:
declare <ty2>
@llvm.experimental.constrained.fcmp(<type> <op1>, <type> <op2>,
metadata <condition code>,
metadata <exception behavior>)
declare <ty2>
@llvm.experimental.constrained.fcmps(<type> <op1>, <type> <op2>,
metadata <condition code>,
metadata <exception behavior>)
The first variant implements an IEEE "quiet" comparison (i.e. we only
get an invalid FP exception if either argument is a SNaN), while the
second variant implements an IEEE "signaling" comparison (i.e. we get
an invalid FP exception if either argument is any NaN).
The condition code is implemented as a metadata string. The same set
of predicates as for the fcmp instruction is supported (except for the
"true" and "false" predicates).
These new intrinsics are mapped by SelectionDAG codegen onto two new
ISD opcodes, ISD::STRICT_FSETCC and ISD::STRICT_FSETCCS, again
representing quiet vs. signaling comparison operations. Otherwise
those nodes look like SETCC nodes, with an additional chain argument
and result as usual for strict FP nodes. The patch includes support
for the common legalization operations for those nodes.
The patch also includes full SystemZ back-end support for the new
ISD nodes, mapping them to all available SystemZ instruction to
fully implement strict semantics (scalar and vector).
Differential Revision: https://reviews.llvm.org/D69281
2019-12-06 18:30:04 +08:00
|
|
|
case SystemZ::WFKDB:
|
|
|
|
Changed |= shortenOn01(MI, SystemZ::KDBR);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SystemZ::WFKSB:
|
|
|
|
Changed |= shortenOn01(MI, SystemZ::KEBR);
|
|
|
|
break;
|
|
|
|
|
2015-05-06 03:28:34 +08:00
|
|
|
case SystemZ::VL32:
|
|
|
|
// For z13 we prefer LDE over LE to avoid partial register dependencies.
|
|
|
|
Changed |= shortenOn0(MI, SystemZ::LDE32);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SystemZ::VST32:
|
|
|
|
Changed |= shortenOn0(MI, SystemZ::STE);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SystemZ::VL64:
|
|
|
|
Changed |= shortenOn0(MI, SystemZ::LD);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SystemZ::VST64:
|
|
|
|
Changed |= shortenOn0(MI, SystemZ::STD);
|
|
|
|
break;
|
2019-06-08 14:19:15 +08:00
|
|
|
|
|
|
|
default: {
|
|
|
|
int TwoOperandOpcode = SystemZ::getTwoOperandOpcode(MI.getOpcode());
|
|
|
|
if (TwoOperandOpcode == -1)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ((MI.getOperand(0).getReg() != MI.getOperand(1).getReg()) &&
|
|
|
|
(!MI.isCommutable() ||
|
|
|
|
MI.getOperand(0).getReg() != MI.getOperand(2).getReg() ||
|
|
|
|
!TII->commuteInstruction(MI, false, 1, 2)))
|
|
|
|
break;
|
|
|
|
|
|
|
|
MI.setDesc(TII->get(TwoOperandOpcode));
|
|
|
|
MI.tieOperands(0, 1);
|
|
|
|
if (TwoOperandOpcode == SystemZ::SLL ||
|
|
|
|
TwoOperandOpcode == SystemZ::SLA ||
|
|
|
|
TwoOperandOpcode == SystemZ::SRL ||
|
|
|
|
TwoOperandOpcode == SystemZ::SRA) {
|
|
|
|
// These shifts only use the low 6 bits of the shift count.
|
|
|
|
MachineOperand &ImmMO = MI.getOperand(3);
|
|
|
|
ImmMO.setImm(ImmMO.getImm() & 0xfff);
|
|
|
|
}
|
|
|
|
Changed = true;
|
|
|
|
break;
|
|
|
|
}
|
2015-05-06 03:28:34 +08:00
|
|
|
}
|
|
|
|
|
2015-10-20 23:05:58 +08:00
|
|
|
LiveRegs.stepBackward(MI);
|
2013-09-25 18:11:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return Changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SystemZShortenInst::runOnMachineFunction(MachineFunction &F) {
|
2017-12-16 06:22:58 +08:00
|
|
|
if (skipFunction(F.getFunction()))
|
2016-04-27 07:49:41 +08:00
|
|
|
return false;
|
|
|
|
|
2015-10-20 23:05:58 +08:00
|
|
|
const SystemZSubtarget &ST = F.getSubtarget<SystemZSubtarget>();
|
|
|
|
TII = ST.getInstrInfo();
|
|
|
|
TRI = ST.getRegisterInfo();
|
2016-12-08 08:15:51 +08:00
|
|
|
LiveRegs.init(*TRI);
|
2013-09-25 18:11:07 +08:00
|
|
|
|
|
|
|
bool Changed = false;
|
2014-03-06 19:00:15 +08:00
|
|
|
for (auto &MBB : F)
|
|
|
|
Changed |= processBlock(MBB);
|
2013-09-25 18:11:07 +08:00
|
|
|
|
|
|
|
return Changed;
|
|
|
|
}
|