Index: lib/Target/SystemZ/SystemZInstrFormats.td =================================================================== --- lib/Target/SystemZ/SystemZInstrFormats.td +++ lib/Target/SystemZ/SystemZInstrFormats.td @@ -129,13 +129,13 @@ let ValueCols = [["mem"]]; } -// Return the 3-operand form of a 2-operand instruction. -def getThreeOperandOpcode : InstrMapping { +// Return the 2-operand form of a 3-operand instruction. +def getTwoOperandOpcode : InstrMapping { let FilterClass = "InstSystemZ"; let RowFields = ["NumOpsKey"]; let ColFields = ["NumOpsValue"]; - let KeyCol = ["2"]; - let ValueCols = [["3"]]; + let KeyCol = ["3"]; + let ValueCols = [["2"]]; } //===----------------------------------------------------------------------===// @@ -3073,10 +3073,10 @@ RegisterOperand cls2> { let NumOpsKey = mnemonic in { let NumOpsValue = "3" in - def K : BinaryRRFa, + def K : BinaryRRFa, Requires<[FeatureDistinctOps]>; - let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in - def "" : BinaryRR; + let NumOpsValue = "2" in + def "" : BinaryRR; } } @@ -3085,10 +3085,10 @@ RegisterOperand cls2> { let NumOpsKey = mnemonic in { let NumOpsValue = "3" in - def K : BinaryRRFa, + def K : BinaryRRFa, Requires<[FeatureDistinctOps]>; - let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in - def "" : BinaryRRE; + let NumOpsValue = "2" in + def "" : BinaryRRE; } } @@ -3188,10 +3188,10 @@ Immediate imm> { let NumOpsKey = mnemonic in { let NumOpsValue = "3" in - def K : BinaryRIE, + def K : BinaryRIE, Requires<[FeatureDistinctOps]>; - let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in - def "" : BinaryRI; + let NumOpsValue = "2" in + def "" : BinaryRI; } } @@ -3265,10 +3265,10 @@ SDPatternOperator operator, RegisterOperand cls> { let NumOpsKey = mnemonic in { let NumOpsValue = "3" in - def K : BinaryRSY, + def K : BinaryRSY, Requires<[FeatureDistinctOps]>; - let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in - def "" : BinaryRS; + let NumOpsValue = "2" in + def "" : BinaryRS; } } @@ -4593,10 +4593,10 @@ RegisterOperand cls, Immediate imm> { let NumOpsKey = key in { let NumOpsValue = "3" in - def K : BinaryRIEPseudo, + def K : BinaryRIEPseudo, Requires<[FeatureHighWord, FeatureDistinctOps]>; - let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in - def "" : BinaryRIPseudo, + let NumOpsValue = "2" in + def "" : BinaryRIPseudo, Requires<[FeatureHighWord]>; } } Index: lib/Target/SystemZ/SystemZInstrInfo.h =================================================================== --- lib/Target/SystemZ/SystemZInstrInfo.h +++ lib/Target/SystemZ/SystemZInstrInfo.h @@ -315,6 +315,9 @@ bool areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb, AliasAnalysis *AA = nullptr) const override; + + // A wrapper for getTwoOperandOpcode(). + int get2AddrOpcode(unsigned Opcode) const; }; } // end namespace llvm Index: lib/Target/SystemZ/SystemZInstrInfo.cpp =================================================================== --- lib/Target/SystemZ/SystemZInstrInfo.cpp +++ lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -957,73 +957,12 @@ } } -// Used to return from convertToThreeAddress after replacing two-address -// instruction OldMI with three-address instruction NewMI. -static MachineInstr *finishConvertToThreeAddress(MachineInstr *OldMI, - MachineInstr *NewMI, - LiveVariables *LV) { - if (LV) { - unsigned NumOps = OldMI->getNumOperands(); - for (unsigned I = 1; I < NumOps; ++I) { - MachineOperand &Op = OldMI->getOperand(I); - if (Op.isReg() && Op.isKill()) - LV->replaceKillInstruction(Op.getReg(), *OldMI, *NewMI); - } - } - transferDeadCC(OldMI, NewMI); - return NewMI; -} - MachineInstr *SystemZInstrInfo::convertToThreeAddress( MachineFunction::iterator &MFI, MachineInstr &MI, LiveVariables *LV) const { MachineBasicBlock *MBB = MI.getParent(); - MachineFunction *MF = MBB->getParent(); - MachineRegisterInfo &MRI = MF->getRegInfo(); - - unsigned Opcode = MI.getOpcode(); - unsigned NumOps = MI.getNumOperands(); - - // Try to convert something like SLL into SLLK, if supported. - // We prefer to keep the two-operand form where possible both - // because it tends to be shorter and because some instructions - // have memory forms that can be used during spilling. - if (STI.hasDistinctOps()) { - MachineOperand &Dest = MI.getOperand(0); - MachineOperand &Src = MI.getOperand(1); - unsigned DestReg = Dest.getReg(); - unsigned SrcReg = Src.getReg(); - // AHIMux is only really a three-operand instruction when both operands - // are low registers. Try to constrain both operands to be low if - // possible. - if (Opcode == SystemZ::AHIMux && - TargetRegisterInfo::isVirtualRegister(DestReg) && - TargetRegisterInfo::isVirtualRegister(SrcReg) && - MRI.getRegClass(DestReg)->contains(SystemZ::R1L) && - MRI.getRegClass(SrcReg)->contains(SystemZ::R1L)) { - MRI.constrainRegClass(DestReg, &SystemZ::GR32BitRegClass); - MRI.constrainRegClass(SrcReg, &SystemZ::GR32BitRegClass); - } - int ThreeOperandOpcode = SystemZ::getThreeOperandOpcode(Opcode); - if (ThreeOperandOpcode >= 0) { - // Create three address instruction without adding the implicit - // operands. Those will instead be copied over from the original - // instruction by the loop below. - MachineInstrBuilder MIB( - *MF, MF->CreateMachineInstr(get(ThreeOperandOpcode), MI.getDebugLoc(), - /*NoImplicit=*/true)); - MIB.add(Dest); - // Keep the kill state, but drop the tied flag. - MIB.addReg(Src.getReg(), getKillRegState(Src.isKill()), Src.getSubReg()); - // Keep the remaining operands as-is. - for (unsigned I = 2; I < NumOps; ++I) - MIB.add(MI.getOperand(I)); - MBB->insert(MI, MIB); - return finishConvertToThreeAddress(&MI, MIB, LV); - } - } // Try to convert an AND into an RISBG-type instruction. - if (LogicOp And = interpretAndImmediate(Opcode)) { + if (LogicOp And = interpretAndImmediate(MI.getOpcode())) { uint64_t Imm = MI.getOperand(2).getImm() << And.ImmLSB; // AND IMMEDIATE leaves the other bits of the register unchanged. Imm |= allOnes(And.RegSize) & ~(allOnes(And.ImmSize) << And.ImmLSB); @@ -1051,7 +990,16 @@ .addImm(Start) .addImm(End + 128) .addImm(0); - return finishConvertToThreeAddress(&MI, MIB, LV); + if (LV) { + unsigned NumOps = MI.getNumOperands(); + for (unsigned I = 1; I < NumOps; ++I) { + MachineOperand &Op = MI.getOperand(I); + if (Op.isReg() && Op.isKill()) + LV->replaceKillInstruction(Op.getReg(), MI, *MIB); + } + } + transferDeadCC(&MI, MIB); + return MIB; } } return nullptr; @@ -1815,3 +1763,7 @@ return false; } + +int SystemZInstrInfo::get2AddrOpcode(unsigned Opcode) const { + return SystemZ::getTwoOperandOpcode(Opcode); +} Index: lib/Target/SystemZ/SystemZRegisterInfo.cpp =================================================================== --- lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -81,7 +81,9 @@ const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const { const MachineRegisterInfo *MRI = &MF.getRegInfo(); - const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); + const SystemZSubtarget &Subtarget = MF.getSubtarget(); + const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); + const SystemZInstrInfo *TII = Subtarget.getInstrInfo(); bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints( VirtReg, Order, Hints, MF, VRM, Matrix); @@ -138,6 +140,30 @@ } } + if (VRM == nullptr) + return BaseImplRetVal; + + // Add any two address hints after any copy hints. + SmallSet TwoAddrHints; + for (auto &Use : MRI->use_instructions(VirtReg)) + if (TII->get2AddrOpcode(Use.getOpcode()) != -1) { + unsigned DstReg = Use.getOperand(0).getReg(); + unsigned SrcReg = Use.getOperand(1).getReg(); + unsigned OtherReg = 0; + if (VirtReg == DstReg) + OtherReg = SrcReg; + else if (VirtReg == SrcReg) + OtherReg = DstReg; + if (OtherReg && VRM->hasPhys(OtherReg)) + TwoAddrHints.insert(VRM->getPhys(OtherReg)); + } + SmallSet CopyHints; + CopyHints.insert(Hints.begin(), Hints.end()); + for (MCPhysReg OrderReg : Order) + if (!CopyHints.count(OrderReg) && TwoAddrHints.count(OrderReg) && + !MRI->isReserved(OrderReg)) + Hints.push_back(OrderReg); + return BaseImplRetVal; } Index: lib/Target/SystemZ/SystemZShortenInst.cpp =================================================================== --- lib/Target/SystemZ/SystemZShortenInst.cpp +++ lib/Target/SystemZ/SystemZShortenInst.cpp @@ -299,6 +299,24 @@ case SystemZ::VST64: Changed |= shortenOn0(MI, SystemZ::STD); break; + + default: { + int TwoOperandOpcode = TII->get2AddrOpcode(MI.getOpcode()); + if (TwoOperandOpcode != -1) { + if ((TwoOperandOpcode == SystemZ::SLL || + TwoOperandOpcode == SystemZ::SLA || + TwoOperandOpcode == SystemZ::SRL || + TwoOperandOpcode == SystemZ::SRA) && + !isUInt<12>(MI.getOperand(3).getImm())) + break; + if (MI.getOperand(0).getReg() == MI.getOperand(1).getReg()) { + MI.setDesc(TII->get(TwoOperandOpcode)); + MI.tieOperands(0, 1); + Changed = true; + } + } + break; + } } LiveRegs.stepBackward(MI);