Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/VE/LVLGen.cpp
35294 views
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 (MachineBasicBlock &MBB : F)
129
Changed |= runOnMachineBasicBlock(MBB);
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
139