diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp | 129 |
1 files changed, 93 insertions, 36 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp b/contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp index bf9b32e1278e..3e7c2984655a 100644 --- a/contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp +++ b/contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp @@ -334,6 +334,36 @@ SDValue AVRTargetLowering::LowerShifts(SDValue Op, SelectionDAG &DAG) const { llvm_unreachable("Invalid shift opcode"); } + // Optimize int8 shifts. + if (VT.getSizeInBits() == 8) { + if (Op.getOpcode() == ISD::SHL && 4 <= ShiftAmount && ShiftAmount < 7) { + // Optimize LSL when 4 <= ShiftAmount <= 6. + Victim = DAG.getNode(AVRISD::SWAP, dl, VT, Victim); + Victim = + DAG.getNode(ISD::AND, dl, VT, Victim, DAG.getConstant(0xf0, dl, VT)); + ShiftAmount -= 4; + } else if (Op.getOpcode() == ISD::SRL && 4 <= ShiftAmount && + ShiftAmount < 7) { + // Optimize LSR when 4 <= ShiftAmount <= 6. + Victim = DAG.getNode(AVRISD::SWAP, dl, VT, Victim); + Victim = + DAG.getNode(ISD::AND, dl, VT, Victim, DAG.getConstant(0x0f, dl, VT)); + ShiftAmount -= 4; + } else if (Op.getOpcode() == ISD::SHL && ShiftAmount == 7) { + // Optimize LSL when ShiftAmount == 7. + Victim = DAG.getNode(AVRISD::LSL7, dl, VT, Victim); + ShiftAmount = 0; + } else if (Op.getOpcode() == ISD::SRL && ShiftAmount == 7) { + // Optimize LSR when ShiftAmount == 7. + Victim = DAG.getNode(AVRISD::LSR7, dl, VT, Victim); + ShiftAmount = 0; + } else if (Op.getOpcode() == ISD::SRA && ShiftAmount == 7) { + // Optimize ASR when ShiftAmount == 7. + Victim = DAG.getNode(AVRISD::ASR7, dl, VT, Victim); + ShiftAmount = 0; + } + } + while (ShiftAmount--) { Victim = DAG.getNode(Opc8, dl, VT, Victim); } @@ -437,6 +467,36 @@ static AVRCC::CondCodes intCCToAVRCC(ISD::CondCode CC) { } } +/// Returns appropriate CP/CPI/CPC nodes code for the given 8/16-bit operands. +SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, + SelectionDAG &DAG, SDLoc DL) const { + assert((LHS.getSimpleValueType() == RHS.getSimpleValueType()) && + "LHS and RHS have different types"); + assert(((LHS.getSimpleValueType() == MVT::i16) || + (LHS.getSimpleValueType() == MVT::i8)) && "invalid comparison type"); + + SDValue Cmp; + + if (LHS.getSimpleValueType() == MVT::i16 && dyn_cast<ConstantSDNode>(RHS)) { + // Generate a CPI/CPC pair if RHS is a 16-bit constant. + SDValue LHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS, + DAG.getIntPtrConstant(0, DL)); + SDValue LHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS, + DAG.getIntPtrConstant(1, DL)); + SDValue RHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS, + DAG.getIntPtrConstant(0, DL)); + SDValue RHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS, + DAG.getIntPtrConstant(1, DL)); + Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHSlo, RHSlo); + Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHShi, RHShi, Cmp); + } else { + // Generate ordinary 16-bit comparison. + Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHS, RHS); + } + + return Cmp; +} + /// Returns appropriate AVR CMP/CMPC nodes and corresponding condition code for /// the given operands. SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, @@ -549,7 +609,7 @@ SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, DAG.getIntPtrConstant(1, DL)); Cmp = DAG.getNode(AVRISD::TST, DL, MVT::Glue, Top); } else { - Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHSlo, RHSlo); + Cmp = getAVRCmp(LHSlo, RHSlo, DAG, DL); Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHShi, RHShi, Cmp); } } else if (VT == MVT::i64) { @@ -587,7 +647,7 @@ SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, DAG.getIntPtrConstant(1, DL)); Cmp = DAG.getNode(AVRISD::TST, DL, MVT::Glue, Top); } else { - Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHS0, RHS0); + Cmp = getAVRCmp(LHS0, RHS0, DAG, DL); Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS1, RHS1, Cmp); Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS2, RHS2, Cmp); Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS3, RHS3, Cmp); @@ -601,7 +661,7 @@ SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, : DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS, DAG.getIntPtrConstant(1, DL))); } else { - Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHS, RHS); + Cmp = getAVRCmp(LHS, RHS, DAG, DL); } } else { llvm_unreachable("Invalid comparison size"); @@ -676,7 +736,7 @@ SDValue AVRTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { SDValue FI = DAG.getFrameIndex(AFI->getVarArgsFrameIndex(), getPointerTy(DL)); return DAG.getStore(Op.getOperand(0), dl, FI, Op.getOperand(1), - MachinePointerInfo(SV), 0); + MachinePointerInfo(SV)); } SDValue AVRTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { @@ -1096,8 +1156,7 @@ SDValue AVRTargetLowering::LowerFormalArguments( // from this parameter. SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DL)); InVals.push_back(DAG.getLoad(LocVT, dl, Chain, FIN, - MachinePointerInfo::getFixedStack(MF, FI), - 0)); + MachinePointerInfo::getFixedStack(MF, FI))); } } @@ -1230,8 +1289,7 @@ SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, Chain = DAG.getStore(Chain, DL, Arg, PtrOff, - MachinePointerInfo::getStack(MF, VA.getLocMemOffset()), - 0); + MachinePointerInfo::getStack(MF, VA.getLocMemOffset())); } } @@ -1460,9 +1518,11 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI, // Create loop block. MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *CheckBB = F->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB); F->insert(I, LoopBB); + F->insert(I, CheckBB); F->insert(I, RemBB); // Update machine-CFG edges by transferring all successors of the current @@ -1471,14 +1531,14 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI, BB->end()); RemBB->transferSuccessorsAndUpdatePHIs(BB); - // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB. - BB->addSuccessor(LoopBB); - BB->addSuccessor(RemBB); - LoopBB->addSuccessor(RemBB); - LoopBB->addSuccessor(LoopBB); + // Add edges BB => LoopBB => CheckBB => RemBB, CheckBB => LoopBB. + BB->addSuccessor(CheckBB); + LoopBB->addSuccessor(CheckBB); + CheckBB->addSuccessor(LoopBB); + CheckBB->addSuccessor(RemBB); - Register ShiftAmtReg = RI.createVirtualRegister(&AVR::LD8RegClass); - Register ShiftAmtReg2 = RI.createVirtualRegister(&AVR::LD8RegClass); + Register ShiftAmtReg = RI.createVirtualRegister(&AVR::GPR8RegClass); + Register ShiftAmtReg2 = RI.createVirtualRegister(&AVR::GPR8RegClass); Register ShiftReg = RI.createVirtualRegister(RC); Register ShiftReg2 = RI.createVirtualRegister(RC); Register ShiftAmtSrcReg = MI.getOperand(2).getReg(); @@ -1486,44 +1546,41 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI, Register DstReg = MI.getOperand(0).getReg(); // BB: - // cpi N, 0 - // breq RemBB - BuildMI(BB, dl, TII.get(AVR::CPIRdK)).addReg(ShiftAmtSrcReg).addImm(0); - BuildMI(BB, dl, TII.get(AVR::BREQk)).addMBB(RemBB); + // rjmp CheckBB + BuildMI(BB, dl, TII.get(AVR::RJMPk)).addMBB(CheckBB); // LoopBB: - // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] - // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] // ShiftReg2 = shift ShiftReg + auto ShiftMI = BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2).addReg(ShiftReg); + if (HasRepeatedOperand) + ShiftMI.addReg(ShiftReg); + + // CheckBB: + // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] + // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] + // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] // ShiftAmt2 = ShiftAmt - 1; - BuildMI(LoopBB, dl, TII.get(AVR::PHI), ShiftReg) + // if (ShiftAmt2 >= 0) goto LoopBB; + BuildMI(CheckBB, dl, TII.get(AVR::PHI), ShiftReg) .addReg(SrcReg) .addMBB(BB) .addReg(ShiftReg2) .addMBB(LoopBB); - BuildMI(LoopBB, dl, TII.get(AVR::PHI), ShiftAmtReg) + BuildMI(CheckBB, dl, TII.get(AVR::PHI), ShiftAmtReg) .addReg(ShiftAmtSrcReg) .addMBB(BB) .addReg(ShiftAmtReg2) .addMBB(LoopBB); - - auto ShiftMI = BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2).addReg(ShiftReg); - if (HasRepeatedOperand) - ShiftMI.addReg(ShiftReg); - - BuildMI(LoopBB, dl, TII.get(AVR::SUBIRdK), ShiftAmtReg2) - .addReg(ShiftAmtReg) - .addImm(1); - BuildMI(LoopBB, dl, TII.get(AVR::BRNEk)).addMBB(LoopBB); - - // RemBB: - // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] - BuildMI(*RemBB, RemBB->begin(), dl, TII.get(AVR::PHI), DstReg) + BuildMI(CheckBB, dl, TII.get(AVR::PHI), DstReg) .addReg(SrcReg) .addMBB(BB) .addReg(ShiftReg2) .addMBB(LoopBB); + BuildMI(CheckBB, dl, TII.get(AVR::DECRd), ShiftAmtReg2) + .addReg(ShiftAmtReg); + BuildMI(CheckBB, dl, TII.get(AVR::BRPLk)).addMBB(LoopBB); + MI.eraseFromParent(); // The pseudo instruction is gone now. return RemBB; } |