diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp | 207 |
1 files changed, 142 insertions, 65 deletions
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp index 1883ad8..1d6455c 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp @@ -116,38 +116,34 @@ 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: { // A transfer-immediate can be combined if its argument is a signed 8bit // value. - assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); - unsigned DestReg = MI->getOperand(0).getReg(); - - // Only combine constant extended TFRI if we are in aggressive mode. - return Hexagon::IntRegsRegClass.contains(DestReg) && - (ShouldCombineAggressively || isInt<8>(MI->getOperand(1).getImm())); - } - - case Hexagon::TFRI_V4: { - if (!ShouldCombineAggressively) - return false; - assert(MI->getOperand(0).isReg() && MI->getOperand(1).isGlobal()); + const MachineOperand &Op0 = MI->getOperand(0); + const MachineOperand &Op1 = MI->getOperand(1); + assert(Op0.isReg()); + unsigned DestReg = Op0.getReg(); // 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) + if (!Op1.isImm() && Op1.getTargetFlags() != HexagonII::MO_NO_FLAG) return false; - unsigned DestReg = MI->getOperand(0).getReg(); - return Hexagon::IntRegsRegClass.contains(DestReg); + // Only combine constant extended A2_tfrsi if we are in aggressive mode. + bool NotExt = Op1.isImm() && isInt<8>(Op1.getImm()); + return Hexagon::IntRegsRegClass.contains(DestReg) && + (ShouldCombineAggressively || NotExt); } default: @@ -157,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 <unsigned N> +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<N>(Op.getImm()); + } + return false; } /// areCombinableOperations - Returns true if the two instruction can be merge @@ -171,31 +168,17 @@ 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(); + (void)HiOpc; // Fix compiler warning + (void)LoOpc; // Fix compiler warning + 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"); - const HexagonRegisterInfo *QRI = - static_cast<const HexagonRegisterInfo *>(TRI); - - // V4 added some combine variations (mixed immediate and register source - // operands), if we are on < V4 we can only combine 2 register-to-register - // moves and 2 immediate-to-register moves. We also don't have - // constant-extenders. - if (!QRI->Subtarget.hasV4TOps()) - return HighRegInst->getOpcode() == LowRegInst->getOpcode() && - !isGreaterThan8BitTFRI(HighRegInst) && - !isGreaterThan6BitTFRI(LowRegInst); - // 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; @@ -222,10 +205,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 @@ -235,9 +222,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. @@ -301,8 +286,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. @@ -418,7 +402,7 @@ bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) { // Get target info. TRI = MF.getSubtarget().getRegisterInfo(); - TII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo()); + TII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo(); // Combine aggressively (for code size) ShouldCombineAggressively = @@ -561,7 +545,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(), @@ -577,17 +561,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) + .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; + } + + // 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; + } - if (!isUInt<6>(LoOperand.getImm())) { - assert(isInt<8>(HiOperand.getImm())); + // 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()); @@ -611,7 +642,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(), @@ -619,6 +650,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) @@ -644,6 +698,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 |