brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.9 KiB · 8c64893 Raw
193 lines · c
1//===-- MVETailPredUtils.h - Tail predication utility functions -*- C++-*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains utility functions for low overhead and tail predicated10// loops, shared between the ARMLowOverheadLoops pass and anywhere else that11// needs them.12//13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H16#define LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H17 18#include "llvm/CodeGen/MachineInstr.h"19#include "llvm/CodeGen/MachineInstrBuilder.h"20#include "llvm/CodeGen/MachineOperand.h"21#include "llvm/CodeGen/TargetInstrInfo.h"22 23namespace llvm {24 25static inline unsigned VCTPOpcodeToLSTP(unsigned Opcode, bool IsDoLoop) {26  switch (Opcode) {27  default:28    llvm_unreachable("unhandled vctp opcode");29    break;30  case ARM::MVE_VCTP8:31    return IsDoLoop ? ARM::MVE_DLSTP_8 : ARM::MVE_WLSTP_8;32  case ARM::MVE_VCTP16:33    return IsDoLoop ? ARM::MVE_DLSTP_16 : ARM::MVE_WLSTP_16;34  case ARM::MVE_VCTP32:35    return IsDoLoop ? ARM::MVE_DLSTP_32 : ARM::MVE_WLSTP_32;36  case ARM::MVE_VCTP64:37    return IsDoLoop ? ARM::MVE_DLSTP_64 : ARM::MVE_WLSTP_64;38  }39  return 0;40}41 42static inline unsigned getTailPredVectorWidth(unsigned Opcode) {43  switch (Opcode) {44  default:45    llvm_unreachable("unhandled vctp opcode");46  case ARM::MVE_VCTP8:47    return 16;48  case ARM::MVE_VCTP16:49    return 8;50  case ARM::MVE_VCTP32:51    return 4;52  case ARM::MVE_VCTP64:53    return 2;54  }55  return 0;56}57 58static inline bool isVCTP(const MachineInstr *MI) {59  switch (MI->getOpcode()) {60  default:61    break;62  case ARM::MVE_VCTP8:63  case ARM::MVE_VCTP16:64  case ARM::MVE_VCTP32:65  case ARM::MVE_VCTP64:66    return true;67  }68  return false;69}70 71static inline bool isDoLoopStart(const MachineInstr &MI) {72  return MI.getOpcode() == ARM::t2DoLoopStart ||73         MI.getOpcode() == ARM::t2DoLoopStartTP;74}75 76static inline bool isWhileLoopStart(const MachineInstr &MI) {77  return MI.getOpcode() == ARM::t2WhileLoopStart ||78         MI.getOpcode() == ARM::t2WhileLoopStartLR ||79         MI.getOpcode() == ARM::t2WhileLoopStartTP;80}81 82static inline bool isLoopStart(const MachineInstr &MI) {83  return isDoLoopStart(MI) || isWhileLoopStart(MI);84}85 86// Return the TargetBB stored in a t2WhileLoopStartLR/t2WhileLoopStartTP.87inline MachineBasicBlock *getWhileLoopStartTargetBB(const MachineInstr &MI) {88  assert(isWhileLoopStart(MI) && "Expected WhileLoopStart!");89  unsigned Op = MI.getOpcode() == ARM::t2WhileLoopStartTP ? 3 : 2;90  return MI.getOperand(Op).getMBB();91}92 93// WhileLoopStart holds the exit block, so produce a subs Op0, Op1, 0 and then a94// beq that branches to the exit branch.95// If UseCmp is true, this will create a t2CMP instead of a t2SUBri, meaning the96// value of LR into the loop will not be setup. This is used if the LR setup is97// done via another means (via a t2DoLoopStart, for example).98inline void RevertWhileLoopStartLR(MachineInstr *MI, const TargetInstrInfo *TII,99                                   unsigned BrOpc = ARM::t2Bcc,100                                   bool UseCmp = false) {101  MachineBasicBlock *MBB = MI->getParent();102  assert((MI->getOpcode() == ARM::t2WhileLoopStartLR ||103          MI->getOpcode() == ARM::t2WhileLoopStartTP) &&104         "Only expected a t2WhileLoopStartLR/TP in RevertWhileLoopStartLR!");105 106  // Subs/Cmp107  if (UseCmp) {108    MachineInstrBuilder MIB =109        BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));110    MIB.add(MI->getOperand(1));111    MIB.addImm(0);112    MIB.addImm(ARMCC::AL);113    MIB.addReg(ARM::NoRegister);114  } else {115    MachineInstrBuilder MIB =116        BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri));117    MIB.add(MI->getOperand(0));118    MIB.add(MI->getOperand(1));119    MIB.addImm(0);120    MIB.addImm(ARMCC::AL);121    MIB.addReg(ARM::NoRegister);122    MIB.addReg(ARM::CPSR, RegState::Define);123  }124 125  // Branch126  MachineInstrBuilder MIB =127      BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));128  MIB.addMBB(getWhileLoopStartTargetBB(*MI)); // branch target129  MIB.addImm(ARMCC::EQ);                      // condition code130  MIB.addReg(ARM::CPSR);131 132  MI->eraseFromParent();133}134 135inline void RevertDoLoopStart(MachineInstr *MI, const TargetInstrInfo *TII) {136  MachineBasicBlock *MBB = MI->getParent();137  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::tMOVr))138      .add(MI->getOperand(0))139      .add(MI->getOperand(1))140      .add(predOps(ARMCC::AL));141 142  MI->eraseFromParent();143}144 145inline void RevertLoopDec(MachineInstr *MI, const TargetInstrInfo *TII,146                          bool SetFlags = false) {147  MachineBasicBlock *MBB = MI->getParent();148 149  MachineInstrBuilder MIB =150      BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri));151  MIB.add(MI->getOperand(0));152  MIB.add(MI->getOperand(1));153  MIB.add(MI->getOperand(2));154  MIB.addImm(ARMCC::AL);155  MIB.addReg(0);156 157  if (SetFlags) {158    MIB.addReg(ARM::CPSR);159    MIB->getOperand(5).setIsDef(true);160  } else161    MIB.addReg(0);162 163  MI->eraseFromParent();164}165 166// Generate a subs, or sub and cmp, and a branch instead of an LE.167inline void RevertLoopEnd(MachineInstr *MI, const TargetInstrInfo *TII,168                          unsigned BrOpc = ARM::t2Bcc, bool SkipCmp = false) {169  MachineBasicBlock *MBB = MI->getParent();170 171  // Create cmp172  if (!SkipCmp) {173    MachineInstrBuilder MIB =174        BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));175    MIB.add(MI->getOperand(0));176    MIB.addImm(0);177    MIB.addImm(ARMCC::AL);178    MIB.addReg(ARM::NoRegister);179  }180 181  // Create bne182  MachineInstrBuilder MIB =183      BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));184  MIB.add(MI->getOperand(1)); // branch target185  MIB.addImm(ARMCC::NE);      // condition code186  MIB.addReg(ARM::CPSR);187  MI->eraseFromParent();188}189 190} // end namespace llvm191 192#endif // LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H193