diff --git a/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp index 5a26045fe4ca..832f16fe0371 100644 --- a/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp +++ b/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp @@ -116,12 +116,14 @@ static bool isCombinableInstType(MachineInstr *MI, switch(MI->getOpcode()) { case Hexagon::A2_tfr: { // A COPY instruction can be combined if its arguments are IntRegs (32bit). - assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg()); + const MachineOperand &Op0 = MI->getOperand(0); + const MachineOperand &Op1 = MI->getOperand(1); + assert(Op0.isReg() && Op1.isReg()); - unsigned DestReg = MI->getOperand(0).getReg(); - unsigned SrcReg = MI->getOperand(1).getReg(); + unsigned DestReg = Op0.getReg(); + unsigned SrcReg = Op1.getReg(); return Hexagon::IntRegsRegClass.contains(DestReg) && - Hexagon::IntRegsRegClass.contains(SrcReg); + Hexagon::IntRegsRegClass.contains(SrcReg); } case Hexagon::A2_tfrsi: { @@ -144,21 +146,6 @@ static bool isCombinableInstType(MachineInstr *MI, (ShouldCombineAggressively || NotExt); } - case Hexagon::TFRI_V4: { - if (!ShouldCombineAggressively) - return false; - assert(MI->getOperand(0).isReg() && MI->getOperand(1).isGlobal()); - - // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a - // workaround for an ABI bug that prevents GOT relocations on combine - // instructions - if (MI->getOperand(1).getTargetFlags() != HexagonII::MO_NO_FLAG) - return false; - - unsigned DestReg = MI->getOperand(0).getReg(); - return Hexagon::IntRegsRegClass.contains(DestReg); - } - default: break; } @@ -166,13 +153,14 @@ static bool isCombinableInstType(MachineInstr *MI, return false; } -static bool isGreaterThan8BitTFRI(MachineInstr *I) { - return I->getOpcode() == Hexagon::A2_tfrsi && - !isInt<8>(I->getOperand(1).getImm()); -} -static bool isGreaterThan6BitTFRI(MachineInstr *I) { - return I->getOpcode() == Hexagon::A2_tfrsi && - !isUInt<6>(I->getOperand(1).getImm()); +template +static bool isGreaterThanNBitTFRI(const MachineInstr *I) { + if (I->getOpcode() == Hexagon::TFRI64_V4 || + I->getOpcode() == Hexagon::A2_tfrsi) { + const MachineOperand &Op = I->getOperand(1); + return !Op.isImm() || !isInt(Op.getImm()); + } + return false; } /// areCombinableOperations - Returns true if the two instruction can be merge @@ -180,19 +168,15 @@ static bool isGreaterThan6BitTFRI(MachineInstr *I) { static bool areCombinableOperations(const TargetRegisterInfo *TRI, MachineInstr *HighRegInst, MachineInstr *LowRegInst) { - assert((HighRegInst->getOpcode() == Hexagon::A2_tfr || - HighRegInst->getOpcode() == Hexagon::A2_tfrsi || - HighRegInst->getOpcode() == Hexagon::TFRI_V4) && - (LowRegInst->getOpcode() == Hexagon::A2_tfr || - LowRegInst->getOpcode() == Hexagon::A2_tfrsi || - LowRegInst->getOpcode() == Hexagon::TFRI_V4) && + unsigned HiOpc = HighRegInst->getOpcode(); + unsigned LoOpc = LowRegInst->getOpcode(); + assert((HiOpc == Hexagon::A2_tfr || HiOpc == Hexagon::A2_tfrsi) && + (LoOpc == Hexagon::A2_tfr || LoOpc == Hexagon::A2_tfrsi) && "Assume individual instructions are of a combinable type"); // There is no combine of two constant extended values. - if ((HighRegInst->getOpcode() == Hexagon::TFRI_V4 || - isGreaterThan8BitTFRI(HighRegInst)) && - (LowRegInst->getOpcode() == Hexagon::TFRI_V4 || - isGreaterThan6BitTFRI(LowRegInst))) + if (isGreaterThanNBitTFRI<8>(HighRegInst) && + isGreaterThanNBitTFRI<6>(LowRegInst)) return false; return true; @@ -219,10 +203,14 @@ static bool isUnsafeToMoveAcross(MachineInstr *I, unsigned UseReg, unsigned DestReg, const TargetRegisterInfo *TRI) { return (UseReg && (I->modifiesRegister(UseReg, TRI))) || - I->modifiesRegister(DestReg, TRI) || - I->readsRegister(DestReg, TRI) || - I->hasUnmodeledSideEffects() || - I->isInlineAsm() || I->isDebugValue(); + I->modifiesRegister(DestReg, TRI) || + I->readsRegister(DestReg, TRI) || + I->hasUnmodeledSideEffects() || + I->isInlineAsm() || I->isDebugValue(); +} + +static unsigned UseReg(const MachineOperand& MO) { + return MO.isReg() ? MO.getReg() : 0; } /// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such @@ -232,9 +220,7 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, unsigned I1DestReg, unsigned I2DestReg, bool &DoInsertAtI1) { - - bool IsImmUseReg = I2->getOperand(1).isImm() || I2->getOperand(1).isGlobal(); - unsigned I2UseReg = IsImmUseReg ? 0 : I2->getOperand(1).getReg(); + unsigned I2UseReg = UseReg(I2->getOperand(1)); // It is not safe to move I1 and I2 into one combine if I2 has a true // dependence on I1. @@ -298,8 +284,7 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, // At O3 we got better results (dhrystone) by being more conservative here. if (!ShouldCombineAggressively) End = std::next(MachineBasicBlock::iterator(I2)); - IsImmUseReg = I1->getOperand(1).isImm() || I1->getOperand(1).isGlobal(); - unsigned I1UseReg = IsImmUseReg ? 0 : I1->getOperand(1).getReg(); + unsigned I1UseReg = UseReg(I1->getOperand(1)); // Track killed operands. If we move across an instruction that kills our // operand, we need to update the kill information on the moved I1. It kills // the operand now. @@ -558,7 +543,7 @@ void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt, DebugLoc DL = InsertPt->getDebugLoc(); MachineBasicBlock *BB = InsertPt->getParent(); - // Handle globals. + // Handle globals. if (HiOperand.isGlobal()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), @@ -574,17 +559,64 @@ void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt, return; } - // Handle constant extended immediates. - if (!isInt<8>(HiOperand.getImm())) { - assert(isInt<8>(LoOperand.getImm())); + // Handle block addresses. + if (HiOperand.isBlockAddress()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) - .addImm(HiOperand.getImm()) + .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(), + HiOperand.getTargetFlags()) .addImm(LoOperand.getImm()); return; } + if (LoOperand.isBlockAddress()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) + .addImm(HiOperand.getImm()) + .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(), + LoOperand.getTargetFlags()); + return; + } - if (!isUInt<6>(LoOperand.getImm())) { - assert(isInt<8>(HiOperand.getImm())); + // Handle jump tables. + if (HiOperand.isJTI()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) + .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags()) + .addImm(LoOperand.getImm()); + return; + } + if (LoOperand.isJTI()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) + .addImm(HiOperand.getImm()) + .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags()); + return; + } + + // Handle constant pools. + if (HiOperand.isCPI()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) + .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(), + HiOperand.getTargetFlags()) + .addImm(LoOperand.getImm()); + return; + } + if (LoOperand.isCPI()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) + .addImm(HiOperand.getImm()) + .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(), + LoOperand.getTargetFlags()); + return; + } + + // First preference should be given to Hexagon::A2_combineii instruction + // as it can include U6 (in Hexagon::A4_combineii) as well. + // In this instruction, HiOperand is const extended, if required. + if (isInt<8>(LoOperand.getImm())) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) + .addImm(HiOperand.getImm()) + .addImm(LoOperand.getImm()); + return; + } + + // In this instruction, LoOperand is const extended, if required. + if (isInt<8>(HiOperand.getImm())) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) .addImm(HiOperand.getImm()) .addImm(LoOperand.getImm()); @@ -608,7 +640,7 @@ void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt, DebugLoc DL = InsertPt->getDebugLoc(); MachineBasicBlock *BB = InsertPt->getParent(); - // Handle global. + // Handle globals. if (HiOperand.isGlobal()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), @@ -616,6 +648,29 @@ void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt, .addReg(LoReg, LoRegKillFlag); return; } + // Handle block addresses. + if (HiOperand.isBlockAddress()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) + .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(), + HiOperand.getTargetFlags()) + .addReg(LoReg, LoRegKillFlag); + return; + } + // Handle jump tables. + if (HiOperand.isJTI()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) + .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags()) + .addReg(LoReg, LoRegKillFlag); + return; + } + // Handle constant pools. + if (HiOperand.isCPI()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) + .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(), + HiOperand.getTargetFlags()) + .addReg(LoReg, LoRegKillFlag); + return; + } // Insert new combine instruction. // DoubleRegDest = combine #HiImm, LoReg BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) @@ -641,6 +696,29 @@ void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt, LoOperand.getTargetFlags()); return; } + // Handle block addresses. + if (LoOperand.isBlockAddress()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) + .addReg(HiReg, HiRegKillFlag) + .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(), + LoOperand.getTargetFlags()); + return; + } + // Handle jump tables. + if (LoOperand.isJTI()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) + .addReg(HiOperand.getReg(), HiRegKillFlag) + .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags()); + return; + } + // Handle constant pools. + if (LoOperand.isCPI()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) + .addReg(HiOperand.getReg(), HiRegKillFlag) + .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(), + LoOperand.getTargetFlags()); + return; + } // Insert new combine instruction. // DoubleRegDest = combine HiReg, #LoImm diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index 9658a5a84df1..80b59cabe3de 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -1770,7 +1770,8 @@ bool HexagonInstrInfo::isConstExtended(MachineInstr *MI) const { // We currently only handle isGlobal() because it is the only kind of // object we are going to end up with here for now. // In the future we probably should add isSymbol(), etc. - if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress()) + if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() || + MO.isJTI() || MO.isCPI()) return true; // If the extendable operand is not 'Immediate' type, the instruction should diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td index d297c7535bec..5b1960d58709 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td @@ -4823,12 +4823,6 @@ def CONST32 : CONSTLDInst<(outs IntRegs:$dst), (ins globaladdress:$global), [(set (i32 IntRegs:$dst), (load (HexagonCONST32 tglobaltlsaddr:$global)))]>; -let isReMaterializable = 1, isMoveImm = 1 in -def CONST32_set_jt : CONSTLDInst<(outs IntRegs:$dst), (ins jumptablebase:$jt), - "$dst = CONST32(#$jt)", - [(set (i32 IntRegs:$dst), - (HexagonCONST32 tjumptable:$jt))]>; - let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in def CONST32_Int_Real : CONSTLDInst<(outs IntRegs:$dst), (ins i32imm:$global), "$dst = CONST32(#$global)", @@ -4836,7 +4830,7 @@ def CONST32_Int_Real : CONSTLDInst<(outs IntRegs:$dst), (ins i32imm:$global), // Map TLS addressses to a CONST32 instruction def: Pat<(HexagonCONST32 tglobaltlsaddr:$addr), (A2_tfrsi s16Ext:$addr)>; -def: Pat<(HexagonCONST32 bbl:$label), (A2_tfrsi s16Ext:$label)>; +def: Pat<(HexagonCONST32 bbl:$label), (A2_tfrsi s16Ext:$label)>; let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in def CONST32_Label : LDInst2<(outs IntRegs:$dst), (ins bblabel:$label), @@ -5145,10 +5139,8 @@ def: Pat<(i32 (sext_inreg (Hexagon_ARGEXTEND (i32 IntRegs:$src1)), i16)), def HexagonJT: SDNode<"HexagonISD::JT", SDTIntUnaryOp>; def HexagonCP: SDNode<"HexagonISD::CP", SDTIntUnaryOp>; -def: Pat<(HexagonJT tjumptable:$dst), - (CONST32_set_jt tjumptable:$dst)>; -def: Pat<(HexagonCP tconstpool :$dst), - (CONST32_set_jt tconstpool:$dst)>; +def: Pat<(HexagonJT tjumptable:$dst), (A2_tfrsi s16Ext:$dst)>; +def: Pat<(HexagonCP tconstpool:$dst), (A2_tfrsi s16Ext:$dst)>; // XTYPE/SHIFT // diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td b/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td index 6fa0bb252c68..72503a626f89 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td @@ -499,10 +499,23 @@ multiclass T_LoadAbsReg_Pat { def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2), (HexagonCONST32 tglobaladdr:$src3)))), (MI IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3)>; - def : Pat <(VT (ldOp (add IntRegs:$src1, (HexagonCONST32 tglobaladdr:$src2)))), (MI IntRegs:$src1, 0, tglobaladdr:$src2)>; + + def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2), + (HexagonCONST32 tconstpool:$src3)))), + (MI IntRegs:$src1, u2ImmPred:$src2, tconstpool:$src3)>; + def : Pat <(VT (ldOp (add IntRegs:$src1, + (HexagonCONST32 tconstpool:$src2)))), + (MI IntRegs:$src1, 0, tconstpool:$src2)>; + + def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2), + (HexagonCONST32 tjumptable:$src3)))), + (MI IntRegs:$src1, u2ImmPred:$src2, tjumptable:$src3)>; + def : Pat <(VT (ldOp (add IntRegs:$src1, + (HexagonCONST32 tjumptable:$src2)))), + (MI IntRegs:$src1, 0, tjumptable:$src2)>; } let AddedComplexity = 60 in { diff --git a/llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp b/llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp index 1a4c7ae6f2b7..4efb5f75af62 100644 --- a/llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp @@ -83,19 +83,8 @@ bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) { while (MII != MIE) { MachineInstr *MI = MII; int Opc = MI->getOpcode(); - if (Opc == Hexagon::CONST32_set_jt) { - int DestReg = MI->getOperand(0).getReg(); - MachineOperand &Symbol = MI->getOperand (1); - BuildMI (*MBB, MII, MI->getDebugLoc(), - TII->get(Hexagon::A2_tfrsi), DestReg).addOperand(Symbol); - - // MBB->erase returns the iterator to the next instruction, which is the - // one we want to process next - MII = MBB->erase (MI); - continue; - } - else if (Opc == Hexagon::CONST32_Int_Real && - MI->getOperand(1).isBlockAddress()) { + if (Opc == Hexagon::CONST32_Int_Real && + MI->getOperand(1).isBlockAddress()) { int DestReg = MI->getOperand(0).getReg(); MachineOperand &Symbol = MI->getOperand (1); diff --git a/llvm/test/CodeGen/Hexagon/block-addr.ll b/llvm/test/CodeGen/Hexagon/block-addr.ll index 902765e42ef4..eda167a67f28 100644 --- a/llvm/test/CodeGen/Hexagon/block-addr.ll +++ b/llvm/test/CodeGen/Hexagon/block-addr.ll @@ -1,7 +1,8 @@ ; RUN: llc -march=hexagon < %s | FileCheck %s -; CHECK: r{{[0-9]+}} = CONST32(#.LJTI{{[0-9]+_[0-9]+}}) -; CHECK: r{{[0-9]+}} = memw(r{{[0-9]+}} + r{{[0-9]+<<#[0-9]+}}) +; Allow combine(..##JTI..): +; CHECK: r{{[0-9]+}}{{.*}} = {{.*}}#.LJTI +; CHECK: r{{[0-9]+}} = memw(r{{[0-9]+}}{{ *}}+{{ *}}r{{[0-9]+<<#[0-9]+}}) ; CHECK: jumpr r{{[0-9]+}} define void @main() #0 { diff --git a/llvm/test/CodeGen/Hexagon/tfr-to-combine.ll b/llvm/test/CodeGen/Hexagon/tfr-to-combine.ll index d22d685f7d6b..a257acfeb49b 100644 --- a/llvm/test/CodeGen/Hexagon/tfr-to-combine.ll +++ b/llvm/test/CodeGen/Hexagon/tfr-to-combine.ll @@ -27,7 +27,7 @@ entry: ; Function Attrs: nounwind define i64 @test4() #0 { -; CHECK: combine(#0, ##100) +; CHECK: combine(#0, #100) entry: store i16 100, i16* @b, align 2 store i16 0, i16* @a, align 2