Revert r194019 to r194021, "Submit the basic port of the rest of ARM constant islands...
[oota-llvm.git] / lib / Target / Mips / MipsConstantIslandPass.cpp
1 //===-- MipsConstantIslandPass.cpp - Emit Pc Relative loads----------------===//
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 //
10 //
11 // This pass is used to make Pc relative loads of constants.
12 // For now, only Mips16 will use this. While it has the same name and
13 // uses many ideas from the LLVM ARM Constant Island Pass, it's not intended
14 // to reuse any of the code from the ARM version.
15 //
16 // Loading constants inline is expensive on Mips16 and it's in general better
17 // to place the constant nearby in code space and then it can be loaded with a
18 // simple 16 bit load instruction.
19 //
20 // The constants can be not just numbers but addresses of functions and labels.
21 // This can be particularly helpful in static relocation mode for embedded
22 // non linux targets.
23 //
24 //
25
26 #define DEBUG_TYPE "mips-constant-islands"
27
28 #include "Mips.h"
29 #include "MCTargetDesc/MipsBaseInfo.h"
30 #include "MipsTargetMachine.h"
31 #include "llvm/ADT/Statistic.h"
32 #include "llvm/CodeGen/MachineBasicBlock.h"
33 #include "llvm/CodeGen/MachineFunctionPass.h"
34 #include "llvm/CodeGen/MachineInstrBuilder.h"
35 #include "llvm/CodeGen/MachineRegisterInfo.h"
36 #include "llvm/IR/Function.h"
37 #include "llvm/Support/CommandLine.h"
38 #include "llvm/Support/Debug.h"
39 #include "llvm/Support/InstIterator.h"
40 #include "llvm/Support/MathExtras.h"
41 #include "llvm/Support/raw_ostream.h"
42 #include "llvm/Target/TargetInstrInfo.h"
43 #include "llvm/Target/TargetMachine.h"
44 #include "llvm/Target/TargetRegisterInfo.h"
45 #include <algorithm>
46
47 using namespace llvm;
48
49 STATISTIC(NumCPEs,       "Number of constpool entries");
50
51 // FIXME: This option should be removed once it has received sufficient testing.
52 static cl::opt<bool>
53 AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true),
54           cl::desc("Align constant islands in code"));
55
56 namespace {
57   typedef MachineBasicBlock::iterator Iter;
58   typedef MachineBasicBlock::reverse_iterator ReverseIter;
59
60   class MipsConstantIslands : public MachineFunctionPass {
61
62   const TargetMachine &TM;
63   bool IsPIC;
64   unsigned ABI;
65   const MipsSubtarget *STI;
66   const MipsInstrInfo *TII;
67   MachineFunction *MF;
68   MachineConstantPool *MCP;
69
70   /// CPEntry - One per constant pool entry, keeping the machine instruction
71   /// pointer, the constpool index, and the number of CPUser's which
72   /// reference this entry.
73   struct CPEntry {
74     MachineInstr *CPEMI;
75     unsigned CPI;
76     unsigned RefCount;
77     CPEntry(MachineInstr *cpemi, unsigned cpi, unsigned rc = 0)
78       : CPEMI(cpemi), CPI(cpi), RefCount(rc) {}
79   };
80
81   /// CPEntries - Keep track of all of the constant pool entry machine
82   /// instructions. For each original constpool index (i.e. those that
83   /// existed upon entry to this pass), it keeps a vector of entries.
84   /// Original elements are cloned as we go along; the clones are
85   /// put in the vector of the original element, but have distinct CPIs.
86   std::vector<std::vector<CPEntry> > CPEntries;
87
88   public:
89     static char ID;
90     MipsConstantIslands(TargetMachine &tm)
91       : MachineFunctionPass(ID), TM(tm),
92         IsPIC(TM.getRelocationModel() == Reloc::PIC_),
93         ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()),
94         STI(&TM.getSubtarget<MipsSubtarget>()), MF(0), MCP(0){}
95
96     virtual const char *getPassName() const {
97       return "Mips Constant Islands";
98     }
99
100     bool runOnMachineFunction(MachineFunction &F);
101
102     void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
103
104     void prescanForConstants();
105
106   private:
107
108   };
109
110   char MipsConstantIslands::ID = 0;
111 } // end of anonymous namespace
112
113 /// createMipsLongBranchPass - Returns a pass that converts branches to long
114 /// branches.
115 FunctionPass *llvm::createMipsConstantIslandPass(MipsTargetMachine &tm) {
116   return new MipsConstantIslands(tm);
117 }
118
119 bool MipsConstantIslands::runOnMachineFunction(MachineFunction &mf) {
120   // The intention is for this to be a mips16 only pass for now
121   // FIXME:
122   MF = &mf;
123   MCP = mf.getConstantPool();
124   DEBUG(dbgs() << "constant island machine function " << "\n");
125   if (!TM.getSubtarget<MipsSubtarget>().inMips16Mode() ||
126       !MipsSubtarget::useConstantIslands()) {
127     return false;
128   }
129   TII = (const MipsInstrInfo*)MF->getTarget().getInstrInfo();
130   DEBUG(dbgs() << "constant island processing " << "\n");
131   //
132   // will need to make predermination if there is any constants we need to
133   // put in constant islands. TBD.
134   //
135   prescanForConstants();
136
137   // This pass invalidates liveness information when it splits basic blocks.
138   MF->getRegInfo().invalidateLiveness();
139
140   // Renumber all of the machine basic blocks in the function, guaranteeing that
141   // the numbers agree with the position of the block in the function.
142   MF->RenumberBlocks();
143
144   // Perform the initial placement of the constant pool entries.  To start with,
145   // we put them all at the end of the function.
146   std::vector<MachineInstr*> CPEMIs;
147   if (!MCP->isEmpty())
148     doInitialPlacement(CPEMIs);
149
150   return true;
151 }
152
153 /// doInitialPlacement - Perform the initial placement of the constant pool
154 /// entries.  To start with, we put them all at the end of the function.
155 void
156 MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
157   // Create the basic block to hold the CPE's.
158   MachineBasicBlock *BB = MF->CreateMachineBasicBlock();
159   MF->push_back(BB);
160
161
162   // MachineConstantPool measures alignment in bytes. We measure in log2(bytes).
163   unsigned MaxAlign = Log2_32(MCP->getConstantPoolAlignment());
164
165   // Mark the basic block as required by the const-pool.
166   // If AlignConstantIslands isn't set, use 4-byte alignment for everything.
167   BB->setAlignment(AlignConstantIslands ? MaxAlign : 2);
168
169   // The function needs to be as aligned as the basic blocks. The linker may
170   // move functions around based on their alignment.
171   MF->ensureAlignment(BB->getAlignment());
172
173   // Order the entries in BB by descending alignment.  That ensures correct
174   // alignment of all entries as long as BB is sufficiently aligned.  Keep
175   // track of the insertion point for each alignment.  We are going to bucket
176   // sort the entries as they are created.
177   SmallVector<MachineBasicBlock::iterator, 8> InsPoint(MaxAlign + 1, BB->end());
178
179   // Add all of the constants from the constant pool to the end block, use an
180   // identity mapping of CPI's to CPE's.
181   const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
182
183   const DataLayout &TD = *MF->getTarget().getDataLayout();
184   for (unsigned i = 0, e = CPs.size(); i != e; ++i) {
185     unsigned Size = TD.getTypeAllocSize(CPs[i].getType());
186     assert(Size >= 4 && "Too small constant pool entry");
187     unsigned Align = CPs[i].getAlignment();
188     assert(isPowerOf2_32(Align) && "Invalid alignment");
189     // Verify that all constant pool entries are a multiple of their alignment.
190     // If not, we would have to pad them out so that instructions stay aligned.
191     assert((Size % Align) == 0 && "CP Entry not multiple of 4 bytes!");
192
193     // Insert CONSTPOOL_ENTRY before entries with a smaller alignment.
194     unsigned LogAlign = Log2_32(Align);
195     MachineBasicBlock::iterator InsAt = InsPoint[LogAlign];
196
197     MachineInstr *CPEMI =
198       BuildMI(*BB, InsAt, DebugLoc(), TII->get(Mips::CONSTPOOL_ENTRY))
199         .addImm(i).addConstantPoolIndex(i).addImm(Size);
200
201     CPEMIs.push_back(CPEMI);
202
203     // Ensure that future entries with higher alignment get inserted before
204     // CPEMI. This is bucket sort with iterators.
205     for (unsigned a = LogAlign + 1; a <= MaxAlign; ++a)
206       if (InsPoint[a] == InsAt)
207         InsPoint[a] = CPEMI;
208     // Add a new CPEntry, but no corresponding CPUser yet.
209     std::vector<CPEntry> CPEs;
210     CPEs.push_back(CPEntry(CPEMI, i));
211     CPEntries.push_back(CPEs);
212     ++NumCPEs;
213     DEBUG(dbgs() << "Moved CPI#" << i << " to end of function, size = "
214                  << Size << ", align = " << Align <<'\n');
215   }
216   DEBUG(BB->dump());
217 }
218
219
220 void MipsConstantIslands::prescanForConstants() {
221   unsigned int J;
222   for (MachineFunction::iterator B =
223          MF->begin(), E = MF->end(); B != E; ++B) {
224     for (MachineBasicBlock::instr_iterator I =
225         B->instr_begin(), EB = B->instr_end(); I != EB; ++I) {
226       switch(I->getDesc().getOpcode()) {
227         case Mips::LwConstant32: {
228           DEBUG(dbgs() << "constant island constant " << *I << "\n");
229           J = I->getNumOperands();
230           DEBUG(dbgs() << "num operands " << J  << "\n");
231           MachineOperand& Literal = I->getOperand(1);
232           if (Literal.isImm()) {
233             int64_t V = Literal.getImm();
234             DEBUG(dbgs() << "literal " << V  << "\n");
235             Type *Int32Ty =
236               Type::getInt32Ty(MF->getFunction()->getContext());
237             const Constant *C = ConstantInt::get(Int32Ty, V);
238             unsigned index = MCP->getConstantPoolIndex(C, 4);
239             I->getOperand(2).ChangeToImmediate(index);
240             DEBUG(dbgs() << "constant island constant " << *I << "\n");
241             I->setDesc(TII->get(Mips::LwRxPcTcpX16));
242             I->RemoveOperand(1);
243             I->RemoveOperand(1);
244             I->addOperand(MachineOperand::CreateCPI(index, 0));
245           }
246           break;
247         }
248         default:
249           break;
250       }
251     }
252   }
253 }