LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HexagonExpandPredSpillCode.cpp
Go to the documentation of this file.
1 //===-- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // The Hexagon processor has no instructions that load or store predicate
10 // registers directly. So, when these registers must be spilled a general
11 // purpose register must be found and the value copied to/from it from/to
12 // the predicate register. This code currently does not use the register
13 // scavenger mechanism available in the allocator. There are two registers
14 // reserved to allow spilling/restoring predicate registers. One is used to
15 // hold the predicate value. The other is used when stack frame offsets are
16 // too large.
17 //
18 //===----------------------------------------------------------------------===//
19 
20 #include "Hexagon.h"
22 #include "HexagonSubtarget.h"
23 #include "HexagonTargetMachine.h"
24 #include "llvm/ADT/Statistic.h"
31 #include "llvm/CodeGen/Passes.h"
34 #include "llvm/Support/Compiler.h"
35 #include "llvm/Support/Debug.h"
40 
41 using namespace llvm;
42 
43 
44 namespace llvm {
46 }
47 
48 
49 namespace {
50 
51 class HexagonExpandPredSpillCode : public MachineFunctionPass {
52  const HexagonTargetMachine& QTM;
53  const HexagonSubtarget &QST;
54 
55  public:
56  static char ID;
57  HexagonExpandPredSpillCode(const HexagonTargetMachine& TM) :
58  MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {
61  }
62 
63  const char *getPassName() const {
64  return "Hexagon Expand Predicate Spill Code";
65  }
66  bool runOnMachineFunction(MachineFunction &Fn);
67 };
68 
69 
71 
72 
73 bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
74 
75  const HexagonInstrInfo *TII = QTM.getInstrInfo();
76 
77  // Loop over all of the basic blocks.
78  for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
79  MBBb != MBBe; ++MBBb) {
80  MachineBasicBlock* MBB = MBBb;
81  // Traverse the basic block.
82  for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
83  ++MII) {
84  MachineInstr *MI = MII;
85  int Opc = MI->getOpcode();
86  if (Opc == Hexagon::STriw_pred) {
87  // STriw_pred [R30], ofst, SrcReg;
88  unsigned FP = MI->getOperand(0).getReg();
89  assert(FP == QTM.getRegisterInfo()->getFrameRegister() &&
90  "Not a Frame Pointer, Nor a Spill Slot");
91  assert(MI->getOperand(1).isImm() && "Not an offset");
92  int Offset = MI->getOperand(1).getImm();
93  int SrcReg = MI->getOperand(2).getReg();
94  assert(Hexagon::PredRegsRegClass.contains(SrcReg) &&
95  "Not a predicate register");
96  if (!TII->isValidOffset(Hexagon::STriw_indexed, Offset)) {
97  if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
98  BuildMI(*MBB, MII, MI->getDebugLoc(),
99  TII->get(Hexagon::CONST32_Int_Real),
100  HEXAGON_RESERVED_REG_1).addImm(Offset);
101  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr),
103  .addReg(FP).addReg(HEXAGON_RESERVED_REG_1);
104  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
105  HEXAGON_RESERVED_REG_2).addReg(SrcReg);
106  BuildMI(*MBB, MII, MI->getDebugLoc(),
107  TII->get(Hexagon::STriw_indexed))
108  .addReg(HEXAGON_RESERVED_REG_1)
110  } else {
111  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
112  HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
113  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
114  HEXAGON_RESERVED_REG_2).addReg(SrcReg);
115  BuildMI(*MBB, MII, MI->getDebugLoc(),
116  TII->get(Hexagon::STriw_indexed))
117  .addReg(HEXAGON_RESERVED_REG_1)
118  .addImm(0)
120  }
121  } else {
122  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
123  HEXAGON_RESERVED_REG_2).addReg(SrcReg);
124  BuildMI(*MBB, MII, MI->getDebugLoc(),
125  TII->get(Hexagon::STriw_indexed)).
126  addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2);
127  }
128  MII = MBB->erase(MI);
129  --MII;
130  } else if (Opc == Hexagon::LDriw_pred) {
131  // DstReg = LDriw_pred [R30], ofst.
132  int DstReg = MI->getOperand(0).getReg();
133  assert(Hexagon::PredRegsRegClass.contains(DstReg) &&
134  "Not a predicate register");
135  unsigned FP = MI->getOperand(1).getReg();
136  assert(FP == QTM.getRegisterInfo()->getFrameRegister() &&
137  "Not a Frame Pointer, Nor a Spill Slot");
138  assert(MI->getOperand(2).isImm() && "Not an offset");
139  int Offset = MI->getOperand(2).getImm();
140  if (!TII->isValidOffset(Hexagon::LDriw, Offset)) {
141  if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
142  BuildMI(*MBB, MII, MI->getDebugLoc(),
143  TII->get(Hexagon::CONST32_Int_Real),
144  HEXAGON_RESERVED_REG_1).addImm(Offset);
145  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr),
147  .addReg(FP)
149  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
151  .addReg(HEXAGON_RESERVED_REG_1)
152  .addImm(0);
153  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
154  DstReg).addReg(HEXAGON_RESERVED_REG_2);
155  } else {
156  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
157  HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
158  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
160  .addReg(HEXAGON_RESERVED_REG_1)
161  .addImm(0);
162  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
163  DstReg).addReg(HEXAGON_RESERVED_REG_2);
164  }
165  } else {
166  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
167  HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset);
168  BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
169  DstReg).addReg(HEXAGON_RESERVED_REG_2);
170  }
171  MII = MBB->erase(MI);
172  --MII;
173  }
174  }
175  }
176 
177  return true;
178 }
179 
180 }
181 
182 //===----------------------------------------------------------------------===//
183 // Public Constructor Functions
184 //===----------------------------------------------------------------------===//
185 
187  const char *Name = "Hexagon Expand Predicate Spill Code";
188  PassInfo *PI = new PassInfo(Name, "hexagon-spill-pred",
189  &HexagonExpandPredSpillCode::ID,
190  0, false, false);
191  Registry.registerPass(*PI, true);
192 }
193 
196 }
197 
200  return new HexagonExpandPredSpillCode(TM);
201 }
instr_iterator erase(instr_iterator I)
static PassRegistry * getPassRegistry()
#define HEXAGON_RESERVED_REG_1
#define HEXAGON_RESERVED_REG_2
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
const MachineInstrBuilder & addImm(int64_t Val) const
bool isValidOffset(const int Opcode, const int Offset) const
int getOpcode() const
Definition: MachineInstr.h:261
int64_t getImm() const
bundle_iterator< MachineInstr, instr_iterator > iterator
const MCInstrInfo & MII
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
FunctionPass * createHexagonExpandPredSpillCode(const HexagonTargetMachine &TM)
void initializeHexagonExpandPredSpillCodePass(PassRegistry &)
static void initializePassOnce(PassRegistry &Registry)
unsigned getReg() const
getReg - Returns the register number.
#define CALL_ONCE_INITIALIZATION(function)
Definition: PassSupport.h:133
BasicBlockListType::iterator iterator
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
void registerPass(const PassInfo &PI, bool ShouldFree=false)
DebugLoc getDebugLoc() const
Definition: MachineInstr.h:244