blob: 3209c0c55f2063f45630304575cf4d5827c0172f [file] [log] [blame]
Reed Kotler5bf80202013-02-27 04:20:14 +00001//===-- MipsConstantIslandPass.cpp - Emit Pc Relative loads----------------===//
Reed Kotlerbb3094a2013-02-27 03:33:58 +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//
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"
Reed Kotler91ae9822013-10-27 21:57:36 +000032#include "llvm/CodeGen/MachineBasicBlock.h"
Reed Kotlerbb3094a2013-02-27 03:33:58 +000033#include "llvm/CodeGen/MachineFunctionPass.h"
34#include "llvm/CodeGen/MachineInstrBuilder.h"
Reed Kotler91ae9822013-10-27 21:57:36 +000035#include "llvm/CodeGen/MachineRegisterInfo.h"
Reed Kotlerbb3094a2013-02-27 03:33:58 +000036#include "llvm/IR/Function.h"
37#include "llvm/Support/CommandLine.h"
Reed Kotler91ae9822013-10-27 21:57:36 +000038#include "llvm/Support/Debug.h"
39#include "llvm/Support/InstIterator.h"
Reed Kotlerbb3094a2013-02-27 03:33:58 +000040#include "llvm/Support/MathExtras.h"
Reed Kotler91ae9822013-10-27 21:57:36 +000041#include "llvm/Support/raw_ostream.h"
Reed Kotlerbb3094a2013-02-27 03:33:58 +000042#include "llvm/Target/TargetInstrInfo.h"
43#include "llvm/Target/TargetMachine.h"
44#include "llvm/Target/TargetRegisterInfo.h"
Reed Kotler91ae9822013-10-27 21:57:36 +000045#include <algorithm>
Reed Kotlerbb3094a2013-02-27 03:33:58 +000046
47using namespace llvm;
48
Reed Kotler91ae9822013-10-27 21:57:36 +000049STATISTIC(NumCPEs, "Number of constpool entries");
50
51// FIXME: This option should be removed once it has received sufficient testing.
52static cl::opt<bool>
53AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true),
54 cl::desc("Align constant islands in code"));
55
Reed Kotlerbb3094a2013-02-27 03:33:58 +000056namespace {
57 typedef MachineBasicBlock::iterator Iter;
58 typedef MachineBasicBlock::reverse_iterator ReverseIter;
59
60 class MipsConstantIslands : public MachineFunctionPass {
61
Reed Kotler91ae9822013-10-27 21:57:36 +000062 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
Reed Kotlerbb3094a2013-02-27 03:33:58 +000088 public:
89 static char ID;
90 MipsConstantIslands(TargetMachine &tm)
91 : MachineFunctionPass(ID), TM(tm),
Reed Kotlerbb3094a2013-02-27 03:33:58 +000092 IsPIC(TM.getRelocationModel() == Reloc::PIC_),
Reed Kotler91ae9822013-10-27 21:57:36 +000093 ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()),
94 STI(&TM.getSubtarget<MipsSubtarget>()), MF(0), MCP(0){}
Reed Kotlerbb3094a2013-02-27 03:33:58 +000095
96 virtual const char *getPassName() const {
97 return "Mips Constant Islands";
98 }
99
100 bool runOnMachineFunction(MachineFunction &F);
101
Reed Kotler91ae9822013-10-27 21:57:36 +0000102 void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
103
104 void prescanForConstants();
105
Reed Kotlerbb3094a2013-02-27 03:33:58 +0000106 private:
Reed Kotler91ae9822013-10-27 21:57:36 +0000107
Reed Kotlerbb3094a2013-02-27 03:33:58 +0000108 };
109
110 char MipsConstantIslands::ID = 0;
111} // end of anonymous namespace
112
113/// createMipsLongBranchPass - Returns a pass that converts branches to long
114/// branches.
115FunctionPass *llvm::createMipsConstantIslandPass(MipsTargetMachine &tm) {
116 return new MipsConstantIslands(tm);
117}
118
Reed Kotler91ae9822013-10-27 21:57:36 +0000119bool MipsConstantIslands::runOnMachineFunction(MachineFunction &mf) {
Reed Kotler1595f362013-04-09 19:46:01 +0000120 // The intention is for this to be a mips16 only pass for now
121 // FIXME:
Reed Kotler91ae9822013-10-27 21:57:36 +0000122 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;
Reed Kotlerbb3094a2013-02-27 03:33:58 +0000151}
152
Reed Kotler91ae9822013-10-27 21:57:36 +0000153/// doInitialPlacement - Perform the initial placement of the constant pool
154/// entries. To start with, we put them all at the end of the function.
155void
156MipsConstantIslands::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
220void 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}