LLVM  14.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"
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();) {
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 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1558
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:233
llvm::VESubtarget::getRegisterInfo
const VERegisterInfo * getRegisterInfo() const override
Definition: VESubtarget.h:55
TargetInstrInfo.h
HAS_VLINDEX
#define HAS_VLINDEX(TSF)
Definition: VEInstrInfo.h:46
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1559
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:56
MachineRegisterInfo.h
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::MCInstrDesc::TSFlags
uint64_t TSFlags
Definition: MCInstrDesc.h:203
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
TargetMachine.h
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:195
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::createLVLGenPass
FunctionPass * createLVLGenPass()
Definition: LVLGen.cpp:38
I
#define I(x, y, z)
Definition: MD5.cpp:59
MachineFunctionPass.h
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::MachineFunction
Definition: MachineFunction.h:241
llvm::Pass::dump
void dump() const
Definition: Pass.cpp:131
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::VESubtarget::getInstrInfo
const VEInstrInfo * getInstrInfo() const override
Definition: VESubtarget.h:51
llvm::ilist_iterator
Iterator for intrusive lists based on ilist_node.
Definition: ilist_iterator.h:57
VE.h
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
MachineInstrBuilder.h
llvm::VESubtarget
Definition: VESubtarget.h:31
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
VESubtarget.h
GET_VLINDEX
#define GET_VLINDEX(TSF)
Definition: VEInstrInfo.h:47
RegName
#define RegName(no)
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38