LLVM  14.0.0git
AVRRelaxMemOperations.cpp
Go to the documentation of this file.
1 //===-- AVRRelaxMemOperations.cpp - Relax out of range loads/stores -------===//
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 // This file contains a pass which relaxes out of range memory operations into
10 // equivalent operations which handle bigger addresses.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "AVR.h"
15 #include "AVRInstrInfo.h"
16 #include "AVRTargetMachine.h"
18 
23 
24 using namespace llvm;
25 
26 #define AVR_RELAX_MEM_OPS_NAME "AVR memory operation relaxation pass"
27 
28 namespace {
29 
30 class AVRRelaxMem : public MachineFunctionPass {
31 public:
32  static char ID;
33 
34  AVRRelaxMem() : MachineFunctionPass(ID) {
36  }
37 
38  bool runOnMachineFunction(MachineFunction &MF) override;
39 
40  StringRef getPassName() const override { return AVR_RELAX_MEM_OPS_NAME; }
41 
42 private:
43  typedef MachineBasicBlock Block;
44  typedef Block::iterator BlockIt;
45 
46  const TargetInstrInfo *TII;
47 
48  template <unsigned OP> bool relax(Block &MBB, BlockIt MBBI);
49 
50  bool runOnBasicBlock(Block &MBB);
51  bool runOnInstruction(Block &MBB, BlockIt MBBI);
52 
53  MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode) {
54  return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode));
55  }
56 };
57 
58 char AVRRelaxMem::ID = 0;
59 
60 bool AVRRelaxMem::runOnMachineFunction(MachineFunction &MF) {
61  bool Modified = false;
62 
63  const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
64  TII = STI.getInstrInfo();
65 
66  for (Block &MBB : MF) {
67  bool BlockModified = runOnBasicBlock(MBB);
68  Modified |= BlockModified;
69  }
70 
71  return Modified;
72 }
73 
74 bool AVRRelaxMem::runOnBasicBlock(Block &MBB) {
75  bool Modified = false;
76 
77  BlockIt MBBI = MBB.begin(), E = MBB.end();
78  while (MBBI != E) {
79  BlockIt NMBBI = std::next(MBBI);
80  Modified |= runOnInstruction(MBB, MBBI);
81  MBBI = NMBBI;
82  }
83 
84  return Modified;
85 }
86 
87 template <> bool AVRRelaxMem::relax<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) {
88  MachineInstr &MI = *MBBI;
89 
90  MachineOperand &Ptr = MI.getOperand(0);
91  MachineOperand &Src = MI.getOperand(2);
92  int64_t Imm = MI.getOperand(1).getImm();
93 
94  // We can definitely optimise this better.
95  if (Imm > 63) {
96  // Push the previous state of the pointer register.
97  // This instruction must preserve the value.
98  buildMI(MBB, MBBI, AVR::PUSHWRr).addReg(Ptr.getReg());
99 
100  // Add the immediate to the pointer register.
101  buildMI(MBB, MBBI, AVR::SBCIWRdK)
102  .addReg(Ptr.getReg(), RegState::Define)
103  .addReg(Ptr.getReg())
104  .addImm(-Imm);
105 
106  // Store the value in the source register to the address
107  // pointed to by the pointer register.
108  buildMI(MBB, MBBI, AVR::STWPtrRr)
109  .addReg(Ptr.getReg())
110  .addReg(Src.getReg(), getKillRegState(Src.isKill()));
111 
112  // Pop the original state of the pointer register.
113  buildMI(MBB, MBBI, AVR::POPWRd)
114  .addDef(Ptr.getReg(), getKillRegState(Ptr.isKill()));
115 
116  MI.removeFromParent();
117  }
118 
119  return false;
120 }
121 
122 bool AVRRelaxMem::runOnInstruction(Block &MBB, BlockIt MBBI) {
123  MachineInstr &MI = *MBBI;
124  int Opcode = MBBI->getOpcode();
125 
126 #define RELAX(Op) \
127  case Op: \
128  return relax<Op>(MBB, MI)
129 
130  switch (Opcode) { RELAX(AVR::STDWPtrQRr); }
131 #undef RELAX
132  return false;
133 }
134 
135 } // end of anonymous namespace
136 
137 INITIALIZE_PASS(AVRRelaxMem, "avr-relax-mem", AVR_RELAX_MEM_OPS_NAME, false,
138  false)
139 
140 namespace llvm {
141 
142 FunctionPass *createAVRRelaxMemPass() { return new AVRRelaxMem(); }
143 
144 } // end of namespace llvm
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
runOnBasicBlock
static bool runOnBasicBlock(MachineBasicBlock *MBB, unsigned BasicBlockNum, VRegRenamer &Renamer)
Definition: MIRCanonicalizerPass.cpp:369
AVR_RELAX_MEM_OPS_NAME
#define AVR_RELAX_MEM_OPS_NAME
Definition: AVRRelaxMemOperations.cpp:26
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
MachineRegisterInfo.h
llvm::MachineOperand::isKill
bool isKill() const
Definition: MachineOperand.h:390
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
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::AVRSubtarget
A specific AVR target MCU.
Definition: AVRSubtarget.h:31
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
RELAX
#define RELAX(Op)
LoopDeletionResult::Modified
@ Modified
llvm::AVRSubtarget::getInstrInfo
const AVRInstrInfo * getInstrInfo() const override
Definition: AVRSubtarget.h:41
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:44
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:626
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:69
MachineFunctionPass.h
AVRTargetMachine.h
AVRMCTargetDesc.h
llvm::initializeAVRRelaxMemPass
void initializeAVRRelaxMemPass(PassRegistry &)
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
MBBI
MachineBasicBlock MachineBasicBlock::iterator MBBI
Definition: AArch64SLSHardening.cpp:75
INITIALIZE_PASS
INITIALIZE_PASS(AVRRelaxMem, "avr-relax-mem", AVR_RELAX_MEM_OPS_NAME, false, false) namespace llvm
Definition: AVRRelaxMemOperations.cpp:137
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
AVR.h
llvm::getKillRegState
unsigned getKillRegState(bool B)
Definition: MachineInstrBuilder.h:508
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
AVRInstrInfo.h
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
TargetRegisterInfo.h
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
llvm::createAVRRelaxMemPass
FunctionPass * createAVRRelaxMemPass()
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37