MipsConstantIslandPass.cpp revision cb2280e4c7c5a07104306cc73265ff64fa8dd973
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 47using namespace llvm; 48 49STATISTIC(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 56namespace { 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. 115FunctionPass *llvm::createMipsConstantIslandPass(MipsTargetMachine &tm) { 116 return new MipsConstantIslands(tm); 117} 118 119bool 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. 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} 254