HexagonExpandPredSpillCode.cpp revision 280031
1239310Sdim//===-- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ------===//
2239310Sdim//
3239310Sdim//                     The LLVM Compiler Infrastructure
4239310Sdim//
5239310Sdim// This file is distributed under the University of Illinois Open Source
6239310Sdim// License. See LICENSE.TXT for details.
7239310Sdim//
8239310Sdim//===----------------------------------------------------------------------===//
9239310Sdim// The Hexagon processor has no instructions that load or store predicate
10239310Sdim// registers directly.  So, when these registers must be spilled a general
11239310Sdim// purpose register must be found and the value copied to/from it from/to
12239310Sdim// the predicate register.  This code currently does not use the register
13239310Sdim// scavenger mechanism available in the allocator.  There are two registers
14239310Sdim// reserved to allow spilling/restoring predicate registers.  One is used to
15249423Sdim// hold the predicate value.  The other is used when stack frame offsets are
16239310Sdim// too large.
17249423Sdim//
18249423Sdim//===----------------------------------------------------------------------===//
19280031Sdim
20288943Sdim#include "Hexagon.h"
21239310Sdim#include "HexagonMachineFunctionInfo.h"
22239310Sdim#include "HexagonSubtarget.h"
23239310Sdim#include "HexagonTargetMachine.h"
24239310Sdim#include "llvm/ADT/Statistic.h"
25239310Sdim#include "llvm/CodeGen/LatencyPriorityQueue.h"
26249423Sdim#include "llvm/CodeGen/MachineDominators.h"
27276479Sdim#include "llvm/CodeGen/MachineFunctionPass.h"
28288943Sdim#include "llvm/CodeGen/MachineInstrBuilder.h"
29276479Sdim#include "llvm/CodeGen/MachineLoopInfo.h"
30239310Sdim#include "llvm/CodeGen/MachineRegisterInfo.h"
31239310Sdim#include "llvm/CodeGen/Passes.h"
32239310Sdim#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
33239310Sdim#include "llvm/CodeGen/SchedulerRegistry.h"
34249423Sdim#include "llvm/Support/Compiler.h"
35249423Sdim#include "llvm/Support/Debug.h"
36249423Sdim#include "llvm/Support/MathExtras.h"
37239310Sdim#include "llvm/Target/TargetInstrInfo.h"
38239310Sdim#include "llvm/Target/TargetMachine.h"
39239310Sdim#include "llvm/Target/TargetRegisterInfo.h"
40239310Sdim
41239310Sdimusing namespace llvm;
42239310Sdim
43239310Sdim
44239310Sdimnamespace llvm {
45239310Sdim  void initializeHexagonExpandPredSpillCodePass(PassRegistry&);
46239310Sdim}
47239310Sdim
48239310Sdim
49239310Sdimnamespace {
50249423Sdim
51249423Sdimclass HexagonExpandPredSpillCode : public MachineFunctionPass {
52251662Sdim    const HexagonTargetMachine& QTM;
53288943Sdim    const HexagonSubtarget &QST;
54276479Sdim
55276479Sdim public:
56296417Sdim    static char ID;
57288943Sdim    HexagonExpandPredSpillCode(const HexagonTargetMachine& TM) :
58288943Sdim      MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {
59249423Sdim      PassRegistry &Registry = *PassRegistry::getPassRegistry();
60239310Sdim      initializeHexagonExpandPredSpillCodePass(Registry);
61239310Sdim    }
62239310Sdim
63239310Sdim    const char *getPassName() const override {
64239310Sdim      return "Hexagon Expand Predicate Spill Code";
65239310Sdim    }
66249423Sdim    bool runOnMachineFunction(MachineFunction &Fn) override;
67249423Sdim};
68296417Sdim
69296417Sdim
70296417Sdimchar HexagonExpandPredSpillCode::ID = 0;
71296417Sdim
72296417Sdim
73296417Sdimbool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
74296417Sdim
75296417Sdim  const HexagonInstrInfo *TII = QTM.getSubtargetImpl()->getInstrInfo();
76296417Sdim
77239310Sdim  // Loop over all of the basic blocks.
78239310Sdim  for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
79288943Sdim       MBBb != MBBe; ++MBBb) {
80288943Sdim    MachineBasicBlock* MBB = MBBb;
81288943Sdim    // Traverse the basic block.
82288943Sdim    for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
83288943Sdim         ++MII) {
84288943Sdim      MachineInstr *MI = MII;
85288943Sdim      int Opc = MI->getOpcode();
86288943Sdim      if (Opc == Hexagon::STriw_pred) {
87288943Sdim        // STriw_pred [R30], ofst, SrcReg;
88288943Sdim        unsigned FP = MI->getOperand(0).getReg();
89288943Sdim        assert(
90288943Sdim            FP ==
91276479Sdim                QTM.getSubtargetImpl()->getRegisterInfo()->getFrameRegister() &&
92276479Sdim            "Not a Frame Pointer, Nor a Spill Slot");
93276479Sdim        assert(MI->getOperand(1).isImm() && "Not an offset");
94276479Sdim        int Offset = MI->getOperand(1).getImm();
95288943Sdim        int SrcReg = MI->getOperand(2).getReg();
96288943Sdim        assert(Hexagon::PredRegsRegClass.contains(SrcReg) &&
97288943Sdim               "Not a predicate register");
98288943Sdim        if (!TII->isValidOffset(Hexagon::S2_storeri_io, Offset)) {
99288943Sdim          if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
100288943Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(),
101288943Sdim                    TII->get(Hexagon::CONST32_Int_Real),
102288943Sdim                      HEXAGON_RESERVED_REG_1).addImm(Offset);
103261991Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add),
104261991Sdim                    HEXAGON_RESERVED_REG_1)
105239310Sdim              .addReg(FP).addReg(HEXAGON_RESERVED_REG_1);
106280031Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
107280031Sdim                      HEXAGON_RESERVED_REG_2).addReg(SrcReg);
108239310Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(),
109239310Sdim                    TII->get(Hexagon::S2_storeri_io))
110288943Sdim              .addReg(HEXAGON_RESERVED_REG_1)
111288943Sdim              .addImm(0).addReg(HEXAGON_RESERVED_REG_2);
112288943Sdim          } else {
113288943Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
114288943Sdim                      HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
115249423Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
116239310Sdim                      HEXAGON_RESERVED_REG_2).addReg(SrcReg);
117239310Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(),
118239310Sdim                          TII->get(Hexagon::S2_storeri_io))
119288943Sdim              .addReg(HEXAGON_RESERVED_REG_1)
120288943Sdim              .addImm(0)
121288943Sdim              .addReg(HEXAGON_RESERVED_REG_2);
122288943Sdim          }
123288943Sdim        } else {
124249423Sdim          BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
125239310Sdim                    HEXAGON_RESERVED_REG_2).addReg(SrcReg);
126261991Sdim          BuildMI(*MBB, MII, MI->getDebugLoc(),
127239310Sdim                        TII->get(Hexagon::S2_storeri_io)).
128239310Sdim                    addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2);
129239310Sdim        }
130249423Sdim        MII = MBB->erase(MI);
131239310Sdim        --MII;
132239310Sdim      } else if (Opc == Hexagon::LDriw_pred) {
133239310Sdim        // DstReg = LDriw_pred [R30], ofst.
134239310Sdim        int DstReg = MI->getOperand(0).getReg();
135239310Sdim        assert(Hexagon::PredRegsRegClass.contains(DstReg) &&
136276479Sdim               "Not a predicate register");
137276479Sdim        unsigned FP = MI->getOperand(1).getReg();
138280031Sdim        assert(
139276479Sdim            FP ==
140261991Sdim                QTM.getSubtargetImpl()->getRegisterInfo()->getFrameRegister() &&
141276479Sdim            "Not a Frame Pointer, Nor a Spill Slot");
142276479Sdim        assert(MI->getOperand(2).isImm() && "Not an offset");
143276479Sdim        int Offset = MI->getOperand(2).getImm();
144296417Sdim        if (!TII->isValidOffset(Hexagon::L2_loadri_io, Offset)) {
145296417Sdim          if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
146296417Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(),
147296417Sdim                    TII->get(Hexagon::CONST32_Int_Real),
148239310Sdim                      HEXAGON_RESERVED_REG_1).addImm(Offset);
149261991Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add),
150239310Sdim                    HEXAGON_RESERVED_REG_1)
151239310Sdim              .addReg(FP)
152239310Sdim              .addReg(HEXAGON_RESERVED_REG_1);
153239310Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
154239310Sdim                      HEXAGON_RESERVED_REG_2)
155239310Sdim              .addReg(HEXAGON_RESERVED_REG_1)
156288943Sdim              .addImm(0);
157296417Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
158288943Sdim                      DstReg).addReg(HEXAGON_RESERVED_REG_2);
159288943Sdim          } else {
160280031Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
161280031Sdim                      HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
162296417Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
163296417Sdim                      HEXAGON_RESERVED_REG_2)
164296417Sdim              .addReg(HEXAGON_RESERVED_REG_1)
165296417Sdim              .addImm(0);
166296417Sdim            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
167296417Sdim                      DstReg).addReg(HEXAGON_RESERVED_REG_2);
168296417Sdim          }
169251662Sdim        } else {
170261991Sdim          BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
171261991Sdim                    HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset);
172261991Sdim          BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
173261991Sdim                    DstReg).addReg(HEXAGON_RESERVED_REG_2);
174261991Sdim        }
175261991Sdim        MII = MBB->erase(MI);
176261991Sdim        --MII;
177261991Sdim      }
178261991Sdim    }
179296417Sdim  }
180276479Sdim
181276479Sdim  return true;
182251662Sdim}
183296417Sdim
184296417Sdim}
185288943Sdim
186288943Sdim//===----------------------------------------------------------------------===//
187288943Sdim//                         Public Constructor Functions
188288943Sdim//===----------------------------------------------------------------------===//
189288943Sdim
190276479Sdimstatic void initializePassOnce(PassRegistry &Registry) {
191288943Sdim  const char *Name = "Hexagon Expand Predicate Spill Code";
192288943Sdim  PassInfo *PI = new PassInfo(Name, "hexagon-spill-pred",
193288943Sdim                              &HexagonExpandPredSpillCode::ID,
194288943Sdim                              nullptr, false, false);
195296417Sdim  Registry.registerPass(*PI, true);
196296417Sdim}
197276479Sdim
198296417Sdimvoid llvm::initializeHexagonExpandPredSpillCodePass(PassRegistry &Registry) {
199288943Sdim  CALL_ONCE_INITIALIZATION(initializePassOnce)
200288943Sdim}
201288943Sdim
202288943SdimFunctionPass*
203288943Sdimllvm::createHexagonExpandPredSpillCode(const HexagonTargetMachine &TM) {
204288943Sdim  return new HexagonExpandPredSpillCode(TM);
205296417Sdim}
206288943Sdim