blob: ae9ba7d8afac28db33b21067268467a96b069b9e [file] [log] [blame]
Jia Liub22310f2012-02-18 12:03:15 +00001//===-- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ------===//
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002//
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//
Jia Liub22310f2012-02-18 12:03:15 +00008//===----------------------------------------------------------------------===//
Tony Linthicum1213a7a2011-12-12 21:14:40 +00009// The Hexagon processor has no instructions that load or store predicate
Sirish Pandef8e5e3c2012-05-03 21:52:53 +000010// 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
Tony Linthicum1213a7a2011-12-12 21:14:40 +000013// 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
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "Hexagon.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000021#include "HexagonMachineFunctionInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000022#include "HexagonSubtarget.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000023#include "llvm/ADT/Statistic.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000024#include "llvm/CodeGen/LatencyPriorityQueue.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000025#include "llvm/CodeGen/MachineDominators.h"
26#include "llvm/CodeGen/MachineFunctionPass.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000027#include "llvm/CodeGen/MachineInstrBuilder.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000028#include "llvm/CodeGen/MachineLoopInfo.h"
29#include "llvm/CodeGen/MachineRegisterInfo.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000030#include "llvm/CodeGen/Passes.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000031#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000032#include "llvm/CodeGen/SchedulerRegistry.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000033#include "llvm/Support/Compiler.h"
34#include "llvm/Support/Debug.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000035#include "llvm/Support/MathExtras.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000036#include "llvm/Target/TargetInstrInfo.h"
37#include "llvm/Target/TargetMachine.h"
38#include "llvm/Target/TargetRegisterInfo.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000039
40using namespace llvm;
41
42
Krzysztof Parzyszek18ee1192013-05-06 21:58:00 +000043namespace llvm {
44 void initializeHexagonExpandPredSpillCodePass(PassRegistry&);
45}
46
47
Tony Linthicum1213a7a2011-12-12 21:14:40 +000048namespace {
49
50class HexagonExpandPredSpillCode : public MachineFunctionPass {
Tony Linthicum1213a7a2011-12-12 21:14:40 +000051 public:
52 static char ID;
Eric Christopher6ff7ed62015-02-02 18:46:31 +000053 HexagonExpandPredSpillCode() : MachineFunctionPass(ID) {
Krzysztof Parzyszek18ee1192013-05-06 21:58:00 +000054 PassRegistry &Registry = *PassRegistry::getPassRegistry();
55 initializeHexagonExpandPredSpillCodePass(Registry);
56 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +000057
Craig Topper906c2cd2014-04-29 07:58:16 +000058 const char *getPassName() const override {
Tony Linthicum1213a7a2011-12-12 21:14:40 +000059 return "Hexagon Expand Predicate Spill Code";
60 }
Craig Topper906c2cd2014-04-29 07:58:16 +000061 bool runOnMachineFunction(MachineFunction &Fn) override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +000062};
63
64
65char HexagonExpandPredSpillCode::ID = 0;
66
67
68bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
69
Eric Christopher6ff7ed62015-02-02 18:46:31 +000070 const HexagonSubtarget &QST = Fn.getSubtarget<HexagonSubtarget>();
71 const HexagonRegisterInfo *TRI = QST.getRegisterInfo();
72 const HexagonInstrInfo *TII = QST.getInstrInfo();
Tony Linthicum1213a7a2011-12-12 21:14:40 +000073
74 // Loop over all of the basic blocks.
75 for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
76 MBBb != MBBe; ++MBBb) {
77 MachineBasicBlock* MBB = MBBb;
78 // Traverse the basic block.
79 for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
80 ++MII) {
81 MachineInstr *MI = MII;
82 int Opc = MI->getOpcode();
83 if (Opc == Hexagon::STriw_pred) {
84 // STriw_pred [R30], ofst, SrcReg;
85 unsigned FP = MI->getOperand(0).getReg();
Eric Christopher6ff7ed62015-02-02 18:46:31 +000086 assert(FP == TRI->getFrameRegister() &&
87 "Not a Frame Pointer, Nor a Spill Slot");
Tony Linthicum1213a7a2011-12-12 21:14:40 +000088 assert(MI->getOperand(1).isImm() && "Not an offset");
89 int Offset = MI->getOperand(1).getImm();
90 int SrcReg = MI->getOperand(2).getReg();
91 assert(Hexagon::PredRegsRegClass.contains(SrcReg) &&
92 "Not a predicate register");
Colin LeMahieubda31b42014-12-29 20:44:51 +000093 if (!TII->isValidOffset(Hexagon::S2_storeri_io, Offset)) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +000094 if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
95 BuildMI(*MBB, MII, MI->getDebugLoc(),
96 TII->get(Hexagon::CONST32_Int_Real),
97 HEXAGON_RESERVED_REG_1).addImm(Offset);
Colin LeMahieuefa74e02014-11-18 20:28:11 +000098 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add),
Tony Linthicum1213a7a2011-12-12 21:14:40 +000099 HEXAGON_RESERVED_REG_1)
100 .addReg(FP).addReg(HEXAGON_RESERVED_REG_1);
Colin LeMahieu30dcb232014-12-09 18:16:49 +0000101 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000102 HEXAGON_RESERVED_REG_2).addReg(SrcReg);
103 BuildMI(*MBB, MII, MI->getDebugLoc(),
Colin LeMahieubda31b42014-12-29 20:44:51 +0000104 TII->get(Hexagon::S2_storeri_io))
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000105 .addReg(HEXAGON_RESERVED_REG_1)
106 .addImm(0).addReg(HEXAGON_RESERVED_REG_2);
107 } else {
108 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
109 HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
Colin LeMahieu30dcb232014-12-09 18:16:49 +0000110 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000111 HEXAGON_RESERVED_REG_2).addReg(SrcReg);
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000112 BuildMI(*MBB, MII, MI->getDebugLoc(),
Colin LeMahieubda31b42014-12-29 20:44:51 +0000113 TII->get(Hexagon::S2_storeri_io))
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000114 .addReg(HEXAGON_RESERVED_REG_1)
115 .addImm(0)
116 .addReg(HEXAGON_RESERVED_REG_2);
117 }
118 } else {
Colin LeMahieu30dcb232014-12-09 18:16:49 +0000119 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000120 HEXAGON_RESERVED_REG_2).addReg(SrcReg);
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000121 BuildMI(*MBB, MII, MI->getDebugLoc(),
Colin LeMahieubda31b42014-12-29 20:44:51 +0000122 TII->get(Hexagon::S2_storeri_io)).
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000123 addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2);
124 }
125 MII = MBB->erase(MI);
126 --MII;
127 } else if (Opc == Hexagon::LDriw_pred) {
128 // DstReg = LDriw_pred [R30], ofst.
129 int DstReg = MI->getOperand(0).getReg();
130 assert(Hexagon::PredRegsRegClass.contains(DstReg) &&
131 "Not a predicate register");
132 unsigned FP = MI->getOperand(1).getReg();
Eric Christopher6ff7ed62015-02-02 18:46:31 +0000133 assert(FP == TRI->getFrameRegister() &&
134 "Not a Frame Pointer, Nor a Spill Slot");
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000135 assert(MI->getOperand(2).isImm() && "Not an offset");
136 int Offset = MI->getOperand(2).getImm();
Colin LeMahieu026e88d2014-12-23 20:02:16 +0000137 if (!TII->isValidOffset(Hexagon::L2_loadri_io, Offset)) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000138 if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
139 BuildMI(*MBB, MII, MI->getDebugLoc(),
140 TII->get(Hexagon::CONST32_Int_Real),
141 HEXAGON_RESERVED_REG_1).addImm(Offset);
Colin LeMahieuefa74e02014-11-18 20:28:11 +0000142 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000143 HEXAGON_RESERVED_REG_1)
144 .addReg(FP)
145 .addReg(HEXAGON_RESERVED_REG_1);
Colin LeMahieu026e88d2014-12-23 20:02:16 +0000146 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000147 HEXAGON_RESERVED_REG_2)
148 .addReg(HEXAGON_RESERVED_REG_1)
149 .addImm(0);
Colin LeMahieu30dcb232014-12-09 18:16:49 +0000150 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000151 DstReg).addReg(HEXAGON_RESERVED_REG_2);
152 } else {
153 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
154 HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
Colin LeMahieu026e88d2014-12-23 20:02:16 +0000155 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000156 HEXAGON_RESERVED_REG_2)
157 .addReg(HEXAGON_RESERVED_REG_1)
158 .addImm(0);
Colin LeMahieu30dcb232014-12-09 18:16:49 +0000159 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000160 DstReg).addReg(HEXAGON_RESERVED_REG_2);
161 }
162 } else {
Colin LeMahieu026e88d2014-12-23 20:02:16 +0000163 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000164 HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset);
Colin LeMahieu30dcb232014-12-09 18:16:49 +0000165 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000166 DstReg).addReg(HEXAGON_RESERVED_REG_2);
167 }
168 MII = MBB->erase(MI);
169 --MII;
170 }
171 }
172 }
173
174 return true;
175}
176
177}
178
179//===----------------------------------------------------------------------===//
180// Public Constructor Functions
181//===----------------------------------------------------------------------===//
182
Krzysztof Parzyszek18ee1192013-05-06 21:58:00 +0000183static void initializePassOnce(PassRegistry &Registry) {
184 const char *Name = "Hexagon Expand Predicate Spill Code";
185 PassInfo *PI = new PassInfo(Name, "hexagon-spill-pred",
186 &HexagonExpandPredSpillCode::ID,
Craig Topper062a2ba2014-04-25 05:30:21 +0000187 nullptr, false, false);
Krzysztof Parzyszek18ee1192013-05-06 21:58:00 +0000188 Registry.registerPass(*PI, true);
189}
190
191void llvm::initializeHexagonExpandPredSpillCodePass(PassRegistry &Registry) {
192 CALL_ONCE_INITIALIZATION(initializePassOnce)
193}
194
Krzysztof Parzyszekd5007472013-05-06 18:38:37 +0000195FunctionPass*
Eric Christopher6ff7ed62015-02-02 18:46:31 +0000196llvm::createHexagonExpandPredSpillCode() {
197 return new HexagonExpandPredSpillCode();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000198}