diff options
author | Sirish Pande <spande@codeaurora.org> | 2012-02-15 18:52:27 +0000 |
---|---|---|
committer | Sirish Pande <spande@codeaurora.org> | 2012-02-15 18:52:27 +0000 |
commit | ab7955b9ce3197215406bc9fc97b22074127d035 (patch) | |
tree | 3d687b6a7fb5ce78376085798a800ac7cbb95c35 | |
parent | 2a4bc1e703335e496e3a78f97d1b1d544aac746d (diff) | |
download | external_llvm-ab7955b9ce3197215406bc9fc97b22074127d035.zip external_llvm-ab7955b9ce3197215406bc9fc97b22074127d035.tar.gz external_llvm-ab7955b9ce3197215406bc9fc97b22074127d035.tar.bz2 |
Optimize redundant sign extends and negation of predicates.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150606 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Hexagon/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib/Target/Hexagon/Hexagon.h | 2 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonAsmPrinter.cpp | 5 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonCFGOptimizer.cpp | 24 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonHardwareLoops.cpp | 4 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonISelDAGToDAG.cpp | 4 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonImmediates.td | 21 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrInfo.cpp | 488 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrInfo.h | 1 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrInfo.td | 86 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrInfoV4.td | 175 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonOptimizeSZExtends.cpp | 129 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonPeephole.cpp | 292 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonSelectCCInfo.td | 12 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonTargetMachine.cpp | 1 |
15 files changed, 1037 insertions, 209 deletions
diff --git a/lib/Target/Hexagon/CMakeLists.txt b/lib/Target/Hexagon/CMakeLists.txt index 0acc211..06040f0 100644 --- a/lib/Target/Hexagon/CMakeLists.txt +++ b/lib/Target/Hexagon/CMakeLists.txt @@ -20,7 +20,7 @@ add_llvm_target(HexagonCodeGen HexagonInstrInfo.cpp HexagonISelDAGToDAG.cpp HexagonISelLowering.cpp - HexagonOptimizeSZExtends.cpp + HexagonPeephole.cpp HexagonRegisterInfo.cpp HexagonRemoveSZExtArgs.cpp HexagonSelectionDAGInfo.cpp diff --git a/lib/Target/Hexagon/Hexagon.h b/lib/Target/Hexagon/Hexagon.h index a5f2279..bbefcaf 100644 --- a/lib/Target/Hexagon/Hexagon.h +++ b/lib/Target/Hexagon/Hexagon.h @@ -35,7 +35,7 @@ namespace llvm { FunctionPass* createHexagonExpandPredSpillCode(HexagonTargetMachine &TM); FunctionPass *createHexagonHardwareLoops(); - FunctionPass *createHexagonOptimizeSZExtends(); + FunctionPass *createHexagonPeephole(); FunctionPass *createHexagonFixupHwLoops(); } // end namespace llvm; diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/lib/Target/Hexagon/HexagonAsmPrinter.cpp index 5402374..4d0c5fa 100644 --- a/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -125,6 +125,11 @@ namespace { O << -value; } + void printHexagonNOneImmOperand(const MachineInstr *MI, unsigned OpNo, + raw_ostream &O) const { + O << -1; + } + void printHexagonMEMriOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { const MachineOperand &MO1 = MI->getOperand(OpNo); diff --git a/lib/Target/Hexagon/HexagonCFGOptimizer.cpp b/lib/Target/Hexagon/HexagonCFGOptimizer.cpp index fc46080..28439eb 100644 --- a/lib/Target/Hexagon/HexagonCFGOptimizer.cpp +++ b/lib/Target/Hexagon/HexagonCFGOptimizer.cpp @@ -51,8 +51,8 @@ private: char HexagonCFGOptimizer::ID = 0; static bool IsConditionalBranch(int Opc) { - return (Opc == Hexagon::JMP_Pred) || (Opc == Hexagon::JMP_PredNot) - || (Opc == Hexagon::JMP_PredPt) || (Opc == Hexagon::JMP_PredNotPt); + return (Opc == Hexagon::JMP_c) || (Opc == Hexagon::JMP_cNot) + || (Opc == Hexagon::JMP_cdnPt) || (Opc == Hexagon::JMP_cdnNotPt); } @@ -67,20 +67,20 @@ HexagonCFGOptimizer::InvertAndChangeJumpTarget(MachineInstr* MI, const HexagonInstrInfo *QII = QTM.getInstrInfo(); int NewOpcode = 0; switch(MI->getOpcode()) { - case Hexagon::JMP_Pred: - NewOpcode = Hexagon::JMP_PredNot; + case Hexagon::JMP_c: + NewOpcode = Hexagon::JMP_cNot; break; - case Hexagon::JMP_PredNot: - NewOpcode = Hexagon::JMP_Pred; + case Hexagon::JMP_cNot: + NewOpcode = Hexagon::JMP_c; break; - case Hexagon::JMP_PredPt: - NewOpcode = Hexagon::JMP_PredNotPt; + case Hexagon::JMP_cdnPt: + NewOpcode = Hexagon::JMP_cdnNotPt; break; - case Hexagon::JMP_PredNotPt: - NewOpcode = Hexagon::JMP_PredPt; + case Hexagon::JMP_cdnNotPt: + NewOpcode = Hexagon::JMP_cdnPt; break; default: @@ -155,8 +155,8 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) { // The target of the unconditional branch must be JumpAroundTarget. // TODO: If not, we should not invert the unconditional branch. MachineBasicBlock* CondBranchTarget = NULL; - if ((MI->getOpcode() == Hexagon::JMP_Pred) || - (MI->getOpcode() == Hexagon::JMP_PredNot)) { + if ((MI->getOpcode() == Hexagon::JMP_c) || + (MI->getOpcode() == Hexagon::JMP_cNot)) { CondBranchTarget = MI->getOperand(1).getMBB(); } diff --git a/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/lib/Target/Hexagon/HexagonHardwareLoops.cpp index c1abc4a..04ea4ed 100644 --- a/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ b/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -517,8 +517,8 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) { // The loop ends with either: // - a conditional branch followed by an unconditional branch, or // - a conditional branch to the loop start. - if (LastI->getOpcode() == Hexagon::JMP_Pred || - LastI->getOpcode() == Hexagon::JMP_PredNot) { + if (LastI->getOpcode() == Hexagon::JMP_c || + LastI->getOpcode() == Hexagon::JMP_cNot) { // delete one and change/add an uncond. branch to out of the loop MachineBasicBlock *BranchTarget = LastI->getOperand(1).getMBB(); LastI = LastMBB->erase(LastI); diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index 0bbb2d2..086f9bc 100644 --- a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -238,7 +238,7 @@ static unsigned doesIntrinsicContainPredicate(unsigned ID) case Intrinsic::hexagon_C2_or: return Hexagon::OR_pp; case Intrinsic::hexagon_C2_not: - return Hexagon::NOT_pp; + return Hexagon::NOT_p; case Intrinsic::hexagon_C2_any8: return Hexagon::ANY_pp; case Intrinsic::hexagon_C2_all8: @@ -1178,7 +1178,7 @@ SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) { SDValue(IntRegTFR, 0)); // not(Pd) - SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_pp, dl, MVT::i1, + SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1, SDValue(Pd, 0)); // xor(not(Pd)) diff --git a/lib/Target/Hexagon/HexagonImmediates.td b/lib/Target/Hexagon/HexagonImmediates.td index 1e3fcb8..0422a43 100644 --- a/lib/Target/Hexagon/HexagonImmediates.td +++ b/lib/Target/Hexagon/HexagonImmediates.td @@ -52,12 +52,12 @@ def s10Imm : Operand<i32> { let PrintMethod = "printHexagonImmOperand"; } -def s8Imm : Operand<i32> { +def s9Imm : Operand<i32> { // For now, we use a generic print function for all operands. let PrintMethod = "printHexagonImmOperand"; } -def s9Imm : Operand<i32> { +def s8Imm : Operand<i32> { // For now, we use a generic print function for all operands. let PrintMethod = "printHexagonImmOperand"; } @@ -197,6 +197,11 @@ def u2Imm : Operand<i32> { let PrintMethod = "printHexagonImmOperand"; } +def u1Imm : Operand<i32> { + // For now, we use a generic print function for all operands. + let PrintMethod = "printHexagonImmOperand"; +} + def n8Imm : Operand<i32> { // For now, we use a generic print function for all operands. let PrintMethod = "printHexagonImmOperand"; @@ -207,6 +212,11 @@ def m6Imm : Operand<i32> { let PrintMethod = "printHexagonImmOperand"; } +def nOneImm : Operand<i32> { + // For now, we use a generic print function for all operands. + let PrintMethod = "printHexagonNOneImmOperand"; +} + // // Immediate predicates // @@ -489,3 +499,10 @@ def n8ImmPred : PatLeaf<(i32 imm), [{ int64_t v = (int64_t)N->getSExtValue(); return (-255 <= v && v <= 0); }]>; + +def nOneImmPred : PatLeaf<(i32 imm), [{ + // nOneImmPred predicate - True if the immediate is -1. + int64_t v = (int64_t)N->getSExtValue(); + return (-1 == v); +}]>; + diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp index a615959..a34b813 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -124,16 +124,16 @@ HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, DebugLoc DL) const{ int BOpc = Hexagon::JMP; - int BccOpc = Hexagon::JMP_Pred; + int BccOpc = Hexagon::JMP_c; assert(TBB && "InsertBranch must not be told to insert a fallthrough"); int regPos = 0; // Check if ReverseBranchCondition has asked to reverse this branch // If we want to reverse the branch an odd number of times, we want - // JMP_PredNot. + // JMP_cNot. if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) { - BccOpc = Hexagon::JMP_PredNot; + BccOpc = Hexagon::JMP_cNot; regPos = 1; } @@ -221,13 +221,13 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, TBB = LastInst->getOperand(0).getMBB(); return false; } - if (LastInst->getOpcode() == Hexagon::JMP_Pred) { + if (LastInst->getOpcode() == Hexagon::JMP_c) { // Block ends with fall-through true condbranch. TBB = LastInst->getOperand(1).getMBB(); Cond.push_back(LastInst->getOperand(0)); return false; } - if (LastInst->getOpcode() == Hexagon::JMP_PredNot) { + if (LastInst->getOpcode() == Hexagon::JMP_cNot) { // Block ends with fall-through false condbranch. TBB = LastInst->getOperand(1).getMBB(); Cond.push_back(MachineOperand::CreateImm(0)); @@ -248,7 +248,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, // If the block ends with Hexagon::BRCOND and Hexagon:JMP, handle it. if (((SecondLastInst->getOpcode() == Hexagon::BRCOND) || - (SecondLastInst->getOpcode() == Hexagon::JMP_Pred)) && + (SecondLastInst->getOpcode() == Hexagon::JMP_c)) && LastInst->getOpcode() == Hexagon::JMP) { TBB = SecondLastInst->getOperand(1).getMBB(); Cond.push_back(SecondLastInst->getOperand(0)); @@ -256,8 +256,8 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, return false; } - // If the block ends with Hexagon::JMP_PredNot and Hexagon:JMP, handle it. - if ((SecondLastInst->getOpcode() == Hexagon::JMP_PredNot) && + // If the block ends with Hexagon::JMP_cNot and Hexagon:JMP, handle it. + if ((SecondLastInst->getOpcode() == Hexagon::JMP_cNot) && LastInst->getOpcode() == Hexagon::JMP) { TBB = SecondLastInst->getOperand(1).getMBB(); Cond.push_back(MachineOperand::CreateImm(0)); @@ -284,8 +284,8 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { int BOpc = Hexagon::JMP; - int BccOpc = Hexagon::JMP_Pred; - int BccOpcNot = Hexagon::JMP_PredNot; + int BccOpc = Hexagon::JMP_c; + int BccOpcNot = Hexagon::JMP_cNot; MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return 0; @@ -346,9 +346,9 @@ void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB, if (Hexagon::CRRegsRegClass.contains(DestReg, SrcReg)) { BuildMI(MBB, I, DL, get(Hexagon::TFCR), DestReg).addReg(SrcReg); return; - } - - assert (0 && "Unimplemented"); + } + + llvm_unreachable("Unimplemented"); } @@ -557,6 +557,463 @@ bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const { return true; } +unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const { + switch(Opc) { + case Hexagon::TFR_cPt: + return Hexagon::TFR_cNotPt; + case Hexagon::TFR_cNotPt: + return Hexagon::TFR_cPt; + + case Hexagon::TFRI_cPt: + return Hexagon::TFRI_cNotPt; + case Hexagon::TFRI_cNotPt: + return Hexagon::TFRI_cPt; + + case Hexagon::JMP_c: + return Hexagon::JMP_cNot; + case Hexagon::JMP_cNot: + return Hexagon::JMP_c; + + case Hexagon::ADD_ri_cPt: + return Hexagon::ADD_ri_cNotPt; + case Hexagon::ADD_ri_cNotPt: + return Hexagon::ADD_ri_cPt; + + case Hexagon::ADD_rr_cPt: + return Hexagon::ADD_rr_cNotPt; + case Hexagon::ADD_rr_cNotPt: + return Hexagon::ADD_rr_cPt; + + case Hexagon::XOR_rr_cPt: + return Hexagon::XOR_rr_cNotPt; + case Hexagon::XOR_rr_cNotPt: + return Hexagon::XOR_rr_cPt; + + case Hexagon::AND_rr_cPt: + return Hexagon::AND_rr_cNotPt; + case Hexagon::AND_rr_cNotPt: + return Hexagon::AND_rr_cPt; + + case Hexagon::OR_rr_cPt: + return Hexagon::OR_rr_cNotPt; + case Hexagon::OR_rr_cNotPt: + return Hexagon::OR_rr_cPt; + + case Hexagon::SUB_rr_cPt: + return Hexagon::SUB_rr_cNotPt; + case Hexagon::SUB_rr_cNotPt: + return Hexagon::SUB_rr_cPt; + + case Hexagon::COMBINE_rr_cPt: + return Hexagon::COMBINE_rr_cNotPt; + case Hexagon::COMBINE_rr_cNotPt: + return Hexagon::COMBINE_rr_cPt; + + case Hexagon::ASLH_cPt_V4: + return Hexagon::ASLH_cNotPt_V4; + case Hexagon::ASLH_cNotPt_V4: + return Hexagon::ASLH_cPt_V4; + + case Hexagon::ASRH_cPt_V4: + return Hexagon::ASRH_cNotPt_V4; + case Hexagon::ASRH_cNotPt_V4: + return Hexagon::ASRH_cPt_V4; + + case Hexagon::SXTB_cPt_V4: + return Hexagon::SXTB_cNotPt_V4; + case Hexagon::SXTB_cNotPt_V4: + return Hexagon::SXTB_cPt_V4; + + case Hexagon::SXTH_cPt_V4: + return Hexagon::SXTH_cNotPt_V4; + case Hexagon::SXTH_cNotPt_V4: + return Hexagon::SXTH_cPt_V4; + + case Hexagon::ZXTB_cPt_V4: + return Hexagon::ZXTB_cNotPt_V4; + case Hexagon::ZXTB_cNotPt_V4: + return Hexagon::ZXTB_cPt_V4; + + case Hexagon::ZXTH_cPt_V4: + return Hexagon::ZXTH_cNotPt_V4; + case Hexagon::ZXTH_cNotPt_V4: + return Hexagon::ZXTH_cPt_V4; + + + case Hexagon::JMPR_cPt: + return Hexagon::JMPR_cNotPt; + case Hexagon::JMPR_cNotPt: + return Hexagon::JMPR_cPt; + + // V4 indexed+scaled load. + case Hexagon::LDrid_indexed_cPt_V4: + return Hexagon::LDrid_indexed_cNotPt_V4; + case Hexagon::LDrid_indexed_cNotPt_V4: + return Hexagon::LDrid_indexed_cPt_V4; + + case Hexagon::LDrid_indexed_shl_cPt_V4: + return Hexagon::LDrid_indexed_shl_cNotPt_V4; + case Hexagon::LDrid_indexed_shl_cNotPt_V4: + return Hexagon::LDrid_indexed_shl_cPt_V4; + + case Hexagon::LDrib_indexed_cPt_V4: + return Hexagon::LDrib_indexed_cNotPt_V4; + case Hexagon::LDrib_indexed_cNotPt_V4: + return Hexagon::LDrib_indexed_cPt_V4; + + case Hexagon::LDriub_indexed_cPt_V4: + return Hexagon::LDriub_indexed_cNotPt_V4; + case Hexagon::LDriub_indexed_cNotPt_V4: + return Hexagon::LDriub_indexed_cPt_V4; + + case Hexagon::LDrib_indexed_shl_cPt_V4: + return Hexagon::LDrib_indexed_shl_cNotPt_V4; + case Hexagon::LDrib_indexed_shl_cNotPt_V4: + return Hexagon::LDrib_indexed_shl_cPt_V4; + + case Hexagon::LDriub_indexed_shl_cPt_V4: + return Hexagon::LDriub_indexed_shl_cNotPt_V4; + case Hexagon::LDriub_indexed_shl_cNotPt_V4: + return Hexagon::LDriub_indexed_shl_cPt_V4; + + case Hexagon::LDrih_indexed_cPt_V4: + return Hexagon::LDrih_indexed_cNotPt_V4; + case Hexagon::LDrih_indexed_cNotPt_V4: + return Hexagon::LDrih_indexed_cPt_V4; + + case Hexagon::LDriuh_indexed_cPt_V4: + return Hexagon::LDriuh_indexed_cNotPt_V4; + case Hexagon::LDriuh_indexed_cNotPt_V4: + return Hexagon::LDriuh_indexed_cPt_V4; + + case Hexagon::LDrih_indexed_shl_cPt_V4: + return Hexagon::LDrih_indexed_shl_cNotPt_V4; + case Hexagon::LDrih_indexed_shl_cNotPt_V4: + return Hexagon::LDrih_indexed_shl_cPt_V4; + + case Hexagon::LDriuh_indexed_shl_cPt_V4: + return Hexagon::LDriuh_indexed_shl_cNotPt_V4; + case Hexagon::LDriuh_indexed_shl_cNotPt_V4: + return Hexagon::LDriuh_indexed_shl_cPt_V4; + + case Hexagon::LDriw_indexed_cPt_V4: + return Hexagon::LDriw_indexed_cNotPt_V4; + case Hexagon::LDriw_indexed_cNotPt_V4: + return Hexagon::LDriw_indexed_cPt_V4; + + case Hexagon::LDriw_indexed_shl_cPt_V4: + return Hexagon::LDriw_indexed_shl_cNotPt_V4; + case Hexagon::LDriw_indexed_shl_cNotPt_V4: + return Hexagon::LDriw_indexed_shl_cPt_V4; + + // Byte. + case Hexagon::POST_STbri_cPt: + return Hexagon::POST_STbri_cNotPt; + case Hexagon::POST_STbri_cNotPt: + return Hexagon::POST_STbri_cPt; + + case Hexagon::STrib_cPt: + return Hexagon::STrib_cNotPt; + case Hexagon::STrib_cNotPt: + return Hexagon::STrib_cPt; + + case Hexagon::STrib_indexed_cPt: + return Hexagon::STrib_indexed_cNotPt; + case Hexagon::STrib_indexed_cNotPt: + return Hexagon::STrib_indexed_cPt; + + case Hexagon::STrib_imm_cPt_V4: + return Hexagon::STrib_imm_cNotPt_V4; + case Hexagon::STrib_imm_cNotPt_V4: + return Hexagon::STrib_imm_cPt_V4; + + case Hexagon::STrib_indexed_shl_cPt_V4: + return Hexagon::STrib_indexed_shl_cNotPt_V4; + case Hexagon::STrib_indexed_shl_cNotPt_V4: + return Hexagon::STrib_indexed_shl_cPt_V4; + + // Halfword. + case Hexagon::POST_SThri_cPt: + return Hexagon::POST_SThri_cNotPt; + case Hexagon::POST_SThri_cNotPt: + return Hexagon::POST_SThri_cPt; + + case Hexagon::STrih_cPt: + return Hexagon::STrih_cNotPt; + case Hexagon::STrih_cNotPt: + return Hexagon::STrih_cPt; + + case Hexagon::STrih_indexed_cPt: + return Hexagon::STrih_indexed_cNotPt; + case Hexagon::STrih_indexed_cNotPt: + return Hexagon::STrih_indexed_cPt; + + case Hexagon::STrih_imm_cPt_V4: + return Hexagon::STrih_imm_cNotPt_V4; + case Hexagon::STrih_imm_cNotPt_V4: + return Hexagon::STrih_imm_cPt_V4; + + case Hexagon::STrih_indexed_shl_cPt_V4: + return Hexagon::STrih_indexed_shl_cNotPt_V4; + case Hexagon::STrih_indexed_shl_cNotPt_V4: + return Hexagon::STrih_indexed_shl_cPt_V4; + + // Word. + case Hexagon::POST_STwri_cPt: + return Hexagon::POST_STwri_cNotPt; + case Hexagon::POST_STwri_cNotPt: + return Hexagon::POST_STwri_cPt; + + case Hexagon::STriw_cPt: + return Hexagon::STriw_cNotPt; + case Hexagon::STriw_cNotPt: + return Hexagon::STriw_cPt; + + case Hexagon::STriw_indexed_cPt: + return Hexagon::STriw_indexed_cNotPt; + case Hexagon::STriw_indexed_cNotPt: + return Hexagon::STriw_indexed_cPt; + + case Hexagon::STriw_indexed_shl_cPt_V4: + return Hexagon::STriw_indexed_shl_cNotPt_V4; + case Hexagon::STriw_indexed_shl_cNotPt_V4: + return Hexagon::STriw_indexed_shl_cPt_V4; + + case Hexagon::STriw_imm_cPt_V4: + return Hexagon::STriw_imm_cNotPt_V4; + case Hexagon::STriw_imm_cNotPt_V4: + return Hexagon::STriw_imm_cPt_V4; + + // Double word. + case Hexagon::POST_STdri_cPt: + return Hexagon::POST_STdri_cNotPt; + case Hexagon::POST_STdri_cNotPt: + return Hexagon::POST_STdri_cPt; + + case Hexagon::STrid_cPt: + return Hexagon::STrid_cNotPt; + case Hexagon::STrid_cNotPt: + return Hexagon::STrid_cPt; + + case Hexagon::STrid_indexed_cPt: + return Hexagon::STrid_indexed_cNotPt; + case Hexagon::STrid_indexed_cNotPt: + return Hexagon::STrid_indexed_cPt; + + case Hexagon::STrid_indexed_shl_cPt_V4: + return Hexagon::STrid_indexed_shl_cNotPt_V4; + case Hexagon::STrid_indexed_shl_cNotPt_V4: + return Hexagon::STrid_indexed_shl_cPt_V4; + + // Load. + case Hexagon::LDrid_cPt: + return Hexagon::LDrid_cNotPt; + case Hexagon::LDrid_cNotPt: + return Hexagon::LDrid_cPt; + + case Hexagon::LDriw_cPt: + return Hexagon::LDriw_cNotPt; + case Hexagon::LDriw_cNotPt: + return Hexagon::LDriw_cPt; + + case Hexagon::LDrih_cPt: + return Hexagon::LDrih_cNotPt; + case Hexagon::LDrih_cNotPt: + return Hexagon::LDrih_cPt; + + case Hexagon::LDriuh_cPt: + return Hexagon::LDriuh_cNotPt; + case Hexagon::LDriuh_cNotPt: + return Hexagon::LDriuh_cPt; + + case Hexagon::LDrib_cPt: + return Hexagon::LDrib_cNotPt; + case Hexagon::LDrib_cNotPt: + return Hexagon::LDrib_cPt; + + case Hexagon::LDriub_cPt: + return Hexagon::LDriub_cNotPt; + case Hexagon::LDriub_cNotPt: + return Hexagon::LDriub_cPt; + + // Load Indexed. + case Hexagon::LDrid_indexed_cPt: + return Hexagon::LDrid_indexed_cNotPt; + case Hexagon::LDrid_indexed_cNotPt: + return Hexagon::LDrid_indexed_cPt; + + case Hexagon::LDriw_indexed_cPt: + return Hexagon::LDriw_indexed_cNotPt; + case Hexagon::LDriw_indexed_cNotPt: + return Hexagon::LDriw_indexed_cPt; + + case Hexagon::LDrih_indexed_cPt: + return Hexagon::LDrih_indexed_cNotPt; + case Hexagon::LDrih_indexed_cNotPt: + return Hexagon::LDrih_indexed_cPt; + + case Hexagon::LDriuh_indexed_cPt: + return Hexagon::LDriuh_indexed_cNotPt; + case Hexagon::LDriuh_indexed_cNotPt: + return Hexagon::LDriuh_indexed_cPt; + + case Hexagon::LDrib_indexed_cPt: + return Hexagon::LDrib_indexed_cNotPt; + case Hexagon::LDrib_indexed_cNotPt: + return Hexagon::LDrib_indexed_cPt; + + case Hexagon::LDriub_indexed_cPt: + return Hexagon::LDriub_indexed_cNotPt; + case Hexagon::LDriub_indexed_cNotPt: + return Hexagon::LDriub_indexed_cPt; + + // Post Inc Load. + case Hexagon::POST_LDrid_cPt: + return Hexagon::POST_LDrid_cNotPt; + case Hexagon::POST_LDriw_cNotPt: + return Hexagon::POST_LDriw_cPt; + + case Hexagon::POST_LDrih_cPt: + return Hexagon::POST_LDrih_cNotPt; + case Hexagon::POST_LDrih_cNotPt: + return Hexagon::POST_LDrih_cPt; + + case Hexagon::POST_LDriuh_cPt: + return Hexagon::POST_LDriuh_cNotPt; + case Hexagon::POST_LDriuh_cNotPt: + return Hexagon::POST_LDriuh_cPt; + + case Hexagon::POST_LDrib_cPt: + return Hexagon::POST_LDrib_cNotPt; + case Hexagon::POST_LDrib_cNotPt: + return Hexagon::POST_LDrib_cPt; + + case Hexagon::POST_LDriub_cPt: + return Hexagon::POST_LDriub_cNotPt; + case Hexagon::POST_LDriub_cNotPt: + return Hexagon::POST_LDriub_cPt; + + // Dealloc_return. + case Hexagon::DEALLOC_RET_cPt_V4: + return Hexagon::DEALLOC_RET_cNotPt_V4; + case Hexagon::DEALLOC_RET_cNotPt_V4: + return Hexagon::DEALLOC_RET_cPt_V4; + + // New Value Jump. + // JMPEQ_ri - with -1. + case Hexagon::JMP_EQriPtneg_nv_V4: + return Hexagon::JMP_EQriNotPtneg_nv_V4; + case Hexagon::JMP_EQriNotPtneg_nv_V4: + return Hexagon::JMP_EQriPtneg_nv_V4; + + case Hexagon::JMP_EQriPntneg_nv_V4: + return Hexagon::JMP_EQriNotPntneg_nv_V4; + case Hexagon::JMP_EQriNotPntneg_nv_V4: + return Hexagon::JMP_EQriPntneg_nv_V4; + + // JMPEQ_ri. + case Hexagon::JMP_EQriPt_nv_V4: + return Hexagon::JMP_EQriNotPt_nv_V4; + case Hexagon::JMP_EQriNotPt_nv_V4: + return Hexagon::JMP_EQriPt_nv_V4; + + case Hexagon::JMP_EQriPnt_nv_V4: + return Hexagon::JMP_EQriNotPnt_nv_V4; + case Hexagon::JMP_EQriNotPnt_nv_V4: + return Hexagon::JMP_EQriPnt_nv_V4; + + // JMPEQ_rr. + case Hexagon::JMP_EQrrPt_nv_V4: + return Hexagon::JMP_EQrrNotPt_nv_V4; + case Hexagon::JMP_EQrrNotPt_nv_V4: + return Hexagon::JMP_EQrrPt_nv_V4; + + case Hexagon::JMP_EQrrPnt_nv_V4: + return Hexagon::JMP_EQrrNotPnt_nv_V4; + case Hexagon::JMP_EQrrNotPnt_nv_V4: + return Hexagon::JMP_EQrrPnt_nv_V4; + + // JMPGT_ri - with -1. + case Hexagon::JMP_GTriPtneg_nv_V4: + return Hexagon::JMP_GTriNotPtneg_nv_V4; + case Hexagon::JMP_GTriNotPtneg_nv_V4: + return Hexagon::JMP_GTriPtneg_nv_V4; + + case Hexagon::JMP_GTriPntneg_nv_V4: + return Hexagon::JMP_GTriNotPntneg_nv_V4; + case Hexagon::JMP_GTriNotPntneg_nv_V4: + return Hexagon::JMP_GTriPntneg_nv_V4; + + // JMPGT_ri. + case Hexagon::JMP_GTriPt_nv_V4: + return Hexagon::JMP_GTriNotPt_nv_V4; + case Hexagon::JMP_GTriNotPt_nv_V4: + return Hexagon::JMP_GTriPt_nv_V4; + + case Hexagon::JMP_GTriPnt_nv_V4: + return Hexagon::JMP_GTriNotPnt_nv_V4; + case Hexagon::JMP_GTriNotPnt_nv_V4: + return Hexagon::JMP_GTriPnt_nv_V4; + + // JMPGT_rr. + case Hexagon::JMP_GTrrPt_nv_V4: + return Hexagon::JMP_GTrrNotPt_nv_V4; + case Hexagon::JMP_GTrrNotPt_nv_V4: + return Hexagon::JMP_GTrrPt_nv_V4; + + case Hexagon::JMP_GTrrPnt_nv_V4: + return Hexagon::JMP_GTrrNotPnt_nv_V4; + case Hexagon::JMP_GTrrNotPnt_nv_V4: + return Hexagon::JMP_GTrrPnt_nv_V4; + + // JMPGT_rrdn. + case Hexagon::JMP_GTrrdnPt_nv_V4: + return Hexagon::JMP_GTrrdnNotPt_nv_V4; + case Hexagon::JMP_GTrrdnNotPt_nv_V4: + return Hexagon::JMP_GTrrdnPt_nv_V4; + + case Hexagon::JMP_GTrrdnPnt_nv_V4: + return Hexagon::JMP_GTrrdnNotPnt_nv_V4; + case Hexagon::JMP_GTrrdnNotPnt_nv_V4: + return Hexagon::JMP_GTrrdnPnt_nv_V4; + + // JMPGTU_ri. + case Hexagon::JMP_GTUriPt_nv_V4: + return Hexagon::JMP_GTUriNotPt_nv_V4; + case Hexagon::JMP_GTUriNotPt_nv_V4: + return Hexagon::JMP_GTUriPt_nv_V4; + + case Hexagon::JMP_GTUriPnt_nv_V4: + return Hexagon::JMP_GTUriNotPnt_nv_V4; + case Hexagon::JMP_GTUriNotPnt_nv_V4: + return Hexagon::JMP_GTUriPnt_nv_V4; + + // JMPGTU_rr. + case Hexagon::JMP_GTUrrPt_nv_V4: + return Hexagon::JMP_GTUrrNotPt_nv_V4; + case Hexagon::JMP_GTUrrNotPt_nv_V4: + return Hexagon::JMP_GTUrrPt_nv_V4; + + case Hexagon::JMP_GTUrrPnt_nv_V4: + return Hexagon::JMP_GTUrrNotPnt_nv_V4; + case Hexagon::JMP_GTUrrNotPnt_nv_V4: + return Hexagon::JMP_GTUrrPnt_nv_V4; + + // JMPGTU_rrdn. + case Hexagon::JMP_GTUrrdnPt_nv_V4: + return Hexagon::JMP_GTUrrdnNotPt_nv_V4; + case Hexagon::JMP_GTUrrdnNotPt_nv_V4: + return Hexagon::JMP_GTUrrdnPt_nv_V4; + + case Hexagon::JMP_GTUrrdnPnt_nv_V4: + return Hexagon::JMP_GTUrrdnNotPnt_nv_V4; + case Hexagon::JMP_GTUrrdnNotPnt_nv_V4: + return Hexagon::JMP_GTUrrdnPnt_nv_V4; + + default: + llvm_unreachable("Unexpected predicated instruction"); + } +} int HexagonInstrInfo:: @@ -569,8 +1026,8 @@ getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const { return !invertPredicate ? Hexagon::TFRI_cPt : Hexagon::TFRI_cNotPt; case Hexagon::JMP: - return !invertPredicate ? Hexagon::JMP_Pred : - Hexagon::JMP_PredNot; + return !invertPredicate ? Hexagon::JMP_c : + Hexagon::JMP_cNot; case Hexagon::ADD_ri: return !invertPredicate ? Hexagon::ADD_ri_cPt : Hexagon::ADD_ri_cNotPt; @@ -1064,7 +1521,6 @@ isValidAutoIncImm(const EVT VT, const int Offset) const { return (Offset >= Hexagon_MEMB_AUTOINC_MIN && Offset <= Hexagon_MEMB_AUTOINC_MAX); } - llvm_unreachable("Not an auto-inc opc!"); } diff --git a/lib/Target/Hexagon/HexagonInstrInfo.h b/lib/Target/Hexagon/HexagonInstrInfo.h index 8be1ef3..1e3ba01 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.h +++ b/lib/Target/Hexagon/HexagonInstrInfo.h @@ -163,6 +163,7 @@ public: bool isConditionalALU32 (const MachineInstr* MI) const; bool isConditionalLoad (const MachineInstr* MI) const; bool isDeallocRet(const MachineInstr *MI) const; + unsigned getInvertedPredicatedOpcode(const int Opc) const; private: int getMatchingCondBranchOpcode(int Opc, bool sense) const; diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index a0e5c97..da8c548 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -695,10 +695,6 @@ def AND_pnotp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, "$dst = and($src1, !$src2)", []>; -def NOT_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1), - "$dst = not($src1)", - [(set PredRegs:$dst, (not PredRegs:$src1))]>; - def ANY_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1), "$dst = any8($src1)", []>; @@ -728,7 +724,7 @@ def MASK_p : SInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1), "$dst = mask($src1)", []>; -def NOT_Ps : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1), +def NOT_p : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1), "$dst = not($src1)", [(set PredRegs:$dst, (not PredRegs:$src1))]>; @@ -761,7 +757,7 @@ let isBranch = 1, isTerminator=1, isBarrier = 1, isPredicable = 1 in { // if (p0) jump let isBranch = 1, isTerminator=1, Defs = [PC], isPredicated = 1 in { - def JMP_Pred : JInst< (outs), + def JMP_c : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if ($src) jump $offset", [(brcond PredRegs:$src, bb:$offset)]>; @@ -770,7 +766,7 @@ let isBranch = 1, isTerminator=1, Defs = [PC], // if (!p0) jump let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], isPredicated = 1 in { - def JMP_PredNot : JInst< (outs), + def JMP_cNot : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if (!$src) jump $offset", []>; @@ -787,7 +783,7 @@ let isTerminator = 1, isBranch = 1, neverHasSideEffects = 1, Defs = [PC], // if (p0) jump:t let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], isPredicated = 1 in { - def JMP_PredPt : JInst< (outs), + def JMP_cdnPt : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if ($src.new) jump:t $offset", []>; @@ -796,7 +792,7 @@ let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], // if (!p0) jump:t let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], isPredicated = 1 in { - def JMP_PredNotPt : JInst< (outs), + def JMP_cdnNotPt : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if (!$src.new) jump:t $offset", []>; @@ -805,7 +801,7 @@ let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], // Not taken. let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], isPredicated = 1 in { - def JMP_PredPnt : JInst< (outs), + def JMP_cdnPnt : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if ($src.new) jump:nt $offset", []>; @@ -814,7 +810,7 @@ let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], // Not taken. let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], isPredicated = 1 in { - def JMP_PredNotPnt : JInst< (outs), + def JMP_cdnNotPnt : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if (!$src.new) jump:nt $offset", []>; @@ -2268,6 +2264,20 @@ def TFR_condset_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src3))]>; let AddedComplexity = 100 in +def TFR_condset_ri : ALU32_rr<(outs IntRegs:$dst), + (ins PredRegs:$src1, IntRegs:$src2, s12Imm:$src3), + "Error; should not emit", + [(set IntRegs:$dst, + (select PredRegs:$src1, IntRegs:$src2, s12ImmPred:$src3))]>; + +let AddedComplexity = 100 in +def TFR_condset_ir : ALU32_rr<(outs IntRegs:$dst), + (ins PredRegs:$src1, s12Imm:$src2, IntRegs:$src3), + "Error; should not emit", + [(set IntRegs:$dst, + (select PredRegs:$src1, s12ImmPred:$src2, IntRegs:$src3))]>; + +let AddedComplexity = 100 in def TFR_condset_ii : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, s12Imm:$src2, s12Imm:$src3), "Error; should not emit", @@ -2460,7 +2470,7 @@ def : Pat <(and IntRegs:$src1, 255), // Add(p1, false) should never be produced, // if it does, it got to be mapped to NOOP. def : Pat <(add PredRegs:$src1, -1), - (NOT_pp PredRegs:$src1)>; + (NOT_p PredRegs:$src1)>; // Map from p0 = setlt(r0, r1) r2 = mux(p0, r3, r4) => // p0 = cmp.lt(r0, r1), r0 = mux(p0, r2, r1). @@ -2475,7 +2485,7 @@ def : Pat <(select (not PredRegs:$src1), s8ImmPred:$src2, s8ImmPred:$src3), // Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump. def : Pat <(brcond (not PredRegs:$src1), bb:$offset), - (JMP_PredNot PredRegs:$src1, bb:$offset)>; + (JMP_cNot PredRegs:$src1, bb:$offset)>; // Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2). def : Pat <(and PredRegs:$src1, (not PredRegs:$src2)), @@ -2674,39 +2684,39 @@ def : Pat <(i64 (sext_inreg DoubleRegs:$src1, i8)), (i64 (SXTW (SXTB (EXTRACT_SUBREG DoubleRegs:$src1, subreg_loreg))))>; // We want to prevent emiting pnot's as much as possible. -// Map brcond with an unsupported setcc to a JMP_PredNot. +// Map brcond with an unsupported setcc to a JMP_cNot. def : Pat <(brcond (i1 (setne IntRegs:$src1, IntRegs:$src2)), bb:$offset), - (JMP_PredNot (CMPEQrr IntRegs:$src1, IntRegs:$src2), bb:$offset)>; + (JMP_cNot (CMPEQrr IntRegs:$src1, IntRegs:$src2), bb:$offset)>; def : Pat <(brcond (i1 (setne IntRegs:$src1, s10ImmPred:$src2)), bb:$offset), - (JMP_PredNot (CMPEQri IntRegs:$src1, s10ImmPred:$src2), bb:$offset)>; + (JMP_cNot (CMPEQri IntRegs:$src1, s10ImmPred:$src2), bb:$offset)>; def : Pat <(brcond (i1 (setne PredRegs:$src1, (i1 -1))), bb:$offset), - (JMP_PredNot PredRegs:$src1, bb:$offset)>; + (JMP_cNot PredRegs:$src1, bb:$offset)>; def : Pat <(brcond (i1 (setne PredRegs:$src1, (i1 0))), bb:$offset), - (JMP_Pred PredRegs:$src1, bb:$offset)>; + (JMP_c PredRegs:$src1, bb:$offset)>; def : Pat <(brcond (i1 (setlt IntRegs:$src1, s8ImmPred:$src2)), bb:$offset), - (JMP_PredNot (CMPGEri IntRegs:$src1, s8ImmPred:$src2), bb:$offset)>; + (JMP_cNot (CMPGEri IntRegs:$src1, s8ImmPred:$src2), bb:$offset)>; def : Pat <(brcond (i1 (setlt IntRegs:$src1, IntRegs:$src2)), bb:$offset), - (JMP_Pred (CMPLTrr IntRegs:$src1, IntRegs:$src2), bb:$offset)>; + (JMP_c (CMPLTrr IntRegs:$src1, IntRegs:$src2), bb:$offset)>; def : Pat <(brcond (i1 (setuge DoubleRegs:$src1, DoubleRegs:$src2)), bb:$offset), - (JMP_PredNot (CMPGTU64rr DoubleRegs:$src2, DoubleRegs:$src1), + (JMP_cNot (CMPGTU64rr DoubleRegs:$src2, DoubleRegs:$src1), bb:$offset)>; def : Pat <(brcond (i1 (setule IntRegs:$src1, IntRegs:$src2)), bb:$offset), - (JMP_PredNot (CMPGTUrr IntRegs:$src1, IntRegs:$src2), bb:$offset)>; + (JMP_cNot (CMPGTUrr IntRegs:$src1, IntRegs:$src2), bb:$offset)>; def : Pat <(brcond (i1 (setule DoubleRegs:$src1, DoubleRegs:$src2)), bb:$offset), - (JMP_PredNot (CMPGTU64rr DoubleRegs:$src1, DoubleRegs:$src2), + (JMP_cNot (CMPGTU64rr DoubleRegs:$src1, DoubleRegs:$src2), bb:$offset)>; -// Map from a 64-bit select to an emulated 64-bit mux. +// Map from a 64-bit select to an emulated 64-bit mux. // Hexagon does not support 64-bit MUXes; so emulate with combines. def : Pat <(select PredRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3), (COMBINE_rr @@ -2721,7 +2731,7 @@ def : Pat <(select PredRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3), // From LegalizeDAG.cpp: (B1 ? B2 : B3) <=> (B1 & B2)|(!B1&B3). def : Pat <(select PredRegs:$src1, PredRegs:$src2, PredRegs:$src3), (OR_pp (AND_pp PredRegs:$src1, PredRegs:$src2), - (AND_pp (NOT_pp PredRegs:$src1), PredRegs:$src3))>; + (AND_pp (NOT_p PredRegs:$src1), PredRegs:$src3))>; // Map Pd = load(addr) -> Rs = load(addr); Pd = Rs. def : Pat<(i1 (load ADDRriS11_2:$addr)), @@ -2773,26 +2783,26 @@ def : Pat<(i64 (anyext IntRegs:$src1)), // Map cmple -> cmpgt. // rs <= rt -> !(rs > rt). def : Pat<(i1 (setle IntRegs:$src1, s10ImmPred:$src2)), - (i1 (NOT_Ps (CMPGTri IntRegs:$src1, s10ImmPred:$src2)))>; + (i1 (NOT_p (CMPGTri IntRegs:$src1, s10ImmPred:$src2)))>; // rs <= rt -> !(rs > rt). def : Pat<(i1 (setle IntRegs:$src1, IntRegs:$src2)), - (i1 (NOT_Ps (CMPGTrr IntRegs:$src1, IntRegs:$src2)))>; + (i1 (NOT_p (CMPGTrr IntRegs:$src1, IntRegs:$src2)))>; // Rss <= Rtt -> !(Rss > Rtt). def : Pat<(i1 (setle DoubleRegs:$src1, DoubleRegs:$src2)), - (i1 (NOT_Ps (CMPGT64rr DoubleRegs:$src1, DoubleRegs:$src2)))>; + (i1 (NOT_p (CMPGT64rr DoubleRegs:$src1, DoubleRegs:$src2)))>; // Map cmpne -> cmpeq. // Hexagon_TODO: We should improve on this. // rs != rt -> !(rs == rt). def : Pat <(i1 (setne IntRegs:$src1, s10ImmPred:$src2)), - (i1 (NOT_Ps(i1 (CMPEQri IntRegs:$src1, s10ImmPred:$src2))))>; + (i1 (NOT_p(i1 (CMPEQri IntRegs:$src1, s10ImmPred:$src2))))>; // Map cmpne(Rs) -> !cmpeqe(Rs). // rs != rt -> !(rs == rt). def : Pat <(i1 (setne IntRegs:$src1, IntRegs:$src2)), - (i1 (NOT_Ps(i1 (CMPEQrr IntRegs:$src1, IntRegs:$src2))))>; + (i1 (NOT_p(i1 (CMPEQrr IntRegs:$src1, IntRegs:$src2))))>; // Convert setne back to xor for hexagon since we compute w/ pred registers. def : Pat <(i1 (setne PredRegs:$src1, PredRegs:$src2)), @@ -2801,12 +2811,12 @@ def : Pat <(i1 (setne PredRegs:$src1, PredRegs:$src2)), // Map cmpne(Rss) -> !cmpew(Rss). // rs != rt -> !(rs == rt). def : Pat <(i1 (setne DoubleRegs:$src1, DoubleRegs:$src2)), - (i1 (NOT_Ps(i1 (CMPEHexagon4rr DoubleRegs:$src1, DoubleRegs:$src2))))>; + (i1 (NOT_p(i1 (CMPEHexagon4rr DoubleRegs:$src1, DoubleRegs:$src2))))>; // Map cmpge(Rs, Rt) -> !(cmpgt(Rs, Rt). // rs >= rt -> !(rt > rs). def : Pat <(i1 (setge IntRegs:$src1, IntRegs:$src2)), - (i1 (NOT_Ps(i1 (CMPGTrr IntRegs:$src2, IntRegs:$src1))))>; + (i1 (NOT_p(i1 (CMPGTrr IntRegs:$src2, IntRegs:$src1))))>; def : Pat <(i1 (setge IntRegs:$src1, s8ImmPred:$src2)), (i1 (CMPGEri IntRegs:$src1, s8ImmPred:$src2))>; @@ -2814,12 +2824,12 @@ def : Pat <(i1 (setge IntRegs:$src1, s8ImmPred:$src2)), // Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss). // rss >= rtt -> !(rtt > rss). def : Pat <(i1 (setge DoubleRegs:$src1, DoubleRegs:$src2)), - (i1 (NOT_Ps(i1 (CMPGT64rr DoubleRegs:$src2, DoubleRegs:$src1))))>; + (i1 (NOT_p(i1 (CMPGT64rr DoubleRegs:$src2, DoubleRegs:$src1))))>; // Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm). // rs < rt -> !(rs >= rt). def : Pat <(i1 (setlt IntRegs:$src1, s8ImmPred:$src2)), - (i1 (NOT_Ps (CMPGEri IntRegs:$src1, s8ImmPred:$src2)))>; + (i1 (NOT_p (CMPGEri IntRegs:$src1, s8ImmPred:$src2)))>; // Map cmplt(Rs, Rt) -> cmplt(Rs, Rt). // rs < rt -> rs < rt. Let assembler map it. @@ -2844,22 +2854,22 @@ def : Pat <(i1 (setult DoubleRegs:$src1, DoubleRegs:$src2)), // Map from Rs >= Rt -> !(Rt > Rs). // rs >= rt -> !(rt > rs). def : Pat <(i1 (setuge IntRegs:$src1, IntRegs:$src2)), - (i1 (NOT_Ps (CMPGTUrr IntRegs:$src2, IntRegs:$src1)))>; + (i1 (NOT_p (CMPGTUrr IntRegs:$src2, IntRegs:$src1)))>; // Map from Rs >= Rt -> !(Rt > Rs). // rs >= rt -> !(rt > rs). def : Pat <(i1 (setuge DoubleRegs:$src1, DoubleRegs:$src2)), - (i1 (NOT_Ps (CMPGTU64rr DoubleRegs:$src2, DoubleRegs:$src1)))>; + (i1 (NOT_p (CMPGTU64rr DoubleRegs:$src2, DoubleRegs:$src1)))>; // Map from cmpleu(Rs, Rs) -> !cmpgtu(Rs, Rs). // Map from (Rs <= Rt) -> !(Rs > Rt). def : Pat <(i1 (setule IntRegs:$src1, IntRegs:$src2)), - (i1 (NOT_Ps (CMPGTUrr IntRegs:$src1, IntRegs:$src2)))>; + (i1 (NOT_p (CMPGTUrr IntRegs:$src1, IntRegs:$src2)))>; // Map from cmpleu(Rss, Rtt) -> !cmpgtu(Rss, Rtt-1). // Map from (Rs <= Rt) -> !(Rs > Rt). def : Pat <(i1 (setule DoubleRegs:$src1, DoubleRegs:$src2)), - (i1 (NOT_Ps (CMPGTU64rr DoubleRegs:$src1, DoubleRegs:$src2)))>; + (i1 (NOT_p (CMPGTU64rr DoubleRegs:$src1, DoubleRegs:$src2)))>; // Sign extends. // i1 -> i32 diff --git a/lib/Target/Hexagon/HexagonInstrInfoV4.td b/lib/Target/Hexagon/HexagonInstrInfoV4.td index 30e2c49..9e60cf2 100644 --- a/lib/Target/Hexagon/HexagonInstrInfoV4.td +++ b/lib/Target/Hexagon/HexagonInstrInfoV4.td @@ -2231,6 +2231,181 @@ def POST_STwri_cdnNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), // NV/ST - //===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// NV/J + +//===----------------------------------------------------------------------===// + +multiclass NVJ_type_basic_reg<string NotStr, string OpcStr, string TakenStr> { + def _ie_nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, $src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; + + def _nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, $src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; +} + +multiclass NVJ_type_basic_2ndDotNew<string NotStr, string OpcStr, string TakenStr> { + def _ie_nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1, $src2.new)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; + + def _nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1, $src2.new)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; +} + +multiclass NVJ_type_basic_imm<string NotStr, string OpcStr, string TakenStr> { + def _ie_nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; + + def _nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; +} + +multiclass NVJ_type_basic_neg<string NotStr, string OpcStr, string TakenStr> { + def _ie_nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; + + def _nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; +} + +multiclass NVJ_type_basic_tstbit<string NotStr, string OpcStr, string TakenStr> { + def _ie_nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; + + def _nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; +} + +// Multiclass for regular dot new of Ist operand register. +multiclass NVJ_type_br_pred_reg<string NotStr, string OpcStr> { + defm Pt : NVJ_type_basic_reg<NotStr, OpcStr, "t">; + defm Pnt : NVJ_type_basic_reg<NotStr, OpcStr, "nt">; +} + +// Multiclass for dot new of 2nd operand register. +multiclass NVJ_type_br_pred_2ndDotNew<string NotStr, string OpcStr> { + defm Pt : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "t">; + defm Pnt : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "nt">; +} + +// Multiclass for 2nd operand immediate, including -1. +multiclass NVJ_type_br_pred_imm<string NotStr, string OpcStr> { + defm Pt : NVJ_type_basic_imm<NotStr, OpcStr, "t">; + defm Pnt : NVJ_type_basic_imm<NotStr, OpcStr, "nt">; + defm Ptneg : NVJ_type_basic_neg<NotStr, OpcStr, "t">; + defm Pntneg : NVJ_type_basic_neg<NotStr, OpcStr, "nt">; +} + +// Multiclass for 2nd operand immediate, excluding -1. +multiclass NVJ_type_br_pred_imm_only<string NotStr, string OpcStr> { + defm Pt : NVJ_type_basic_imm<NotStr, OpcStr, "t">; + defm Pnt : NVJ_type_basic_imm<NotStr, OpcStr, "nt">; +} + +// Multiclass for tstbit, where 2nd operand is always #0. +multiclass NVJ_type_br_pred_tstbit<string NotStr, string OpcStr> { + defm Pt : NVJ_type_basic_tstbit<NotStr, OpcStr, "t">; + defm Pnt : NVJ_type_basic_tstbit<NotStr, OpcStr, "nt">; +} + +// Multiclass for GT. +multiclass NVJ_type_rr_ri<string OpcStr> { + defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>; + defm rr : NVJ_type_br_pred_reg<"", OpcStr>; + defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>; + defm rrdn : NVJ_type_br_pred_2ndDotNew<"", OpcStr>; + defm riNot : NVJ_type_br_pred_imm<"!", OpcStr>; + defm ri : NVJ_type_br_pred_imm<"", OpcStr>; +} + +// Multiclass for EQ. +multiclass NVJ_type_rr_ri_no_2ndDotNew<string OpcStr> { + defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>; + defm rr : NVJ_type_br_pred_reg<"", OpcStr>; + defm riNot : NVJ_type_br_pred_imm<"!", OpcStr>; + defm ri : NVJ_type_br_pred_imm<"", OpcStr>; +} + +// Multiclass for GTU. +multiclass NVJ_type_rr_ri_no_nOne<string OpcStr> { + defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>; + defm rr : NVJ_type_br_pred_reg<"", OpcStr>; + defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>; + defm rrdn : NVJ_type_br_pred_2ndDotNew<"", OpcStr>; + defm riNot : NVJ_type_br_pred_imm_only<"!", OpcStr>; + defm ri : NVJ_type_br_pred_imm_only<"", OpcStr>; +} + +// Multiclass for tstbit. +multiclass NVJ_type_r0<string OpcStr> { + defm r0Not : NVJ_type_br_pred_tstbit<"!", OpcStr>; + defm r0 : NVJ_type_br_pred_tstbit<"", OpcStr>; + } + +// Base Multiclass for New Value Jump. +multiclass NVJ_type { + defm GT : NVJ_type_rr_ri<"cmp.gt">; + defm EQ : NVJ_type_rr_ri_no_2ndDotNew<"cmp.eq">; + defm GTU : NVJ_type_rr_ri_no_nOne<"cmp.gtu">; + defm TSTBIT : NVJ_type_r0<"tstbit">; +} + +let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in { + defm JMP_ : NVJ_type; +} + +//===----------------------------------------------------------------------===// +// NV/J - +//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // XTYPE/ALU + diff --git a/lib/Target/Hexagon/HexagonOptimizeSZExtends.cpp b/lib/Target/Hexagon/HexagonOptimizeSZExtends.cpp deleted file mode 100644 index 1229aca..0000000 --- a/lib/Target/Hexagon/HexagonOptimizeSZExtends.cpp +++ /dev/null @@ -1,129 +0,0 @@ -//===-- HexagonOptimizeSZExtends.cpp - Identify and remove sign and -------===// -//===-- zero extends. -------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Constants.h" -#include "llvm/PassSupport.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/MachineDominators.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineLoopInfo.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/RegisterScavenging.h" -#include "llvm/Support/Debug.h" -#include "llvm/CodeGen/MachineFunctionAnalysis.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetInstrInfo.h" -#include <algorithm> -#include "Hexagon.h" -#include "HexagonTargetMachine.h" - -using namespace llvm; - -namespace { - struct HexagonOptimizeSZExtends : public MachineFunctionPass { - - public: - static char ID; - HexagonOptimizeSZExtends() : MachineFunctionPass(ID) {} - - bool runOnMachineFunction(MachineFunction &MF); - - const char *getPassName() const { - return "Hexagon remove redundant zero and size extends"; - } - - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<MachineFunctionAnalysis>(); - AU.addPreserved<MachineFunctionAnalysis>(); - MachineFunctionPass::getAnalysisUsage(AU); - } - - private: - }; -} - -char HexagonOptimizeSZExtends::ID = 0; - -// This is a brain dead pass to get rid of redundant sign extends for the -// following case: -// -// Transform the following pattern -// %vreg170<def> = SXTW %vreg166 -// ... -// %vreg176<def> = COPY %vreg170:subreg_loreg -// -// Into -// %vreg176<def> = COPY vreg166 - -bool HexagonOptimizeSZExtends::runOnMachineFunction(MachineFunction &MF) { - DenseMap<unsigned, unsigned> SExtMap; - - // Loop over all of the basic blocks - for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end(); - MBBb != MBBe; ++MBBb) { - MachineBasicBlock* MBB = MBBb; - SExtMap.clear(); - - // Traverse the basic block. - for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end(); - ++MII) { - MachineInstr *MI = MII; - // Look for sign extends: - // %vreg170<def> = SXTW %vreg166 - if (MI->getOpcode() == Hexagon::SXTW) { - assert (MI->getNumOperands() == 2); - MachineOperand &Dst = MI->getOperand(0); - MachineOperand &Src = MI->getOperand(1); - unsigned DstReg = Dst.getReg(); - unsigned SrcReg = Src.getReg(); - // Just handle virtual registers. - if (TargetRegisterInfo::isVirtualRegister(DstReg) && - TargetRegisterInfo::isVirtualRegister(SrcReg)) { - // Map the following: - // %vreg170<def> = SXTW %vreg166 - // SExtMap[170] = vreg166 - SExtMap[DstReg] = SrcReg; - } - } - // Look for copy: - // %vreg176<def> = COPY %vreg170:subreg_loreg - if (MI->isCopy()) { - assert (MI->getNumOperands() == 2); - MachineOperand &Dst = MI->getOperand(0); - MachineOperand &Src = MI->getOperand(1); - - // Make sure we are copying the lower 32 bits. - if (Src.getSubReg() != Hexagon::subreg_loreg) - continue; - - unsigned DstReg = Dst.getReg(); - unsigned SrcReg = Src.getReg(); - if (TargetRegisterInfo::isVirtualRegister(DstReg) && - TargetRegisterInfo::isVirtualRegister(SrcReg)) { - // Try to find in the map. - if (unsigned SextSrc = SExtMap.lookup(SrcReg)) { - // Change the 1st operand. - MI->RemoveOperand(1); - MI->addOperand(MachineOperand::CreateReg(SextSrc, false)); - } - } - } - } - } - return true; -} - -FunctionPass *llvm::createHexagonOptimizeSZExtends() { - return new HexagonOptimizeSZExtends(); -} diff --git a/lib/Target/Hexagon/HexagonPeephole.cpp b/lib/Target/Hexagon/HexagonPeephole.cpp new file mode 100644 index 0000000..2dda8fa --- /dev/null +++ b/lib/Target/Hexagon/HexagonPeephole.cpp @@ -0,0 +1,292 @@ +//===-- HexagonPeephole.cpp - Hexagon Peephole Optimiztions ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +// This peephole pass optimizes in the following cases. +// 1. Optimizes redundant sign extends for the following case +// Transform the following pattern +// %vreg170<def> = SXTW %vreg166 +// ... +// %vreg176<def> = COPY %vreg170:subreg_loreg +// +// Into +// %vreg176<def> = COPY vreg166 +// +// 2. Optimizes redundant negation of predicates. +// %vreg15<def> = CMPGTrr %vreg6, %vreg2 +// ... +// %vreg16<def> = NOT_p %vreg15<kill> +// ... +// JMP_c %vreg16<kill>, <BB#1>, %PC<imp-def,dead> +// +// Into +// %vreg15<def> = CMPGTrr %vreg6, %vreg2; +// ... +// JMP_cNot %vreg15<kill>, <BB#1>, %PC<imp-def,dead>; +// +// Note: The peephole pass makes the instrucstions like +// %vreg170<def> = SXTW %vreg166 or %vreg16<def> = NOT_p %vreg15<kill> +// redundant and relies on some form of dead removal instrucions, like +// DCE or DIE to actually eliminate them. + + +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "hexagon-peephole" +#include "llvm/Constants.h" +#include "llvm/PassSupport.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Target/TargetInstrInfo.h" +#include <algorithm> +#include "Hexagon.h" +#include "HexagonTargetMachine.h" + +#include "llvm/Support/CommandLine.h" + +using namespace llvm; + +cl::opt<int> DebugHexagonPeephole("debug-hexagon-peephole", + cl::Hidden, cl::desc("")); + +static cl::opt<bool> DisableHexagonPeephole("disable-hexagon-peephole", + cl::Hidden, cl::ZeroOrMore, cl::init(false), + cl::desc("Disable Peephole Optimization")); + +static cl::opt<int> +DbgPNPCount("pnp-count", cl::init(-1), cl::Hidden, + cl::desc("Maximum number of P=NOT(P) to be optimized")); + +static cl::opt<bool> DisablePNotP("disable-hexagon-pnotp", + cl::Hidden, cl::ZeroOrMore, cl::init(false), + cl::desc("Disable Optimization of PNotP")); + +static cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext", + cl::Hidden, cl::ZeroOrMore, cl::init(false), + cl::desc("Disable Optimization of Sign/Zero Extends")); + +namespace { + struct HexagonPeephole : public MachineFunctionPass { + const HexagonInstrInfo *QII; + const HexagonRegisterInfo *QRI; + const MachineRegisterInfo *MRI; + + public: + static char ID; + HexagonPeephole() : MachineFunctionPass(ID) { } + + bool runOnMachineFunction(MachineFunction &MF); + + const char *getPassName() const { + return "Hexagon optimize redundant zero and size extends"; + } + + void getAnalysisUsage(AnalysisUsage &AU) const { + MachineFunctionPass::getAnalysisUsage(AU); + } + + private: + void ChangeOpInto(MachineOperand &Dst, MachineOperand &Src); + }; +} + +char HexagonPeephole::ID = 0; + +bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) { + + QII = static_cast<const HexagonInstrInfo *>(MF.getTarget(). + getInstrInfo()); + QRI = static_cast<const HexagonRegisterInfo *>(MF.getTarget(). + getRegisterInfo()); + MRI = &MF.getRegInfo(); + + DenseMap<unsigned, unsigned> PeepholeMap; + + if (DisableHexagonPeephole) return false; + + // Loop over all of the basic blocks. + for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end(); + MBBb != MBBe; ++MBBb) { + MachineBasicBlock* MBB = MBBb; + PeepholeMap.clear(); + + // Traverse the basic block. + for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end(); + ++MII) { + MachineInstr *MI = MII; + // Look for sign extends: + // %vreg170<def> = SXTW %vreg166 + if (!DisableOptSZExt && MI->getOpcode() == Hexagon::SXTW) { + assert (MI->getNumOperands() == 2); + MachineOperand &Dst = MI->getOperand(0); + MachineOperand &Src = MI->getOperand(1); + unsigned DstReg = Dst.getReg(); + unsigned SrcReg = Src.getReg(); + // Just handle virtual registers. + if (TargetRegisterInfo::isVirtualRegister(DstReg) && + TargetRegisterInfo::isVirtualRegister(SrcReg)) { + // Map the following: + // %vreg170<def> = SXTW %vreg166 + // PeepholeMap[170] = vreg166 + PeepholeMap[DstReg] = SrcReg; + } + } + + // Look for P=NOT(P). + if (!DisablePNotP && + (MI->getOpcode() == Hexagon::NOT_p)) { + assert (MI->getNumOperands() == 2); + MachineOperand &Dst = MI->getOperand(0); + MachineOperand &Src = MI->getOperand(1); + unsigned DstReg = Dst.getReg(); + unsigned SrcReg = Src.getReg(); + // Just handle virtual registers. + if (TargetRegisterInfo::isVirtualRegister(DstReg) && + TargetRegisterInfo::isVirtualRegister(SrcReg)) { + // Map the following: + // %vreg170<def> = NOT_xx %vreg166 + // PeepholeMap[170] = vreg166 + PeepholeMap[DstReg] = SrcReg; + } + } + + // Look for copy: + // %vreg176<def> = COPY %vreg170:subreg_loreg + if (!DisableOptSZExt && MI->isCopy()) { + assert (MI->getNumOperands() == 2); + MachineOperand &Dst = MI->getOperand(0); + MachineOperand &Src = MI->getOperand(1); + + // Make sure we are copying the lower 32 bits. + if (Src.getSubReg() != Hexagon::subreg_loreg) + continue; + + unsigned DstReg = Dst.getReg(); + unsigned SrcReg = Src.getReg(); + if (TargetRegisterInfo::isVirtualRegister(DstReg) && + TargetRegisterInfo::isVirtualRegister(SrcReg)) { + // Try to find in the map. + if (unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) { + // Change the 1st operand. + MI->RemoveOperand(1); + MI->addOperand(MachineOperand::CreateReg(PeepholeSrc, false)); + } + } + } + + // Look for Predicated instructions. + if (!DisablePNotP) { + bool Done = false; + if (QII->isPredicated(MI)) { + MachineOperand &Op0 = MI->getOperand(0); + unsigned Reg0 = Op0.getReg(); + const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0); + if (RC0->getID() == Hexagon::PredRegsRegClassID) { + // Handle instructions that have a prediate register in op0 + // (most cases of predicable instructions). + if (TargetRegisterInfo::isVirtualRegister(Reg0)) { + // Try to find in the map. + if (unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) { + // Change the 1st operand and, flip the opcode. + MI->getOperand(0).setReg(PeepholeSrc); + int NewOp = QII->getInvertedPredicatedOpcode(MI->getOpcode()); + MI->setDesc(QII->get(NewOp)); + Done = true; + } + } + } + } + + if (!Done) { + // Handle special instructions. + unsigned Op = MI->getOpcode(); + unsigned NewOp = 0; + unsigned PR = 1, S1 = 2, S2 = 3; // Operand indices. + + switch (Op) { + case Hexagon::TFR_condset_rr: + case Hexagon::TFR_condset_ii: + case Hexagon::MUX_ii: + case Hexagon::MUX_rr: + NewOp = Op; + break; + case Hexagon::TFR_condset_ri: + NewOp = Hexagon::TFR_condset_ir; + break; + case Hexagon::TFR_condset_ir: + NewOp = Hexagon::TFR_condset_ri; + break; + case Hexagon::MUX_ri: + NewOp = Hexagon::MUX_ir; + break; + case Hexagon::MUX_ir: + NewOp = Hexagon::MUX_ri; + break; + } + if (NewOp) { + unsigned PSrc = MI->getOperand(PR).getReg(); + if (unsigned POrig = PeepholeMap.lookup(PSrc)) { + MI->getOperand(PR).setReg(POrig); + MI->setDesc(QII->get(NewOp)); + // Swap operands S1 and S2. + MachineOperand Op1 = MI->getOperand(S1); + MachineOperand Op2 = MI->getOperand(S2); + ChangeOpInto(MI->getOperand(S1), Op2); + ChangeOpInto(MI->getOperand(S2), Op1); + } + } // if (NewOp) + } // if (!Done) + + } // if (!DisablePNotP) + + } // Instruction + } // Basic Block + return true; +} + +void HexagonPeephole::ChangeOpInto(MachineOperand &Dst, MachineOperand &Src) { + assert (&Dst != &Src && "Cannot duplicate into itself"); + switch (Dst.getType()) { + case MachineOperand::MO_Register: + if (Src.isReg()) { + Dst.setReg(Src.getReg()); + } else if (Src.isImm()) { + Dst.ChangeToImmediate(Src.getImm()); + } else { + llvm_unreachable("Unexpected src operand type"); + } + break; + + case MachineOperand::MO_Immediate: + if (Src.isImm()) { + Dst.setImm(Src.getImm()); + } else if (Src.isReg()) { + Dst.ChangeToRegister(Src.getReg(), Src.isDef(), Src.isImplicit(), + Src.isKill(), Src.isDead(), Src.isUndef(), + Src.isDebug()); + } else { + llvm_unreachable("Unexpected src operand type"); + } + break; + + default: + llvm_unreachable("Unexpected dst operand type"); + break; + } +} + +FunctionPass *llvm::createHexagonPeephole() { + return new HexagonPeephole(); +} diff --git a/lib/Target/Hexagon/HexagonSelectCCInfo.td b/lib/Target/Hexagon/HexagonSelectCCInfo.td index f21d928..dcee59f 100644 --- a/lib/Target/Hexagon/HexagonSelectCCInfo.td +++ b/lib/Target/Hexagon/HexagonSelectCCInfo.td @@ -18,7 +18,7 @@ def : Pat <(i32 (selectcc IntRegs:$lhs, IntRegs:$rhs, IntRegs:$tval, def : Pat <(i32 (selectcc IntRegs:$lhs, IntRegs:$rhs, IntRegs:$tval, IntRegs:$fval, SETNE)), - (i32 (MUX_rr (i1 (NOT_Ps (CMPEQrr IntRegs:$lhs, IntRegs:$rhs))), + (i32 (MUX_rr (i1 (NOT_p (CMPEQrr IntRegs:$lhs, IntRegs:$rhs))), IntRegs:$tval, IntRegs:$fval))>; def : Pat <(i32 (selectcc IntRegs:$lhs, IntRegs:$rhs, IntRegs:$tval, @@ -35,24 +35,24 @@ def : Pat <(i32 (selectcc IntRegs:$lhs, IntRegs:$rhs, IntRegs:$tval, def : Pat <(i32 (selectcc IntRegs:$lhs, IntRegs:$rhs, IntRegs:$tval, IntRegs:$fval, SETULT)), - (i32 (MUX_rr (i1 (NOT_Ps (CMPGTUrr IntRegs:$lhs, + (i32 (MUX_rr (i1 (NOT_p (CMPGTUrr IntRegs:$lhs, (ADD_ri IntRegs:$rhs, -1)))), IntRegs:$tval, IntRegs:$fval))>; def : Pat <(i32 (selectcc IntRegs:$lhs, IntRegs:$rhs, IntRegs:$tval, IntRegs:$fval, SETLT)), - (i32 (MUX_rr (i1 (NOT_Ps (CMPGTrr IntRegs:$lhs, + (i32 (MUX_rr (i1 (NOT_p (CMPGTrr IntRegs:$lhs, (ADD_ri IntRegs:$rhs, -1)))), IntRegs:$tval, IntRegs:$fval))>; def : Pat <(i32 (selectcc IntRegs:$lhs, IntRegs:$rhs, IntRegs:$tval, IntRegs:$fval, SETLE)), - (i32 (MUX_rr (i1 (NOT_Ps (CMPGTrr IntRegs:$lhs, IntRegs:$rhs))), + (i32 (MUX_rr (i1 (NOT_p (CMPGTrr IntRegs:$lhs, IntRegs:$rhs))), IntRegs:$tval, IntRegs:$fval))>; def : Pat <(i32 (selectcc IntRegs:$lhs, IntRegs:$rhs, IntRegs:$tval, IntRegs:$fval, SETULE)), - (i32 (MUX_rr (i1 (NOT_Ps (CMPGTUrr IntRegs:$lhs, IntRegs:$rhs))), + (i32 (MUX_rr (i1 (NOT_p (CMPGTUrr IntRegs:$lhs, IntRegs:$rhs))), IntRegs:$tval, IntRegs:$fval))>; @@ -86,7 +86,7 @@ def : Pat <(i32 (selectcc PredRegs:$lhs, PredRegs:$rhs, IntRegs:$tval, def : Pat <(i32 (selectcc PredRegs:$lhs, PredRegs:$rhs, IntRegs:$tval, IntRegs:$fval, SETEQ)), - (i32 (MUX_rr (i1 (NOT_pp (XOR_pp PredRegs:$lhs, PredRegs:$rhs))), + (i32 (MUX_rr (i1 (NOT_p (XOR_pp PredRegs:$lhs, PredRegs:$rhs))), IntRegs:$tval, IntRegs:$fval))>; diff --git a/lib/Target/Hexagon/HexagonTargetMachine.cpp b/lib/Target/Hexagon/HexagonTargetMachine.cpp index 1f7bdf0..6c41885 100644 --- a/lib/Target/Hexagon/HexagonTargetMachine.cpp +++ b/lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -101,6 +101,7 @@ TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { bool HexagonPassConfig::addInstSelector() { PM.add(createHexagonRemoveExtendOps(getHexagonTargetMachine())); PM.add(createHexagonISelDag(getHexagonTargetMachine())); + PM.add(createHexagonPeephole()); return false; } |