brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.8 KiB · 3370ded Raw
313 lines · cpp
1//===- PPCRegisterBankInfo.cpp --------------------------------------------===//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/// \file9/// This file implements the targeting of the RegisterBankInfo class for10/// PowerPC.11//===----------------------------------------------------------------------===//12 13#include "PPCRegisterBankInfo.h"14#include "PPCRegisterInfo.h"15#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"16#include "llvm/CodeGen/GlobalISel/Utils.h"17#include "llvm/CodeGen/MachineFunction.h"18#include "llvm/CodeGen/MachineRegisterInfo.h"19 20#define DEBUG_TYPE "ppc-reg-bank-info"21 22#define GET_TARGET_REGBANK_IMPL23#include "PPCGenRegisterBank.inc"24 25// This file will be TableGen'ed at some point.26#include "PPCGenRegisterBankInfo.def"27 28using namespace llvm;29 30PPCRegisterBankInfo::PPCRegisterBankInfo(const TargetRegisterInfo &TRI) {}31 32const RegisterBank &33PPCRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,34                                            LLT Ty) const {35  switch (RC.getID()) {36  case PPC::VSFRCRegClassID:37  case PPC::SPILLTOVSRRC_and_VSFRCRegClassID:38  case PPC::SPILLTOVSRRC_and_VFRCRegClassID:39  case PPC::SPILLTOVSRRC_and_F4RCRegClassID:40  case PPC::F8RCRegClassID:41  case PPC::VFRCRegClassID:42  case PPC::VSSRCRegClassID:43  case PPC::F4RCRegClassID:44    return getRegBank(PPC::FPRRegBankID);45  default:46    return PPCGenRegisterBankInfo::getRegBankFromRegClass(RC, Ty);47  }48}49 50const RegisterBankInfo::InstructionMapping &51PPCRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {52  const unsigned Opc = MI.getOpcode();53 54  // Try the default logic for non-generic instructions that are either copies55  // or already have some operands assigned to banks.56  if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {57    const RegisterBankInfo::InstructionMapping &Mapping =58        getInstrMappingImpl(MI);59    if (Mapping.isValid())60      return Mapping;61  }62 63  const MachineFunction &MF = *MI.getParent()->getParent();64  const MachineRegisterInfo &MRI = MF.getRegInfo();65  const TargetSubtargetInfo &STI = MF.getSubtarget();66  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();67 68  unsigned NumOperands = MI.getNumOperands();69  const ValueMapping *OperandsMapping = nullptr;70  unsigned Cost = 1;71  unsigned MappingID = DefaultMappingID;72 73  switch (Opc) {74    // Arithmetic ops.75  case TargetOpcode::G_ADD:76  case TargetOpcode::G_SUB:77    // Bitwise ops.78  case TargetOpcode::G_AND:79  case TargetOpcode::G_OR:80  case TargetOpcode::G_XOR:81    // Extension ops.82  case TargetOpcode::G_SEXT:83  case TargetOpcode::G_ZEXT:84  case TargetOpcode::G_ANYEXT: {85    assert(NumOperands <= 3 &&86           "This code is for instructions with 3 or less operands");87    LLT Ty = MRI.getType(MI.getOperand(0).getReg());88    unsigned Size = Ty.getSizeInBits();89    switch (Size) {90    case 128:91      OperandsMapping = getValueMapping(PMI_VEC128);92      break;93    default:94      OperandsMapping = getValueMapping(PMI_GPR64);95      break;96    }97    break;98  }99  case TargetOpcode::G_FADD:100  case TargetOpcode::G_FSUB:101  case TargetOpcode::G_FMUL:102  case TargetOpcode::G_FDIV: {103    Register SrcReg = MI.getOperand(1).getReg();104    unsigned Size = getSizeInBits(SrcReg, MRI, TRI);105 106    assert((Size == 32 || Size == 64 || Size == 128) &&107           "Unsupported floating point types!\n");108    switch (Size) {109    case 32:110      OperandsMapping = getValueMapping(PMI_FPR32);111      break;112    case 64:113      OperandsMapping = getValueMapping(PMI_FPR64);114      break;115    case 128:116      OperandsMapping = getValueMapping(PMI_VEC128);117      break;118    }119    break;120  }121  case TargetOpcode::G_FCMP: {122    unsigned CmpSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();123 124    OperandsMapping = getOperandsMapping(125        {getValueMapping(PMI_CR), nullptr,126         getValueMapping(CmpSize == 32 ? PMI_FPR32 : PMI_FPR64),127         getValueMapping(CmpSize == 32 ? PMI_FPR32 : PMI_FPR64)});128    break;129  }130  case TargetOpcode::G_CONSTANT:131    OperandsMapping = getOperandsMapping({getValueMapping(PMI_GPR64), nullptr});132    break;133  case TargetOpcode::G_CONSTANT_POOL:134    OperandsMapping = getOperandsMapping({getValueMapping(PMI_GPR64), nullptr});135    break;136  case TargetOpcode::G_FPTOUI:137  case TargetOpcode::G_FPTOSI: {138    Register SrcReg = MI.getOperand(1).getReg();139    unsigned Size = getSizeInBits(SrcReg, MRI, TRI);140 141    OperandsMapping = getOperandsMapping(142        {getValueMapping(PMI_GPR64),143         getValueMapping(Size == 32 ? PMI_FPR32 : PMI_FPR64)});144    break;145  }146  case TargetOpcode::G_UITOFP:147  case TargetOpcode::G_SITOFP: {148    Register SrcReg = MI.getOperand(0).getReg();149    unsigned Size = getSizeInBits(SrcReg, MRI, TRI);150 151    OperandsMapping =152        getOperandsMapping({getValueMapping(Size == 32 ? PMI_FPR32 : PMI_FPR64),153                            getValueMapping(PMI_GPR64)});154    break;155  }156  case TargetOpcode::G_LOAD: {157    unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();158    // Check if that load feeds fp instructions.159    if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),160               [&](const MachineInstr &UseMI) {161                 // If we have at least one direct use in a FP instruction,162                 // assume this was a floating point load in the IR. If it was163                 // not, we would have had a bitcast before reaching that164                 // instruction.165                 //166                 // Int->FP conversion operations are also captured in167                 // onlyDefinesFP().168                 return onlyUsesFP(UseMI, MRI, TRI);169               }))170      OperandsMapping = getOperandsMapping(171          {getValueMapping(Size == 64 ? PMI_FPR64 : PMI_FPR32),172           getValueMapping(PMI_GPR64)});173    else174      OperandsMapping = getOperandsMapping(175          {getValueMapping(Size == 64 ? PMI_GPR64 : PMI_GPR32),176           getValueMapping(PMI_GPR64)});177    break;178  }179  case TargetOpcode::G_STORE: {180    // Check if the store is fed by fp instructions.181    MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(0).getReg());182    unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();183    if (onlyDefinesFP(*DefMI, MRI, TRI))184      OperandsMapping = getOperandsMapping(185          {getValueMapping(Size == 64 ? PMI_FPR64 : PMI_FPR32),186           getValueMapping(PMI_GPR64)});187    else188      OperandsMapping = getOperandsMapping(189          {getValueMapping(Size == 64 ? PMI_GPR64 : PMI_GPR32),190           getValueMapping(PMI_GPR64)});191    break;192  }193  case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS: {194    // FIXME: We have to check every operand in this MI and compute value195    // mapping accordingly.196    SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);197    OperandsMapping = getOperandsMapping(OpdsMapping);198    break;199  }200  case TargetOpcode::G_BITCAST: {201    LLT DstTy = MRI.getType(MI.getOperand(0).getReg());202    LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());203    unsigned DstSize = DstTy.getSizeInBits();204 205    bool DstIsGPR = !DstTy.isVector();206    bool SrcIsGPR = !SrcTy.isVector();207    // TODO: Currently, only vector and GPR register banks are handled.208    //       This needs to be extended to handle floating point register209    //       banks in the future.210    const RegisterBank &DstRB = DstIsGPR ? PPC::GPRRegBank : PPC::VECRegBank;211    const RegisterBank &SrcRB = SrcIsGPR ? PPC::GPRRegBank : PPC::VECRegBank;212 213    return getInstructionMapping(214        MappingID, Cost, getCopyMapping(DstRB.getID(), SrcRB.getID(), DstSize),215        NumOperands);216  }217  default:218    return getInvalidInstructionMapping();219  }220 221  return getInstructionMapping(MappingID, Cost, OperandsMapping, NumOperands);222}223 224/// \returns true if a given intrinsic \p ID only uses and defines FPRs.225static bool isFPIntrinsic(unsigned ID) {226  // TODO: Add more intrinsics.227  return false;228}229 230/// FIXME: this is copied from target AArch64. Needs some code refactor here to231/// put this function in class RegisterBankInfo.232bool PPCRegisterBankInfo::hasFPConstraints(const MachineInstr &MI,233                                           const MachineRegisterInfo &MRI,234                                           const TargetRegisterInfo &TRI,235                                           unsigned Depth) const {236  unsigned Op = MI.getOpcode();237 238  if (auto *GI = dyn_cast<GIntrinsic>(&MI)) {239    if (isFPIntrinsic(GI->getIntrinsicID()))240      return true;241  }242 243  // Do we have an explicit floating point instruction?244  if (isPreISelGenericFloatingPointOpcode(Op))245    return true;246 247  // No. Check if we have a copy-like instruction. If we do, then we could248  // still be fed by floating point instructions.249  if (Op != TargetOpcode::COPY && !MI.isPHI() &&250      !isPreISelGenericOptimizationHint(Op))251    return false;252 253  // Check if we already know the register bank.254  auto *RB = getRegBank(MI.getOperand(0).getReg(), MRI, TRI);255  if (RB == &PPC::FPRRegBank)256    return true;257  if (RB == &PPC::GPRRegBank)258    return false;259 260  // We don't know anything.261  //262  // If we have a phi, we may be able to infer that it will be assigned a FPR263  // based off of its inputs.264  if (!MI.isPHI() || Depth > MaxFPRSearchDepth)265    return false;266 267  return any_of(MI.explicit_uses(), [&](const MachineOperand &Op) {268    return Op.isReg() &&269           onlyDefinesFP(*MRI.getVRegDef(Op.getReg()), MRI, TRI, Depth + 1);270  });271}272 273/// FIXME: this is copied from target AArch64. Needs some code refactor here to274/// put this function in class RegisterBankInfo.275bool PPCRegisterBankInfo::onlyUsesFP(const MachineInstr &MI,276                                     const MachineRegisterInfo &MRI,277                                     const TargetRegisterInfo &TRI,278                                     unsigned Depth) const {279  switch (MI.getOpcode()) {280  case TargetOpcode::G_FPTOSI:281  case TargetOpcode::G_FPTOUI:282  case TargetOpcode::G_FCMP:283  case TargetOpcode::G_LROUND:284  case TargetOpcode::G_LLROUND:285    return true;286  default:287    break;288  }289  return hasFPConstraints(MI, MRI, TRI, Depth);290}291 292/// FIXME: this is copied from target AArch64. Needs some code refactor here to293/// put this function in class RegisterBankInfo.294bool PPCRegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,295                                        const MachineRegisterInfo &MRI,296                                        const TargetRegisterInfo &TRI,297                                        unsigned Depth) const {298  switch (MI.getOpcode()) {299  case TargetOpcode::G_SITOFP:300  case TargetOpcode::G_UITOFP:301    return true;302  default:303    break;304  }305  return hasFPConstraints(MI, MRI, TRI, Depth);306}307 308RegisterBankInfo::InstructionMappings309PPCRegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {310  // TODO Implement.311  return RegisterBankInfo::getInstrAlternativeMappings(MI);312}313