brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · db2d96f Raw
196 lines · cpp
1//===- NVPTXInstrInfo.cpp - NVPTX Instruction Information -----------------===//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 the NVPTX implementation of the TargetInstrInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "NVPTXInstrInfo.h"14#include "NVPTX.h"15#include "NVPTXSubtarget.h"16#include "llvm/CodeGen/MachineFunction.h"17#include "llvm/CodeGen/MachineInstrBuilder.h"18#include "llvm/CodeGen/MachineRegisterInfo.h"19 20using namespace llvm;21 22#define GET_INSTRINFO_CTOR_DTOR23#include "NVPTXGenInstrInfo.inc"24 25// Pin the vtable to this file.26void NVPTXInstrInfo::anchor() {}27 28NVPTXInstrInfo::NVPTXInstrInfo(const NVPTXSubtarget &STI)29    : NVPTXGenInstrInfo(STI, RegInfo), RegInfo() {}30 31void NVPTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,32                                 MachineBasicBlock::iterator I,33                                 const DebugLoc &DL, Register DestReg,34                                 Register SrcReg, bool KillSrc,35                                 bool RenamableDest, bool RenamableSrc) const {36  const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();37  const TargetRegisterClass *DestRC = MRI.getRegClass(DestReg);38  const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);39 40  if (DestRC != SrcRC)41    report_fatal_error("Copy one register into another with a different width");42 43  unsigned Op;44  if (DestRC == &NVPTX::B1RegClass)45    Op = NVPTX::MOV_B1_r;46  else if (DestRC == &NVPTX::B16RegClass)47    Op = NVPTX::MOV_B16_r;48  else if (DestRC == &NVPTX::B32RegClass)49    Op = NVPTX::MOV_B32_r;50  else if (DestRC == &NVPTX::B64RegClass)51    Op = NVPTX::MOV_B64_r;52  else if (DestRC == &NVPTX::B128RegClass)53    Op = NVPTX::MOV_B128_r;54  else55    llvm_unreachable("Bad register copy");56 57  BuildMI(MBB, I, DL, get(Op), DestReg)58      .addReg(SrcReg, getKillRegState(KillSrc));59}60 61/// analyzeBranch - Analyze the branching code at the end of MBB, returning62/// true if it cannot be understood (e.g. it's a switch dispatch or isn't63/// implemented for a target).  Upon success, this returns false and returns64/// with the following information in various cases:65///66/// 1. If this block ends with no branches (it just falls through to its succ)67///    just return false, leaving TBB/FBB null.68/// 2. If this block ends with only an unconditional branch, it sets TBB to be69///    the destination block.70/// 3. If this block ends with an conditional branch and it falls through to71///    an successor block, it sets TBB to be the branch destination block and a72///    list of operands that evaluate the condition. These73///    operands can be passed to other TargetInstrInfo methods to create new74///    branches.75/// 4. If this block ends with an conditional branch and an unconditional76///    block, it returns the 'true' destination in TBB, the 'false' destination77///    in FBB, and a list of operands that evaluate the condition. These78///    operands can be passed to other TargetInstrInfo methods to create new79///    branches.80///81/// Note that removeBranch and insertBranch must be implemented to support82/// cases where this method returns success.83///84bool NVPTXInstrInfo::analyzeBranch(MachineBasicBlock &MBB,85                                   MachineBasicBlock *&TBB,86                                   MachineBasicBlock *&FBB,87                                   SmallVectorImpl<MachineOperand> &Cond,88                                   bool AllowModify) const {89  // If the block has no terminators, it just falls into the block after it.90  MachineBasicBlock::iterator I = MBB.end();91  if (I == MBB.begin() || !isUnpredicatedTerminator(*--I))92    return false;93 94  // Get the last instruction in the block.95  MachineInstr &LastInst = *I;96 97  // If there is only one terminator instruction, process it.98  if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {99    if (LastInst.getOpcode() == NVPTX::GOTO) {100      TBB = LastInst.getOperand(0).getMBB();101      return false;102    } else if (LastInst.getOpcode() == NVPTX::CBranch) {103      // Block ends with fall-through condbranch.104      TBB = LastInst.getOperand(1).getMBB();105      Cond.push_back(LastInst.getOperand(0));106      return false;107    }108    // Otherwise, don't know what this is.109    return true;110  }111 112  // Get the instruction before it if it's a terminator.113  MachineInstr &SecondLastInst = *I;114 115  // If there are three terminators, we don't know what sort of block this is.116  if (I != MBB.begin() && isUnpredicatedTerminator(*--I))117    return true;118 119  // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.120  if (SecondLastInst.getOpcode() == NVPTX::CBranch &&121      LastInst.getOpcode() == NVPTX::GOTO) {122    TBB = SecondLastInst.getOperand(1).getMBB();123    Cond.push_back(SecondLastInst.getOperand(0));124    FBB = LastInst.getOperand(0).getMBB();125    return false;126  }127 128  // If the block ends with two NVPTX:GOTOs, handle it.  The second one is not129  // executed, so remove it.130  if (SecondLastInst.getOpcode() == NVPTX::GOTO &&131      LastInst.getOpcode() == NVPTX::GOTO) {132    TBB = SecondLastInst.getOperand(0).getMBB();133    I = LastInst;134    if (AllowModify)135      I->eraseFromParent();136    return false;137  }138 139  // Otherwise, can't handle this.140  return true;141}142 143unsigned NVPTXInstrInfo::removeBranch(MachineBasicBlock &MBB,144                                      int *BytesRemoved) const {145  assert(!BytesRemoved && "code size not handled");146  MachineBasicBlock::iterator I = MBB.end();147  if (I == MBB.begin())148    return 0;149  --I;150  if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch)151    return 0;152 153  // Remove the branch.154  I->eraseFromParent();155 156  I = MBB.end();157 158  if (I == MBB.begin())159    return 1;160  --I;161  if (I->getOpcode() != NVPTX::CBranch)162    return 1;163 164  // Remove the branch.165  I->eraseFromParent();166  return 2;167}168 169unsigned NVPTXInstrInfo::insertBranch(MachineBasicBlock &MBB,170                                      MachineBasicBlock *TBB,171                                      MachineBasicBlock *FBB,172                                      ArrayRef<MachineOperand> Cond,173                                      const DebugLoc &DL,174                                      int *BytesAdded) const {175  assert(!BytesAdded && "code size not handled");176 177  // Shouldn't be a fall through.178  assert(TBB && "insertBranch must not be told to insert a fallthrough");179  assert((Cond.size() == 1 || Cond.size() == 0) &&180         "NVPTX branch conditions have two components!");181 182  // One-way branch.183  if (!FBB) {184    if (Cond.empty()) // Unconditional branch185      BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(TBB);186    else // Conditional branch187      BuildMI(&MBB, DL, get(NVPTX::CBranch)).add(Cond[0]).addMBB(TBB);188    return 1;189  }190 191  // Two-way Conditional Branch.192  BuildMI(&MBB, DL, get(NVPTX::CBranch)).add(Cond[0]).addMBB(TBB);193  BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(FBB);194  return 2;195}196