LLVM 20.0.0git
LVLGen.cpp
Go to the documentation of this file.
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"
14
15using namespace llvm;
16
17#define DEBUG_TYPE "lvl-gen"
18
19namespace {
20struct LVLGen : public MachineFunctionPass {
21 const TargetInstrInfo *TII;
23
24 static char ID;
25 LVLGen() : MachineFunctionPass(ID) {}
26 bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
28
29 unsigned getVL(const MachineInstr &MI);
30 int getVLIndex(unsigned Opcode);
31};
32char LVLGen::ID = 0;
33
34} // end of anonymous namespace
35
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 when
49// 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();) {
68
69 // Check whether MI uses a vector length operand. If so, we prepare for VL
70 // register. We would like to reuse VL register as much as possible. We
71 // also would like to keep the number of LEA instructions as fewer as
72 // possible. Therefore, we use a regular scalar register to hold immediate
73 // values to load VL register. And try to reuse identical scalar registers
74 // 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 value
98 // 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}
MachineBasicBlock & MBB
#define LLVM_DEBUG(...)
Definition: Debug.h:106
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define RegName(no)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
#define GET_VLINDEX(TSF)
Definition: VEInstrInfo.h:47
#define HAS_VLINDEX(TSF)
Definition: VEInstrInfo.h:46
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:310
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
Definition: MachineInstr.h:69
void dump() const
Definition: Pass.cpp:136
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const VEInstrInfo * getInstrInfo() const override
Definition: VESubtarget.h:51
const VERegisterInfo * getRegisterInfo() const override
Definition: VESubtarget.h:55
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createLVLGenPass()
Definition: LVLGen.cpp:36
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163