123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- //===-- MVETailPredUtils.h - Tail predication utility functions -*- C++-*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file contains utility functions for low overhead and tail predicated
- // loops, shared between the ARMLowOverheadLoops pass and anywhere else that
- // needs them.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
- #define LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
- #include "llvm/CodeGen/MachineInstr.h"
- #include "llvm/CodeGen/MachineInstrBuilder.h"
- #include "llvm/CodeGen/MachineOperand.h"
- #include "llvm/CodeGen/TargetInstrInfo.h"
- namespace llvm {
- static inline unsigned VCTPOpcodeToLSTP(unsigned Opcode, bool IsDoLoop) {
- switch (Opcode) {
- default:
- llvm_unreachable("unhandled vctp opcode");
- break;
- case ARM::MVE_VCTP8:
- return IsDoLoop ? ARM::MVE_DLSTP_8 : ARM::MVE_WLSTP_8;
- case ARM::MVE_VCTP16:
- return IsDoLoop ? ARM::MVE_DLSTP_16 : ARM::MVE_WLSTP_16;
- case ARM::MVE_VCTP32:
- return IsDoLoop ? ARM::MVE_DLSTP_32 : ARM::MVE_WLSTP_32;
- case ARM::MVE_VCTP64:
- return IsDoLoop ? ARM::MVE_DLSTP_64 : ARM::MVE_WLSTP_64;
- }
- return 0;
- }
- static inline unsigned getTailPredVectorWidth(unsigned Opcode) {
- switch (Opcode) {
- default:
- llvm_unreachable("unhandled vctp opcode");
- case ARM::MVE_VCTP8:
- return 16;
- case ARM::MVE_VCTP16:
- return 8;
- case ARM::MVE_VCTP32:
- return 4;
- case ARM::MVE_VCTP64:
- return 2;
- }
- return 0;
- }
- static inline bool isVCTP(const MachineInstr *MI) {
- switch (MI->getOpcode()) {
- default:
- break;
- case ARM::MVE_VCTP8:
- case ARM::MVE_VCTP16:
- case ARM::MVE_VCTP32:
- case ARM::MVE_VCTP64:
- return true;
- }
- return false;
- }
- static inline bool isLoopStart(MachineInstr &MI) {
- return MI.getOpcode() == ARM::t2DoLoopStart ||
- MI.getOpcode() == ARM::t2DoLoopStartTP ||
- MI.getOpcode() == ARM::t2WhileLoopStart;
- }
- // WhileLoopStart holds the exit block, so produce a cmp lr, 0 and then a
- // beq that branches to the exit branch.
- inline void RevertWhileLoopStart(MachineInstr *MI, const TargetInstrInfo *TII,
- unsigned BrOpc = ARM::t2Bcc) {
- MachineBasicBlock *MBB = MI->getParent();
- // Cmp
- MachineInstrBuilder MIB =
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));
- MIB.add(MI->getOperand(0));
- MIB.addImm(0);
- MIB.addImm(ARMCC::AL);
- MIB.addReg(ARM::NoRegister);
- // Branch
- MIB = BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
- MIB.add(MI->getOperand(1)); // branch target
- MIB.addImm(ARMCC::EQ); // condition code
- MIB.addReg(ARM::CPSR);
- MI->eraseFromParent();
- }
- inline void RevertDoLoopStart(MachineInstr *MI, const TargetInstrInfo *TII) {
- MachineBasicBlock *MBB = MI->getParent();
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::tMOVr))
- .add(MI->getOperand(0))
- .add(MI->getOperand(1))
- .add(predOps(ARMCC::AL));
- MI->eraseFromParent();
- }
- inline void RevertLoopDec(MachineInstr *MI, const TargetInstrInfo *TII,
- bool SetFlags = false) {
- MachineBasicBlock *MBB = MI->getParent();
- MachineInstrBuilder MIB =
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri));
- MIB.add(MI->getOperand(0));
- MIB.add(MI->getOperand(1));
- MIB.add(MI->getOperand(2));
- MIB.addImm(ARMCC::AL);
- MIB.addReg(0);
- if (SetFlags) {
- MIB.addReg(ARM::CPSR);
- MIB->getOperand(5).setIsDef(true);
- } else
- MIB.addReg(0);
- MI->eraseFromParent();
- }
- // Generate a subs, or sub and cmp, and a branch instead of an LE.
- inline void RevertLoopEnd(MachineInstr *MI, const TargetInstrInfo *TII,
- unsigned BrOpc = ARM::t2Bcc, bool SkipCmp = false) {
- MachineBasicBlock *MBB = MI->getParent();
- // Create cmp
- if (!SkipCmp) {
- MachineInstrBuilder MIB =
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));
- MIB.add(MI->getOperand(0));
- MIB.addImm(0);
- MIB.addImm(ARMCC::AL);
- MIB.addReg(ARM::NoRegister);
- }
- // Create bne
- MachineInstrBuilder MIB =
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
- MIB.add(MI->getOperand(1)); // branch target
- MIB.addImm(ARMCC::NE); // condition code
- MIB.addReg(ARM::CPSR);
- MI->eraseFromParent();
- }
- } // end namespace llvm
- #endif // LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
|