brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · 103aea3 Raw
136 lines · cpp
1//===-- LVLGen.cpp - LVL instruction generator ----------------------------===//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#include "VE.h"10#include "VESubtarget.h"11#include "llvm/CodeGen/MachineFunctionPass.h"12#include "llvm/CodeGen/MachineInstrBuilder.h"13#include "llvm/CodeGen/TargetInstrInfo.h"14 15using namespace llvm;16 17#define DEBUG_TYPE "lvl-gen"18 19namespace {20struct LVLGen : public MachineFunctionPass {21  const TargetInstrInfo *TII;22  const TargetRegisterInfo *TRI;23 24  static char ID;25  LVLGen() : MachineFunctionPass(ID) {}26  bool runOnMachineBasicBlock(MachineBasicBlock &MBB);27  bool runOnMachineFunction(MachineFunction &F) override;28 29  unsigned getVL(const MachineInstr &MI);30  int getVLIndex(unsigned Opcode);31};32char LVLGen::ID = 0;33 34} // end of anonymous namespace35 36FunctionPass *llvm::createLVLGenPass() { return new LVLGen; }37 38int LVLGen::getVLIndex(unsigned Opcode) {39  const MCInstrDesc &MCID = TII->get(Opcode);40 41  // If an instruction has VLIndex information, return it.42  if (HAS_VLINDEX(MCID.TSFlags))43    return GET_VLINDEX(MCID.TSFlags);44 45  return -1;46}47 48// returns a register holding a vector length. NoRegister is returned when49// this MI does not have a vector length.50unsigned LVLGen::getVL(const MachineInstr &MI) {51  int Index = getVLIndex(MI.getOpcode());52  if (Index >= 0)53    return MI.getOperand(Index).getReg();54 55  return VE::NoRegister;56}57 58bool LVLGen::runOnMachineBasicBlock(MachineBasicBlock &MBB) {59#define RegName(no)                                                            \60  (MBB.getParent()->getSubtarget<VESubtarget>().getRegisterInfo()->getName(no))61 62  bool Changed = false;63  bool HasRegForVL = false;64  unsigned RegForVL;65 66  for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end();) {67    MachineBasicBlock::iterator MI = I;68 69    // Check whether MI uses a vector length operand.  If so, we prepare for VL70    // register.  We would like to reuse VL register as much as possible.  We71    // also would like to keep the number of LEA instructions as fewer as72    // possible.  Therefore, we use a regular scalar register to hold immediate73    // values to load VL register.  And try to reuse identical scalar registers74    // to avoid new LVLr instructions as much as possible.75    unsigned Reg = getVL(*MI);76    if (Reg != VE::NoRegister) {77      LLVM_DEBUG(dbgs() << "Vector instruction found: ");78      LLVM_DEBUG(MI->dump());79      LLVM_DEBUG(dbgs() << "Vector length is " << RegName(Reg) << ". ");80      LLVM_DEBUG(dbgs() << "Current VL is "81                        << (HasRegForVL ? RegName(RegForVL) : "unknown")82                        << ". ");83 84      if (!HasRegForVL || RegForVL != Reg) {85        // Use VL, but a different value in a different scalar register.86        // So, generate new LVL instruction just before the current instruction.87        LLVM_DEBUG(dbgs() << "Generate a LVL instruction to load "88                          << RegName(Reg) << ".\n");89        BuildMI(MBB, I, MI->getDebugLoc(), TII->get(VE::LVLr)).addReg(Reg);90        HasRegForVL = true;91        RegForVL = Reg;92        Changed = true;93      } else {94        LLVM_DEBUG(dbgs() << "Reuse current VL.\n");95      }96    }97    // Check the update of a given scalar register holding an immediate value98    // for VL register.  Also, a call doesn't preserve VL register.99    if (HasRegForVL) {100      if (MI->definesRegister(RegForVL, TRI) ||101          MI->modifiesRegister(RegForVL, TRI) ||102          MI->killsRegister(RegForVL, TRI) || MI->isCall()) {103        // The latest VL is needed to be updated, so disable HasRegForVL.104        LLVM_DEBUG(dbgs() << RegName(RegForVL) << " is needed to be updated: ");105        LLVM_DEBUG(MI->dump());106        HasRegForVL = false;107      }108    }109 110    ++I;111  }112  return Changed;113}114 115bool LVLGen::runOnMachineFunction(MachineFunction &F) {116  LLVM_DEBUG(dbgs() << "********** Begin LVLGen **********\n");117  LLVM_DEBUG(dbgs() << "********** Function: " << F.getName() << '\n');118  LLVM_DEBUG(F.dump());119 120  bool Changed = false;121 122  const VESubtarget &Subtarget = F.getSubtarget<VESubtarget>();123  TII = Subtarget.getInstrInfo();124  TRI = Subtarget.getRegisterInfo();125 126  for (MachineBasicBlock &MBB : F)127    Changed |= runOnMachineBasicBlock(MBB);128 129  if (Changed) {130    LLVM_DEBUG(dbgs() << "\n");131    LLVM_DEBUG(F.dump());132  }133  LLVM_DEBUG(dbgs() << "********** End LVLGen **********\n");134  return Changed;135}136