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;
LVLGen__anone9a7728f0111::LVLGen27 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
createLVLGenPass()38 FunctionPass *llvm::createLVLGenPass() { return new LVLGen; }
39
getVLIndex(unsigned Opcode)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.
getVL(const MachineInstr & MI)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
runOnMachineBasicBlock(MachineBasicBlock & MBB)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
runOnMachineFunction(MachineFunction & F)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