brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · 84bb6ca Raw
166 lines · cpp
1//===- ARCExpandPseudosPass - ARC expand pseudo loads -----------*- 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 pass expands stores with large offsets into an appropriate sequence.10//===----------------------------------------------------------------------===//11 12#include "ARC.h"13#include "ARCInstrInfo.h"14#include "ARCRegisterInfo.h"15#include "ARCSubtarget.h"16#include "MCTargetDesc/ARCInfo.h"17#include "llvm/ADT/Statistic.h"18#include "llvm/CodeGen/MachineFunctionPass.h"19#include "llvm/CodeGen/MachineInstrBuilder.h"20#include "llvm/CodeGen/MachineRegisterInfo.h"21 22using namespace llvm;23 24#define DEBUG_TYPE "arc-expand-pseudos"25 26namespace {27 28class ARCExpandPseudos : public MachineFunctionPass {29public:30  static char ID;31  ARCExpandPseudos() : MachineFunctionPass(ID) {}32 33  bool runOnMachineFunction(MachineFunction &Fn) override;34 35  StringRef getPassName() const override { return "ARC Expand Pseudos"; }36 37private:38  void expandStore(MachineFunction &, MachineBasicBlock::iterator);39  void expandCTLZ(MachineFunction &, MachineBasicBlock::iterator);40  void expandCTTZ(MachineFunction &, MachineBasicBlock::iterator);41 42  const ARCInstrInfo *TII;43};44 45char ARCExpandPseudos::ID = 0;46 47} // end anonymous namespace48 49static unsigned getMappedOp(unsigned PseudoOp) {50  switch (PseudoOp) {51  case ARC::ST_FAR:52    return ARC::ST_rs9;53  case ARC::STH_FAR:54    return ARC::STH_rs9;55  case ARC::STB_FAR:56    return ARC::STB_rs9;57  default:58    llvm_unreachable("Unhandled pseudo op.");59  }60}61 62void ARCExpandPseudos::expandStore(MachineFunction &MF,63                                   MachineBasicBlock::iterator SII) {64  MachineInstr &SI = *SII;65  Register AddrReg = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass);66  Register AddOpc =67      isUInt<6>(SI.getOperand(2).getImm()) ? ARC::ADD_rru6 : ARC::ADD_rrlimm;68  BuildMI(*SI.getParent(), SI, SI.getDebugLoc(), TII->get(AddOpc), AddrReg)69      .addReg(SI.getOperand(1).getReg())70      .addImm(SI.getOperand(2).getImm());71  BuildMI(*SI.getParent(), SI, SI.getDebugLoc(),72          TII->get(getMappedOp(SI.getOpcode())))73      .addReg(SI.getOperand(0).getReg())74      .addReg(AddrReg)75      .addImm(0);76  SI.eraseFromParent();77}78 79void ARCExpandPseudos::expandCTLZ(MachineFunction &MF,80                                  MachineBasicBlock::iterator MII) {81  // Expand:82  //	%R2<def> = CTLZ %R0, %STATUS<imp-def>83  // To:84  //	%R2<def> = FLS_f_rr %R0, %STATUS<imp-def>85  //	%R2<def,tied1> = MOV_cc_ru6 %R2<tied0>, 32, pred:1, %STATUS<imp-use>86  //	%R2<def,tied1> = RSUB_cc_rru6 %R2<tied0>, 31, pred:2, %STATUS<imp-use>87  MachineInstr &MI = *MII;88  const MachineOperand &Dest = MI.getOperand(0);89  const MachineOperand &Src = MI.getOperand(1);90  Register Ra = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass);91  Register Rb = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass);92 93  BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(ARC::FLS_f_rr), Ra)94      .add(Src);95  BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(ARC::MOV_cc_ru6), Rb)96      .addImm(32)97      .addImm(ARCCC::EQ)98      .addReg(Ra);99  BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(ARC::RSUB_cc_rru6))100      .add(Dest)101      .addImm(31)102      .addImm(ARCCC::NE)103      .addReg(Rb);104 105  MI.eraseFromParent();106}107 108void ARCExpandPseudos::expandCTTZ(MachineFunction &MF,109                                  MachineBasicBlock::iterator MII) {110  // Expand:111  //	%R0<def> = CTTZ %R0<kill>, %STATUS<imp-def>112  // To:113  //	%R0<def> = FFS_f_rr %R0<kill>, %STATUS<imp-def>114  //	%R0<def,tied1> = MOVcc_ru6 %R0<tied0>, 32, pred:1, %STATUS<imp-use>115  MachineInstr &MI = *MII;116  const MachineOperand &Dest = MI.getOperand(0);117  const MachineOperand &Src = MI.getOperand(1);118  Register R = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass);119 120  BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(ARC::FFS_f_rr), R)121      .add(Src);122  BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(ARC::MOV_cc_ru6))123      .add(Dest)124      .addImm(32)125      .addImm(ARCCC::EQ)126      .addReg(R);127 128  MI.eraseFromParent();129}130 131bool ARCExpandPseudos::runOnMachineFunction(MachineFunction &MF) {132  const ARCSubtarget *STI = &MF.getSubtarget<ARCSubtarget>();133  TII = STI->getInstrInfo();134  bool Expanded = false;135  for (auto &MBB : MF) {136    MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();137    while (MBBI != E) {138      MachineBasicBlock::iterator NMBBI = std::next(MBBI);139      switch (MBBI->getOpcode()) {140      case ARC::ST_FAR:141      case ARC::STH_FAR:142      case ARC::STB_FAR:143        expandStore(MF, MBBI);144        Expanded = true;145        break;146      case ARC::CTLZ:147        expandCTLZ(MF, MBBI);148        Expanded = true;149        break;150      case ARC::CTTZ:151        expandCTTZ(MF, MBBI);152        Expanded = true;153        break;154      default:155        break;156      }157      MBBI = NMBBI;158    }159  }160  return Expanded;161}162 163FunctionPass *llvm::createARCExpandPseudosPass() {164  return new ARCExpandPseudos();165}166