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