LLVM  14.0.0git
HexagonFixupHwLoops.cpp
Go to the documentation of this file.
1 //===---- HexagonFixupHwLoops.cpp - Fixup HW loops too far from LOOPn. ----===//
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 // The loop start address in the LOOPn instruction is encoded as a distance
8 // from the LOOPn instruction itself. If the start address is too far from
9 // the LOOPn instruction, the instruction needs to use a constant extender.
10 // This pass will identify and convert such LOOPn instructions to a proper
11 // form.
12 //===----------------------------------------------------------------------===//
13 
14 #include "Hexagon.h"
15 #include "HexagonTargetMachine.h"
16 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/CodeGen/Passes.h"
23 #include "llvm/Pass.h"
24 
25 using namespace llvm;
26 
28  "hexagon-loop-range", cl::Hidden, cl::init(200),
29  cl::desc("Restrict range of loopN instructions (testing only)"));
30 
31 namespace llvm {
34 }
35 
36 namespace {
37  struct HexagonFixupHwLoops : public MachineFunctionPass {
38  public:
39  static char ID;
40 
41  HexagonFixupHwLoops() : MachineFunctionPass(ID) {
43  }
44 
45  bool runOnMachineFunction(MachineFunction &MF) override;
46 
47  MachineFunctionProperties getRequiredProperties() const override {
50  }
51 
52  StringRef getPassName() const override {
53  return "Hexagon Hardware Loop Fixup";
54  }
55 
56  void getAnalysisUsage(AnalysisUsage &AU) const override {
57  AU.setPreservesCFG();
59  }
60 
61  private:
62  /// Check the offset between each loop instruction and
63  /// the loop basic block to determine if we can use the LOOP instruction
64  /// or if we need to set the LC/SA registers explicitly.
65  bool fixupLoopInstrs(MachineFunction &MF);
66 
67  /// Replace loop instruction with the constant extended
68  /// version if the loop label is too far from the loop instruction.
69  void useExtLoopInstr(MachineFunction &MF,
71  };
72 
73  char HexagonFixupHwLoops::ID = 0;
74 }
75 
76 INITIALIZE_PASS(HexagonFixupHwLoops, "hwloopsfixup",
77  "Hexagon Hardware Loops Fixup", false, false)
78 
80  return new HexagonFixupHwLoops();
81 }
82 
83 /// Returns true if the instruction is a hardware loop instruction.
84 static bool isHardwareLoop(const MachineInstr &MI) {
85  return MI.getOpcode() == Hexagon::J2_loop0r ||
86  MI.getOpcode() == Hexagon::J2_loop0i ||
87  MI.getOpcode() == Hexagon::J2_loop1r ||
88  MI.getOpcode() == Hexagon::J2_loop1i;
89 }
90 
91 bool HexagonFixupHwLoops::runOnMachineFunction(MachineFunction &MF) {
92  if (skipFunction(MF.getFunction()))
93  return false;
94  return fixupLoopInstrs(MF);
95 }
96 
97 /// For Hexagon, if the loop label is to far from the
98 /// loop instruction then we need to set the LC0 and SA0 registers
99 /// explicitly instead of using LOOP(start,count). This function
100 /// checks the distance, and generates register assignments if needed.
101 ///
102 /// This function makes two passes over the basic blocks. The first
103 /// pass computes the offset of the basic block from the start.
104 /// The second pass checks all the loop instructions.
105 bool HexagonFixupHwLoops::fixupLoopInstrs(MachineFunction &MF) {
106 
107  // Offset of the current instruction from the start.
108  unsigned InstOffset = 0;
109  // Map for each basic block to it's first instruction.
111 
112  const HexagonInstrInfo *HII =
113  static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
114 
115  // First pass - compute the offset of each basic block.
116  for (const MachineBasicBlock &MBB : MF) {
117  if (MBB.getAlignment() != Align(1)) {
118  // Although we don't know the exact layout of the final code, we need
119  // to account for alignment padding somehow. This heuristic pads each
120  // aligned basic block according to the alignment value.
121  InstOffset = alignTo(InstOffset, MBB.getAlignment());
122  }
123 
124  BlockToInstOffset[&MBB] = InstOffset;
125  for (const MachineInstr &MI : MBB)
126  InstOffset += HII->getSize(MI);
127  }
128 
129  // Second pass - check each loop instruction to see if it needs to be
130  // converted.
131  bool Changed = false;
132  for (MachineBasicBlock &MBB : MF) {
133  InstOffset = BlockToInstOffset[&MBB];
134 
135  // Loop over all the instructions.
138  while (MII != MIE) {
139  unsigned InstSize = HII->getSize(*MII);
140  if (MII->isMetaInstruction()) {
141  ++MII;
142  continue;
143  }
144  if (isHardwareLoop(*MII)) {
145  assert(MII->getOperand(0).isMBB() &&
146  "Expect a basic block as loop operand");
147  MachineBasicBlock *TargetBB = MII->getOperand(0).getMBB();
148  unsigned Diff = AbsoluteDifference(InstOffset,
149  BlockToInstOffset[TargetBB]);
150  if (Diff > MaxLoopRange) {
151  useExtLoopInstr(MF, MII);
152  MII = MBB.erase(MII);
153  Changed = true;
154  } else {
155  ++MII;
156  }
157  } else {
158  ++MII;
159  }
160  InstOffset += InstSize;
161  }
162  }
163 
164  return Changed;
165 }
166 
167 /// Replace loop instructions with the constant extended version.
168 void HexagonFixupHwLoops::useExtLoopInstr(MachineFunction &MF,
171  MachineBasicBlock *MBB = MII->getParent();
172  DebugLoc DL = MII->getDebugLoc();
174  unsigned newOp;
175  switch (MII->getOpcode()) {
176  case Hexagon::J2_loop0r:
177  newOp = Hexagon::J2_loop0rext;
178  break;
179  case Hexagon::J2_loop0i:
180  newOp = Hexagon::J2_loop0iext;
181  break;
182  case Hexagon::J2_loop1r:
183  newOp = Hexagon::J2_loop1rext;
184  break;
185  case Hexagon::J2_loop1i:
186  newOp = Hexagon::J2_loop1iext;
187  break;
188  default:
189  llvm_unreachable("Invalid Hardware Loop Instruction.");
190  }
191  MIB = BuildMI(*MBB, MII, DL, TII->get(newOp));
192 
193  for (unsigned i = 0; i < MII->getNumOperands(); ++i)
194  MIB.add(MII->getOperand(i));
195 }
i
i
Definition: README.txt:29
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:148
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
MathExtras.h
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
Pass.h
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:92
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
DenseMap.h
TargetInstrInfo.h
MaxLoopRange
static cl::opt< unsigned > MaxLoopRange("hexagon-loop-range", cl::Hidden, cl::init(200), cl::desc("Restrict range of loopN instructions (testing only)"))
llvm::MachineFunctionProperties
Properties which a MachineFunction may have at a given point in time.
Definition: MachineFunction.h:111
HexagonTargetMachine.h
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
llvm::MachineBasicBlock::erase
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Definition: MachineBasicBlock.cpp:1299
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineFunctionProperties::set
MachineFunctionProperties & set(Property P)
Definition: MachineFunction.h:169
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
Align
uint64_t Align
Definition: ELFObjHandler.cpp:83
INITIALIZE_PASS
INITIALIZE_PASS(HexagonFixupHwLoops, "hwloopsfixup", "Hexagon Hardware Loops Fixup", false, false) FunctionPass *llvm
Definition: HexagonFixupHwLoops.cpp:76
isHardwareLoop
static bool isHardwareLoop(const MachineInstr &MI)
Returns true if the instruction is a hardware loop instruction.
Definition: HexagonFixupHwLoops.cpp:84
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
Hexagon.h
llvm::MachineFunctionProperties::Property::NoVRegs
@ NoVRegs
llvm::HexagonInstrInfo::getSize
unsigned getSize(const MachineInstr &MI) const
Definition: HexagonInstrInfo.cpp:4473
Passes.h
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:626
llvm::cl::opt
Definition: CommandLine.h:1434
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:69
llvm::DenseMap
Definition: DenseMap.h:714
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
llvm::MachineBasicBlock::getAlignment
Align getAlignment() const
Return alignment of the basic block.
Definition: MachineBasicBlock.h:519
MachineFunctionPass.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::HexagonInstrInfo
Definition: HexagonInstrInfo.h:38
llvm::createHexagonFixupHwLoops
FunctionPass * createHexagonFixupHwLoops()
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:592
llvm::initializeHexagonFixupHwLoopsPass
void initializeHexagonFixupHwLoopsPass(PassRegistry &)
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
MachineInstrBuilder.h
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
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::cl::desc
Definition: CommandLine.h:414
MachineFunction.h
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
llvm::AbsoluteDifference
std::enable_if_t< std::is_unsigned< T >::value, T > AbsoluteDifference(T X, T Y)
Subtract two unsigned integers, X and Y, of type T and return the absolute value of the result.
Definition: MathExtras.h:794
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37