LLVM API Documentation
00001 //===-- ARMConstantIslandPass.cpp - ARM constant islands --------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains a pass that splits the constant pool up into 'islands' 00011 // which are scattered through-out the function. This is required due to the 00012 // limited pc-relative displacements that ARM has. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #define DEBUG_TYPE "arm-cp-islands" 00017 #include "ARM.h" 00018 #include "ARMMachineFunctionInfo.h" 00019 #include "ARMInstrInfo.h" 00020 #include "llvm/CodeGen/MachineConstantPool.h" 00021 #include "llvm/CodeGen/MachineFunctionPass.h" 00022 #include "llvm/CodeGen/MachineInstrBuilder.h" 00023 #include "llvm/Target/TargetData.h" 00024 #include "llvm/Target/TargetMachine.h" 00025 #include "llvm/Support/Compiler.h" 00026 #include "llvm/Support/Debug.h" 00027 #include "llvm/ADT/SmallVector.h" 00028 #include "llvm/ADT/STLExtras.h" 00029 #include "llvm/ADT/Statistic.h" 00030 using namespace llvm; 00031 00032 STATISTIC(NumCPEs, "Number of constpool entries"); 00033 STATISTIC(NumSplit, "Number of uncond branches inserted"); 00034 STATISTIC(NumCBrFixed, "Number of cond branches fixed"); 00035 STATISTIC(NumUBrFixed, "Number of uncond branches fixed"); 00036 00037 namespace { 00038 /// ARMConstantIslands - Due to limited PC-relative displacements, ARM 00039 /// requires constant pool entries to be scattered among the instructions 00040 /// inside a function. To do this, it completely ignores the normal LLVM 00041 /// constant pool; instead, it places constants wherever it feels like with 00042 /// special instructions. 00043 /// 00044 /// The terminology used in this pass includes: 00045 /// Islands - Clumps of constants placed in the function. 00046 /// Water - Potential places where an island could be formed. 00047 /// CPE - A constant pool entry that has been placed somewhere, which 00048 /// tracks a list of users. 00049 class VISIBILITY_HIDDEN ARMConstantIslands : public MachineFunctionPass { 00050 /// BBSizes - The size of each MachineBasicBlock in bytes of code, indexed 00051 /// by MBB Number. The two-byte pads required for Thumb alignment are 00052 /// counted as part of the following block (i.e., the offset and size for 00053 /// a padded block will both be ==2 mod 4). 00054 std::vector<unsigned> BBSizes; 00055 00056 /// BBOffsets - the offset of each MBB in bytes, starting from 0. 00057 /// The two-byte pads required for Thumb alignment are counted as part of 00058 /// the following block. 00059 std::vector<unsigned> BBOffsets; 00060 00061 /// WaterList - A sorted list of basic blocks where islands could be placed 00062 /// (i.e. blocks that don't fall through to the following block, due 00063 /// to a return, unreachable, or unconditional branch). 00064 std::vector<MachineBasicBlock*> WaterList; 00065 00066 /// CPUser - One user of a constant pool, keeping the machine instruction 00067 /// pointer, the constant pool being referenced, and the max displacement 00068 /// allowed from the instruction to the CP. 00069 struct CPUser { 00070 MachineInstr *MI; 00071 MachineInstr *CPEMI; 00072 unsigned MaxDisp; 00073 CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp) 00074 : MI(mi), CPEMI(cpemi), MaxDisp(maxdisp) {} 00075 }; 00076 00077 /// CPUsers - Keep track of all of the machine instructions that use various 00078 /// constant pools and their max displacement. 00079 std::vector<CPUser> CPUsers; 00080 00081 /// CPEntry - One per constant pool entry, keeping the machine instruction 00082 /// pointer, the constpool index, and the number of CPUser's which 00083 /// reference this entry. 00084 struct CPEntry { 00085 MachineInstr *CPEMI; 00086 unsigned CPI; 00087 unsigned RefCount; 00088 CPEntry(MachineInstr *cpemi, unsigned cpi, unsigned rc = 0) 00089 : CPEMI(cpemi), CPI(cpi), RefCount(rc) {} 00090 }; 00091 00092 /// CPEntries - Keep track of all of the constant pool entry machine 00093 /// instructions. For each original constpool index (i.e. those that 00094 /// existed upon entry to this pass), it keeps a vector of entries. 00095 /// Original elements are cloned as we go along; the clones are 00096 /// put in the vector of the original element, but have distinct CPIs. 00097 std::vector<std::vector<CPEntry> > CPEntries; 00098 00099 /// ImmBranch - One per immediate branch, keeping the machine instruction 00100 /// pointer, conditional or unconditional, the max displacement, 00101 /// and (if isCond is true) the corresponding unconditional branch 00102 /// opcode. 00103 struct ImmBranch { 00104 MachineInstr *MI; 00105 unsigned MaxDisp : 31; 00106 bool isCond : 1; 00107 int UncondBr; 00108 ImmBranch(MachineInstr *mi, unsigned maxdisp, bool cond, int ubr) 00109 : MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {} 00110 }; 00111 00112 /// ImmBranches - Keep track of all the immediate branch instructions. 00113 /// 00114 std::vector<ImmBranch> ImmBranches; 00115 00116 /// PushPopMIs - Keep track of all the Thumb push / pop instructions. 00117 /// 00118 SmallVector<MachineInstr*, 4> PushPopMIs; 00119 00120 /// HasFarJump - True if any far jump instruction has been emitted during 00121 /// the branch fix up pass. 00122 bool HasFarJump; 00123 00124 const TargetInstrInfo *TII; 00125 ARMFunctionInfo *AFI; 00126 bool isThumb; 00127 public: 00128 static char ID; 00129 ARMConstantIslands() : MachineFunctionPass(&ID) {} 00130 00131 virtual bool runOnMachineFunction(MachineFunction &Fn); 00132 00133 virtual const char *getPassName() const { 00134 return "ARM constant island placement and branch shortening pass"; 00135 } 00136 00137 private: 00138 void DoInitialPlacement(MachineFunction &Fn, 00139 std::vector<MachineInstr*> &CPEMIs); 00140 CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI); 00141 void InitialFunctionScan(MachineFunction &Fn, 00142 const std::vector<MachineInstr*> &CPEMIs); 00143 MachineBasicBlock *SplitBlockBeforeInstr(MachineInstr *MI); 00144 void UpdateForInsertedWaterBlock(MachineBasicBlock *NewBB); 00145 void AdjustBBOffsetsAfter(MachineBasicBlock *BB, int delta); 00146 bool DecrementOldEntry(unsigned CPI, MachineInstr* CPEMI); 00147 int LookForExistingCPEntry(CPUser& U, unsigned UserOffset); 00148 bool LookForWater(CPUser&U, unsigned UserOffset, 00149 MachineBasicBlock** NewMBB); 00150 MachineBasicBlock* AcceptWater(MachineBasicBlock *WaterBB, 00151 std::vector<MachineBasicBlock*>::iterator IP); 00152 void CreateNewWater(unsigned CPUserIndex, unsigned UserOffset, 00153 MachineBasicBlock** NewMBB); 00154 bool HandleConstantPoolUser(MachineFunction &Fn, unsigned CPUserIndex); 00155 void RemoveDeadCPEMI(MachineInstr *CPEMI); 00156 bool RemoveUnusedCPEntries(); 00157 bool CPEIsInRange(MachineInstr *MI, unsigned UserOffset, 00158 MachineInstr *CPEMI, unsigned Disp, 00159 bool DoDump); 00160 bool WaterIsInRange(unsigned UserOffset, MachineBasicBlock *Water, 00161 CPUser &U); 00162 bool OffsetIsInRange(unsigned UserOffset, unsigned TrialOffset, 00163 unsigned Disp, bool NegativeOK); 00164 bool BBIsInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp); 00165 bool FixUpImmediateBr(MachineFunction &Fn, ImmBranch &Br); 00166 bool FixUpConditionalBr(MachineFunction &Fn, ImmBranch &Br); 00167 bool FixUpUnconditionalBr(MachineFunction &Fn, ImmBranch &Br); 00168 bool UndoLRSpillRestore(); 00169 00170 unsigned GetOffsetOf(MachineInstr *MI) const; 00171 void dumpBBs(); 00172 void verify(MachineFunction &Fn); 00173 }; 00174 char ARMConstantIslands::ID = 0; 00175 } 00176 00177 /// verify - check BBOffsets, BBSizes, alignment of islands 00178 void ARMConstantIslands::verify(MachineFunction &Fn) { 00179 assert(BBOffsets.size() == BBSizes.size()); 00180 for (unsigned i = 1, e = BBOffsets.size(); i != e; ++i) 00181 assert(BBOffsets[i-1]+BBSizes[i-1] == BBOffsets[i]); 00182 if (isThumb) { 00183 for (MachineFunction::iterator MBBI = Fn.begin(), E = Fn.end(); 00184 MBBI != E; ++MBBI) { 00185 MachineBasicBlock *MBB = MBBI; 00186 if (!MBB->empty() && 00187 MBB->begin()->getOpcode() == ARM::CONSTPOOL_ENTRY) 00188 assert((BBOffsets[MBB->getNumber()]%4 == 0 && 00189 BBSizes[MBB->getNumber()]%4 == 0) || 00190 (BBOffsets[MBB->getNumber()]%4 != 0 && 00191 BBSizes[MBB->getNumber()]%4 != 0)); 00192 } 00193 } 00194 } 00195 00196 /// print block size and offset information - debugging 00197 void ARMConstantIslands::dumpBBs() { 00198 for (unsigned J = 0, E = BBOffsets.size(); J !=E; ++J) { 00199 DOUT << "block " << J << " offset " << BBOffsets[J] << 00200 " size " << BBSizes[J] << "\n"; 00201 } 00202 } 00203 00204 /// createARMConstantIslandPass - returns an instance of the constpool 00205 /// island pass. 00206 FunctionPass *llvm::createARMConstantIslandPass() { 00207 return new ARMConstantIslands(); 00208 } 00209 00210 bool ARMConstantIslands::runOnMachineFunction(MachineFunction &Fn) { 00211 MachineConstantPool &MCP = *Fn.getConstantPool(); 00212 00213 TII = Fn.getTarget().getInstrInfo(); 00214 AFI = Fn.getInfo<ARMFunctionInfo>(); 00215 isThumb = AFI->isThumbFunction(); 00216 00217 HasFarJump = false; 00218 00219 // Renumber all of the machine basic blocks in the function, guaranteeing that 00220 // the numbers agree with the position of the block in the function. 00221 Fn.RenumberBlocks(); 00222 00223 /// Thumb functions containing constant pools get 2-byte alignment. This is so 00224 /// we can keep exact track of where the alignment padding goes. Set default. 00225 AFI->setAlign(isThumb ? 1U : 2U); 00226 00227 // Perform the initial placement of the constant pool entries. To start with, 00228 // we put them all at the end of the function. 00229 std::vector<MachineInstr*> CPEMIs; 00230 if (!MCP.isEmpty()) { 00231 DoInitialPlacement(Fn, CPEMIs); 00232 if (isThumb) 00233 AFI->setAlign(2U); 00234 } 00235 00236 /// The next UID to take is the first unused one. 00237 AFI->initConstPoolEntryUId(CPEMIs.size()); 00238 00239 // Do the initial scan of the function, building up information about the 00240 // sizes of each block, the location of all the water, and finding all of the 00241 // constant pool users. 00242 InitialFunctionScan(Fn, CPEMIs); 00243 CPEMIs.clear(); 00244 00245 /// Remove dead constant pool entries. 00246 RemoveUnusedCPEntries(); 00247 00248 // Iteratively place constant pool entries and fix up branches until there 00249 // is no change. 00250 bool MadeChange = false; 00251 while (true) { 00252 bool Change = false; 00253 for (unsigned i = 0, e = CPUsers.size(); i != e; ++i) 00254 Change |= HandleConstantPoolUser(Fn, i); 00255 DEBUG(dumpBBs()); 00256 for (unsigned i = 0, e = ImmBranches.size(); i != e; ++i) 00257 Change |= FixUpImmediateBr(Fn, ImmBranches[i]); 00258 DEBUG(dumpBBs()); 00259 if (!Change) 00260 break; 00261 MadeChange = true; 00262 } 00263 00264 // After a while, this might be made debug-only, but it is not expensive. 00265 verify(Fn); 00266 00267 // If LR has been forced spilled and no far jumps (i.e. BL) has been issued. 00268 // Undo the spill / restore of LR if possible. 00269 if (!HasFarJump && AFI->isLRSpilledForFarJump() && isThumb) 00270 MadeChange |= UndoLRSpillRestore(); 00271 00272 BBSizes.clear(); 00273 BBOffsets.clear(); 00274 WaterList.clear(); 00275 CPUsers.clear(); 00276 CPEntries.clear(); 00277 ImmBranches.clear(); 00278 PushPopMIs.clear(); 00279 00280 return MadeChange; 00281 } 00282 00283 /// DoInitialPlacement - Perform the initial placement of the constant pool 00284 /// entries. To start with, we put them all at the end of the function. 00285 void ARMConstantIslands::DoInitialPlacement(MachineFunction &Fn, 00286 std::vector<MachineInstr*> &CPEMIs){ 00287 // Create the basic block to hold the CPE's. 00288 MachineBasicBlock *BB = Fn.CreateMachineBasicBlock(); 00289 Fn.push_back(BB); 00290 00291 // Add all of the constants from the constant pool to the end block, use an 00292 // identity mapping of CPI's to CPE's. 00293 const std::vector<MachineConstantPoolEntry> &CPs = 00294 Fn.getConstantPool()->getConstants(); 00295 00296 const TargetData &TD = *Fn.getTarget().getTargetData(); 00297 for (unsigned i = 0, e = CPs.size(); i != e; ++i) { 00298 unsigned Size = TD.getTypePaddedSize(CPs[i].getType()); 00299 // Verify that all constant pool entries are a multiple of 4 bytes. If not, 00300 // we would have to pad them out or something so that instructions stay 00301 // aligned. 00302 assert((Size & 3) == 0 && "CP Entry not multiple of 4 bytes!"); 00303 MachineInstr *CPEMI = 00304 BuildMI(BB, TII->get(ARM::CONSTPOOL_ENTRY)) 00305 .addImm(i).addConstantPoolIndex(i).addImm(Size); 00306 CPEMIs.push_back(CPEMI); 00307 00308 // Add a new CPEntry, but no corresponding CPUser yet. 00309 std::vector<CPEntry> CPEs; 00310 CPEs.push_back(CPEntry(CPEMI, i)); 00311 CPEntries.push_back(CPEs); 00312 NumCPEs++; 00313 DOUT << "Moved CPI#" << i << " to end of function as #" << i << "\n"; 00314 } 00315 } 00316 00317 /// BBHasFallthrough - Return true if the specified basic block can fallthrough 00318 /// into the block immediately after it. 00319 static bool BBHasFallthrough(MachineBasicBlock *MBB) { 00320 // Get the next machine basic block in the function. 00321 MachineFunction::iterator MBBI = MBB; 00322 if (next(MBBI) == MBB->getParent()->end()) // Can't fall off end of function. 00323 return false; 00324 00325 MachineBasicBlock *NextBB = next(MBBI); 00326 for (MachineBasicBlock::succ_iterator I = MBB->succ_begin(), 00327 E = MBB->succ_end(); I != E; ++I) 00328 if (*I == NextBB) 00329 return true; 00330 00331 return false; 00332 } 00333 00334 /// findConstPoolEntry - Given the constpool index and CONSTPOOL_ENTRY MI, 00335 /// look up the corresponding CPEntry. 00336 ARMConstantIslands::CPEntry 00337 *ARMConstantIslands::findConstPoolEntry(unsigned CPI, 00338 const MachineInstr *CPEMI) { 00339 std::vector<CPEntry> &CPEs = CPEntries[CPI]; 00340 // Number of entries per constpool index should be small, just do a 00341 // linear search. 00342 for (unsigned i = 0, e = CPEs.size(); i != e; ++i) { 00343 if (CPEs[i].CPEMI == CPEMI) 00344 return &CPEs[i]; 00345 } 00346 return NULL; 00347 } 00348 00349 /// InitialFunctionScan - Do the initial scan of the function, building up 00350 /// information about the sizes of each block, the location of all the water, 00351 /// and finding all of the constant pool users. 00352 void ARMConstantIslands::InitialFunctionScan(MachineFunction &Fn, 00353 const std::vector<MachineInstr*> &CPEMIs) { 00354 unsigned Offset = 0; 00355 for (MachineFunction::iterator MBBI = Fn.begin(), E = Fn.end(); 00356 MBBI != E; ++MBBI) { 00357 MachineBasicBlock &MBB = *MBBI; 00358 00359 // If this block doesn't fall through into the next MBB, then this is 00360 // 'water' that a constant pool island could be placed. 00361 if (!BBHasFallthrough(&MBB)) 00362 WaterList.push_back(&MBB); 00363 00364 unsigned MBBSize = 0; 00365 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); 00366 I != E; ++I) { 00367 // Add instruction size to MBBSize. 00368 MBBSize += TII->GetInstSizeInBytes(I); 00369 00370 int Opc = I->getOpcode(); 00371 if (I->getDesc().isBranch()) { 00372 bool isCond = false; 00373 unsigned Bits = 0; 00374 unsigned Scale = 1; 00375 int UOpc = Opc; 00376 switch (Opc) { 00377 case ARM::tBR_JTr: 00378 // A Thumb table jump may involve padding; for the offsets to 00379 // be right, functions containing these must be 4-byte aligned. 00380 AFI->setAlign(2U); 00381 if ((Offset+MBBSize)%4 != 0) 00382 MBBSize += 2; // padding 00383 continue; // Does not get an entry in ImmBranches 00384 default: 00385 continue; // Ignore other JT branches 00386 case ARM::Bcc: 00387 isCond = true; 00388 UOpc = ARM::B; 00389 // Fallthrough 00390 case ARM::B: 00391 Bits = 24; 00392 Scale = 4; 00393 break; 00394 case ARM::tBcc: 00395 isCond = true; 00396 UOpc = ARM::tB; 00397 Bits = 8; 00398 Scale = 2; 00399 break; 00400 case ARM::tB: 00401 Bits = 11; 00402 Scale = 2; 00403 break; 00404 } 00405 00406 // Record this immediate branch. 00407 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale; 00408 ImmBranches.push_back(ImmBranch(I, MaxOffs, isCond, UOpc)); 00409 } 00410 00411 if (Opc == ARM::tPUSH || Opc == ARM::tPOP_RET) 00412 PushPopMIs.push_back(I); 00413 00414 // Scan the instructions for constant pool operands. 00415 for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) 00416 if (I->getOperand(op).isCPI()) { 00417 // We found one. The addressing mode tells us the max displacement 00418 // from the PC that this instruction permits. 00419 00420 // Basic size info comes from the TSFlags field. 00421 unsigned Bits = 0; 00422 unsigned Scale = 1; 00423 unsigned TSFlags = I->getDesc().TSFlags; 00424 switch (TSFlags & ARMII::AddrModeMask) { 00425 default: 00426 // Constant pool entries can reach anything. 00427 if (I->getOpcode() == ARM::CONSTPOOL_ENTRY) 00428 continue; 00429 if (I->getOpcode() == ARM::tLEApcrel) { 00430 Bits = 8; // Taking the address of a CP entry. 00431 break; 00432 } 00433 assert(0 && "Unknown addressing mode for CP reference!"); 00434 case ARMII::AddrMode1: // AM1: 8 bits << 2 00435 Bits = 8; 00436 Scale = 4; // Taking the address of a CP entry. 00437 break; 00438 case ARMII::AddrMode2: 00439 Bits = 12; // +-offset_12 00440 break; 00441 case ARMII::AddrMode3: 00442 Bits = 8; // +-offset_8 00443 break; 00444 // addrmode4 has no immediate offset. 00445 case ARMII::AddrMode5: 00446 Bits = 8; 00447 Scale = 4; // +-(offset_8*4) 00448 break; 00449 case ARMII::AddrModeT1: 00450 Bits = 5; // +offset_5 00451 break; 00452 case ARMII::AddrModeT2: 00453 Bits = 5; 00454 Scale = 2; // +(offset_5*2) 00455 break; 00456 case ARMII::AddrModeT4: 00457 Bits = 5; 00458 Scale = 4; // +(offset_5*4) 00459 break; 00460 case ARMII::AddrModeTs: 00461 Bits = 8; 00462 Scale = 4; // +(offset_8*4) 00463 break; 00464 } 00465 00466 // Remember that this is a user of a CP entry. 00467 unsigned CPI = I->getOperand(op).getIndex(); 00468 MachineInstr *CPEMI = CPEMIs[CPI]; 00469 unsigned MaxOffs = ((1 << Bits)-1) * Scale; 00470 CPUsers.push_back(CPUser(I, CPEMI, MaxOffs)); 00471 00472 // Increment corresponding CPEntry reference count. 00473 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI); 00474 assert(CPE && "Cannot find a corresponding CPEntry!"); 00475 CPE->RefCount++; 00476 00477 // Instructions can only use one CP entry, don't bother scanning the 00478 // rest of the operands. 00479 break; 00480 } 00481 } 00482 00483 // In thumb mode, if this block is a constpool island, we may need padding 00484 // so it's aligned on 4 byte boundary. 00485 if (isThumb && 00486 !MBB.empty() && 00487 MBB.begin()->getOpcode() == ARM::CONSTPOOL_ENTRY && 00488 (Offset%4) != 0) 00489 MBBSize += 2; 00490 00491 BBSizes.push_back(MBBSize); 00492 BBOffsets.push_back(Offset); 00493 Offset += MBBSize; 00494 } 00495 } 00496 00497 /// GetOffsetOf - Return the current offset of the specified machine instruction 00498 /// from the start of the function. This offset changes as stuff is moved 00499 /// around inside the function. 00500 unsigned ARMConstantIslands::GetOffsetOf(MachineInstr *MI) const { 00501 MachineBasicBlock *MBB = MI->getParent(); 00502 00503 // The offset is composed of two things: the sum of the sizes of all MBB's 00504 // before this instruction's block, and the offset from the start of the block 00505 // it is in. 00506 unsigned Offset = BBOffsets[MBB->getNumber()]; 00507 00508 // If we're looking for a CONSTPOOL_ENTRY in Thumb, see if this block has 00509 // alignment padding, and compensate if so. 00510 if (isThumb && 00511 MI->getOpcode() == ARM::CONSTPOOL_ENTRY && 00512 Offset%4 != 0) 00513 Offset += 2; 00514 00515 // Sum instructions before MI in MBB. 00516 for (MachineBasicBlock::iterator I = MBB->begin(); ; ++I) { 00517 assert(I != MBB->end() && "Didn't find MI in its own basic block?"); 00518 if (&*I == MI) return Offset; 00519 Offset += TII->GetInstSizeInBytes(I); 00520 } 00521 } 00522 00523 /// CompareMBBNumbers - Little predicate function to sort the WaterList by MBB 00524 /// ID. 00525 static bool CompareMBBNumbers(const MachineBasicBlock *LHS, 00526 const MachineBasicBlock *RHS) { 00527 return LHS->getNumber() < RHS->getNumber(); 00528 } 00529 00530 /// UpdateForInsertedWaterBlock - When a block is newly inserted into the 00531 /// machine function, it upsets all of the block numbers. Renumber the blocks 00532 /// and update the arrays that parallel this numbering. 00533 void ARMConstantIslands::UpdateForInsertedWaterBlock(MachineBasicBlock *NewBB) { 00534 // Renumber the MBB's to keep them consequtive. 00535 NewBB->getParent()->RenumberBlocks(NewBB); 00536 00537 // Insert a size into BBSizes to align it properly with the (newly 00538 // renumbered) block numbers. 00539 BBSizes.insert(BBSizes.begin()+NewBB->getNumber(), 0); 00540 00541 // Likewise for BBOffsets. 00542 BBOffsets.insert(BBOffsets.begin()+NewBB->getNumber(), 0); 00543 00544 // Next, update WaterList. Specifically, we need to add NewMBB as having 00545 // available water after it. 00546 std::vector<MachineBasicBlock*>::iterator IP = 00547 std::lower_bound(WaterList.begin(), WaterList.end(), NewBB, 00548 CompareMBBNumbers); 00549 WaterList.insert(IP, NewBB); 00550 } 00551 00552 00553 /// Split the basic block containing MI into two blocks, which are joined by 00554 /// an unconditional branch. Update datastructures and renumber blocks to 00555 /// account for this change and returns the newly created block. 00556 MachineBasicBlock *ARMConstantIslands::SplitBlockBeforeInstr(MachineInstr *MI) { 00557 MachineBasicBlock *OrigBB = MI->getParent(); 00558 MachineFunction &MF = *OrigBB->getParent(); 00559 00560 // Create a new MBB for the code after the OrigBB. 00561 MachineBasicBlock *NewBB = MF.CreateMachineBasicBlock(OrigBB->getBasicBlock()); 00562 MachineFunction::iterator MBBI = OrigBB; ++MBBI; 00563 MF.insert(MBBI, NewBB); 00564 00565 // Splice the instructions starting with MI over to NewBB. 00566 NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end()); 00567 00568 // Add an unconditional branch from OrigBB to NewBB. 00569 // Note the new unconditional branch is not being recorded. 00570 BuildMI(OrigBB, TII->get(isThumb ? ARM::tB : ARM::B)).addMBB(NewBB); 00571 NumSplit++; 00572 00573 // Update the CFG. All succs of OrigBB are now succs of NewBB. 00574 while (!OrigBB->succ_empty()) { 00575 MachineBasicBlock *Succ = *OrigBB->succ_begin(); 00576 OrigBB->removeSuccessor(Succ); 00577 NewBB->addSuccessor(Succ); 00578 00579 // This pass should be run after register allocation, so there should be no 00580 // PHI nodes to update. 00581 assert((Succ->empty() || Succ->begin()->getOpcode() != TargetInstrInfo::PHI) 00582 && "PHI nodes should be eliminated by now!"); 00583 } 00584 00585 // OrigBB branches to NewBB. 00586 OrigBB->addSuccessor(NewBB); 00587 00588 // Update internal data structures to account for the newly inserted MBB. 00589 // This is almost the same as UpdateForInsertedWaterBlock, except that 00590 // the Water goes after OrigBB, not NewBB. 00591 MF.RenumberBlocks(NewBB); 00592 00593 // Insert a size into BBSizes to align it properly with the (newly 00594 // renumbered) block numbers. 00595 BBSizes.insert(BBSizes.begin()+NewBB->getNumber(), 0); 00596 00597 // Likewise for BBOffsets. 00598 BBOffsets.insert(BBOffsets.begin()+NewBB->getNumber(), 0); 00599 00600 // Next, update WaterList. Specifically, we need to add OrigMBB as having 00601 // available water after it (but not if it's already there, which happens 00602 // when splitting before a conditional branch that is followed by an 00603 // unconditional branch - in that case we want to insert NewBB). 00604 std::vector<MachineBasicBlock*>::iterator IP = 00605 std::lower_bound(WaterList.begin(), WaterList.end(), OrigBB, 00606 CompareMBBNumbers); 00607 MachineBasicBlock* WaterBB = *IP; 00608 if (WaterBB == OrigBB) 00609 WaterList.insert(next(IP), NewBB); 00610 else 00611 WaterList.insert(IP, OrigBB); 00612 00613 // Figure out how large the first NewMBB is. (It cannot 00614 // contain a constpool_entry or tablejump.) 00615 unsigned NewBBSize = 0; 00616 for (MachineBasicBlock::iterator I = NewBB->begin(), E = NewBB->end(); 00617 I != E; ++I) 00618 NewBBSize += TII->GetInstSizeInBytes(I); 00619 00620 unsigned OrigBBI = OrigBB->getNumber(); 00621 unsigned NewBBI = NewBB->getNumber(); 00622 // Set the size of NewBB in BBSizes. 00623 BBSizes[NewBBI] = NewBBSize; 00624 00625 // We removed instructions from UserMBB, subtract that off from its size. 00626 // Add 2 or 4 to the block to count the unconditional branch we added to it. 00627 unsigned delta = isThumb ? 2 : 4; 00628 BBSizes[OrigBBI] -= NewBBSize - delta; 00629 00630 // ...and adjust BBOffsets for NewBB accordingly. 00631 BBOffsets[NewBBI] = BBOffsets[OrigBBI] + BBSizes[OrigBBI]; 00632 00633 // All BBOffsets following these blocks must be modified. 00634 AdjustBBOffsetsAfter(NewBB, delta); 00635 00636 return NewBB; 00637 } 00638 00639 /// OffsetIsInRange - Checks whether UserOffset (the location of a constant pool 00640 /// reference) is within MaxDisp of TrialOffset (a proposed location of a 00641 /// constant pool entry). 00642 bool ARMConstantIslands::OffsetIsInRange(unsigned UserOffset, 00643 unsigned TrialOffset, unsigned MaxDisp, bool NegativeOK) { 00644 // On Thumb offsets==2 mod 4 are rounded down by the hardware for 00645 // purposes of the displacement computation; compensate for that here. 00646 // Effectively, the valid range of displacements is 2 bytes smaller for such 00647 // references. 00648 if (isThumb && UserOffset%4 !=0) 00649 UserOffset -= 2; 00650 // CPEs will be rounded up to a multiple of 4. 00651 if (isThumb && TrialOffset%4 != 0) 00652 TrialOffset += 2; 00653 00654 if (UserOffset <= TrialOffset) { 00655 // User before the Trial. 00656 if (TrialOffset-UserOffset <= MaxDisp) 00657 return true; 00658 } else if (NegativeOK) { 00659 if (UserOffset-TrialOffset <= MaxDisp) 00660 return true; 00661 } 00662 return false; 00663 } 00664 00665 /// WaterIsInRange - Returns true if a CPE placed after the specified 00666 /// Water (a basic block) will be in range for the specific MI. 00667 00668 bool ARMConstantIslands::WaterIsInRange(unsigned UserOffset, 00669 MachineBasicBlock* Water, CPUser &U) 00670 { 00671 unsigned MaxDisp = U.MaxDisp; 00672 MachineFunction::iterator I = next(MachineFunction::iterator(Water)); 00673 unsigned CPEOffset = BBOffsets[Water->getNumber()] + 00674 BBSizes[Water->getNumber()]; 00675 00676 // If the CPE is to be inserted before the instruction, that will raise 00677 // the offset of the instruction. (Currently applies only to ARM, so 00678 // no alignment compensation attempted here.) 00679 if (CPEOffset < UserOffset) 00680 UserOffset += U.CPEMI->getOperand(2).getImm(); 00681 00682 return OffsetIsInRange (UserOffset, CPEOffset, MaxDisp, !isThumb); 00683 } 00684 00685 /// CPEIsInRange - Returns true if the distance between specific MI and 00686 /// specific ConstPool entry instruction can fit in MI's displacement field. 00687 bool ARMConstantIslands::CPEIsInRange(MachineInstr *MI, unsigned UserOffset, 00688 MachineInstr *CPEMI, 00689 unsigned MaxDisp, bool DoDump) { 00690 unsigned CPEOffset = GetOffsetOf(CPEMI); 00691 assert(CPEOffset%4 == 0 && "Misaligned CPE"); 00692 00693 if (DoDump) { 00694 DOUT << "User of CPE#" << CPEMI->getOperand(0).getImm() 00695 << " max delta=" << MaxDisp 00696 << " insn address=" << UserOffset 00697 << " CPE address=" << CPEOffset 00698 << " offset=" << int(CPEOffset-UserOffset) << "\t" << *MI; 00699 } 00700 00701 return OffsetIsInRange(UserOffset, CPEOffset, MaxDisp, !isThumb); 00702 } 00703 00704 #ifndef NDEBUG 00705 /// BBIsJumpedOver - Return true of the specified basic block's only predecessor 00706 /// unconditionally branches to its only successor. 00707 static bool BBIsJumpedOver(MachineBasicBlock *MBB) { 00708 if (MBB->pred_size() != 1 || MBB->succ_size() != 1) 00709 return false; 00710 00711 MachineBasicBlock *Succ = *MBB->succ_begin(); 00712 MachineBasicBlock *Pred = *MBB->pred_begin(); 00713 MachineInstr *PredMI = &Pred->back(); 00714 if (PredMI->getOpcode() == ARM::B || PredMI->getOpcode() == ARM::tB) 00715 return PredMI->getOperand(0).getMBB() == Succ; 00716 return false; 00717 } 00718 #endif // NDEBUG 00719 00720 void ARMConstantIslands::AdjustBBOffsetsAfter(MachineBasicBlock *BB, 00721 int delta) { 00722 MachineFunction::iterator MBBI = BB; MBBI = next(MBBI); 00723 for(unsigned i=BB->getNumber()+1; i<BB->getParent()->getNumBlockIDs(); i++) { 00724 BBOffsets[i] += delta; 00725 // If some existing blocks have padding, adjust the padding as needed, a 00726 // bit tricky. delta can be negative so don't use % on that. 00727 if (isThumb) { 00728 MachineBasicBlock *MBB = MBBI; 00729 if (!MBB->empty()) { 00730 // Constant pool entries require padding. 00731 if (MBB->begin()->getOpcode() == ARM::CONSTPOOL_ENTRY) { 00732 unsigned oldOffset = BBOffsets[i] - delta; 00733 if (oldOffset%4==0 && BBOffsets[i]%4!=0) { 00734 // add new padding 00735 BBSizes[i] += 2; 00736 delta += 2; 00737 } else if (oldOffset%4!=0 && BBOffsets[i]%4==0) { 00738 // remove existing padding 00739 BBSizes[i] -=2; 00740 delta -= 2; 00741 } 00742 } 00743 // Thumb jump tables require padding. They should be at the end; 00744 // following unconditional branches are removed by AnalyzeBranch. 00745 MachineInstr *ThumbJTMI = NULL; 00746 if (prior(MBB->end())->getOpcode() == ARM::tBR_JTr) 00747 ThumbJTMI = prior(MBB->end()); 00748 if (ThumbJTMI) { 00749 unsigned newMIOffset = GetOffsetOf(ThumbJTMI); 00750 unsigned oldMIOffset = newMIOffset - delta; 00751 if (oldMIOffset%4 == 0 && newMIOffset%4 != 0) { 00752 // remove existing padding 00753 BBSizes[i] -= 2; 00754 delta -= 2; 00755 } else if (oldMIOffset%4 != 0 && newMIOffset%4 == 0) { 00756 // add new padding 00757 BBSizes[i] += 2; 00758 delta += 2; 00759 } 00760 } 00761 if (delta==0) 00762 return; 00763 } 00764 MBBI = next(MBBI); 00765 } 00766 } 00767 } 00768 00769 /// DecrementOldEntry - find the constant pool entry with index CPI 00770 /// and instruction CPEMI, and decrement its refcount. If the refcount 00771 /// becomes 0 remove the entry and instruction. Returns true if we removed 00772 /// the entry, false if we didn't. 00773 00774 bool ARMConstantIslands::DecrementOldEntry(unsigned CPI, MachineInstr *CPEMI) { 00775 // Find the old entry. Eliminate it if it is no longer used. 00776 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI); 00777 assert(CPE && "Unexpected!"); 00778 if (--CPE->RefCount == 0) { 00779 RemoveDeadCPEMI(CPEMI); 00780 CPE->CPEMI = NULL; 00781 NumCPEs--; 00782 return true; 00783 } 00784 return false; 00785 } 00786 00787 /// LookForCPEntryInRange - see if the currently referenced CPE is in range; 00788 /// if not, see if an in-range clone of the CPE is in range, and if so, 00789 /// change the data structures so the user references the clone. Returns: 00790 /// 0 = no existing entry found 00791 /// 1 = entry found, and there were no code insertions or deletions 00792 /// 2 = entry found, and there were code insertions or deletions 00793 int ARMConstantIslands::LookForExistingCPEntry(CPUser& U, unsigned UserOffset) 00794 { 00795 MachineInstr *UserMI = U.MI; 00796 MachineInstr *CPEMI = U.CPEMI; 00797 00798 // Check to see if the CPE is already in-range. 00799 if (CPEIsInRange(UserMI, UserOffset, CPEMI, U.MaxDisp, true)) { 00800 DOUT << "In range\n"; 00801 return 1; 00802 } 00803 00804 // No. Look for previously created clones of the CPE that are in range. 00805 unsigned CPI = CPEMI->getOperand(1).getIndex(); 00806 std::vector<CPEntry> &CPEs = CPEntries[CPI]; 00807 for (unsigned i = 0, e = CPEs.size(); i != e; ++i) { 00808 // We already tried this one 00809 if (CPEs[i].CPEMI == CPEMI) 00810 continue; 00811 // Removing CPEs can leave empty entries, skip 00812 if (CPEs[i].CPEMI == NULL) 00813 continue; 00814 if (CPEIsInRange(UserMI, UserOffset, CPEs[i].CPEMI, U.MaxDisp, false)) { 00815 DOUT << "Replacing CPE#" << CPI << " with CPE#" << CPEs[i].CPI << "\n"; 00816 // Point the CPUser node to the replacement 00817 U.CPEMI = CPEs[i].CPEMI; 00818 // Change the CPI in the instruction operand to refer to the clone. 00819 for (unsigned j = 0, e = UserMI->getNumOperands(); j != e; ++j) 00820 if (UserMI->getOperand(j).isCPI()) { 00821 UserMI->getOperand(j).setIndex(CPEs[i].CPI); 00822 break; 00823 } 00824 // Adjust the refcount of the clone... 00825 CPEs[i].RefCount++; 00826 // ...and the original. If we didn't remove the old entry, none of the 00827 // addresses changed, so we don't need another pass. 00828 return DecrementOldEntry(CPI, CPEMI) ? 2 : 1; 00829 } 00830 } 00831 return 0; 00832 } 00833 00834 /// getUnconditionalBrDisp - Returns the maximum displacement that can fit in 00835 /// the specific unconditional branch instruction. 00836 static inline unsigned getUnconditionalBrDisp(int Opc) { 00837 return (Opc == ARM::tB) ? ((1<<10)-1)*2 : ((1<<23)-1)*4; 00838 } 00839 00840 /// AcceptWater - Small amount of common code factored out of the following. 00841 00842 MachineBasicBlock* ARMConstantIslands::AcceptWater(MachineBasicBlock *WaterBB, 00843 std::vector<MachineBasicBlock*>::iterator IP) { 00844 DOUT << "found water in range\n"; 00845 // Remove the original WaterList entry; we want subsequent 00846 // insertions in this vicinity to go after the one we're 00847 // about to insert. This considerably reduces the number 00848 // of times we have to move the same CPE more than once. 00849 WaterList.erase(IP); 00850 // CPE goes before following block (NewMBB). 00851 return next(MachineFunction::iterator(WaterBB)); 00852 } 00853 00854 /// LookForWater - look for an existing entry in the WaterList in which 00855 /// we can place the CPE referenced from U so it's within range of U's MI. 00856 /// Returns true if found, false if not. If it returns true, *NewMBB 00857 /// is set to the WaterList entry. 00858 /// For ARM, we prefer the water that's farthest away. For Thumb, prefer 00859 /// water that will not introduce padding to water that will; within each 00860 /// group, prefer the water that's farthest away. 00861 00862 bool ARMConstantIslands::LookForWater(CPUser &U, unsigned UserOffset, 00863 MachineBasicBlock** NewMBB) { 00864 std::vector<MachineBasicBlock*>::iterator IPThatWouldPad; 00865 MachineBasicBlock* WaterBBThatWouldPad = NULL; 00866 if (!WaterList.empty()) { 00867 for (std::vector<MachineBasicBlock*>::iterator IP = prior(WaterList.end()), 00868 B = WaterList.begin();; --IP) { 00869 MachineBasicBlock* WaterBB = *IP; 00870 if (WaterIsInRange(UserOffset, WaterBB, U)) { 00871 if (isThumb && 00872 (BBOffsets[WaterBB->getNumber()] + 00873 BBSizes[WaterBB->getNumber()])%4 != 0) { 00874 // This is valid Water, but would introduce padding. Remember 00875 // it in case we don't find any Water that doesn't do this. 00876 if (!WaterBBThatWouldPad) { 00877 WaterBBThatWouldPad = WaterBB; 00878 IPThatWouldPad = IP; 00879 } 00880 } else { 00881 *NewMBB = AcceptWater(WaterBB, IP); 00882 return true; 00883 } 00884 } 00885 if (IP == B) 00886 break; 00887 } 00888 } 00889 if (isThumb && WaterBBThatWouldPad) { 00890 *NewMBB = AcceptWater(WaterBBThatWouldPad, IPThatWouldPad); 00891 return true; 00892 } 00893 return false; 00894 } 00895 00896 /// CreateNewWater - No existing WaterList entry will work for 00897 /// CPUsers[CPUserIndex], so create a place to put the CPE. The end of the 00898 /// block is used if in range, and the conditional branch munged so control 00899 /// flow is correct. Otherwise the block is split to create a hole with an 00900 /// unconditional branch around it. In either case *NewMBB is set to a 00901 /// block following which the new island can be inserted (the WaterList 00902 /// is not adjusted). 00903 00904 void ARMConstantIslands::CreateNewWater(unsigned CPUserIndex, 00905 unsigned UserOffset, MachineBasicBlock** NewMBB) { 00906 CPUser &U = CPUsers[CPUserIndex]; 00907 MachineInstr *UserMI = U.MI; 00908 MachineInstr *CPEMI = U.CPEMI; 00909 MachineBasicBlock *UserMBB = UserMI->getParent(); 00910 unsigned OffsetOfNextBlock = BBOffsets[UserMBB->getNumber()] + 00911 BBSizes[UserMBB->getNumber()]; 00912 assert(OffsetOfNextBlock== BBOffsets[UserMBB->getNumber()+1]); 00913 00914 // If the use is at the end of the block, or the end of the block 00915 // is within range, make new water there. (The addition below is 00916 // for the unconditional branch we will be adding: 4 bytes on ARM, 00917 // 2 on Thumb. Possible Thumb alignment padding is allowed for 00918 // inside OffsetIsInRange. 00919 // If the block ends in an unconditional branch already, it is water, 00920 // and is known to be out of range, so we'll always be adding a branch.) 00921 if (&UserMBB->back() == UserMI || 00922 OffsetIsInRange(UserOffset, OffsetOfNextBlock + (isThumb ? 2: 4), 00923 U.MaxDisp, !isThumb)) { 00924 DOUT << "Split at end of block\n"; 00925 if (&UserMBB->back() == UserMI) 00926 assert(BBHasFallthrough(UserMBB) && "Expected a fallthrough BB!"); 00927 *NewMBB = next(MachineFunction::iterator(UserMBB)); 00928 // Add an unconditional branch from UserMBB to fallthrough block. 00929 // Record it for branch lengthening; this new branch will not get out of 00930 // range, but if the preceding conditional branch is out of range, the 00931 // targets will be exchanged, and the altered branch may be out of 00932 // range, so the machinery has to know about it. 00933 int UncondBr = isThumb ? ARM::tB : ARM::B; 00934 BuildMI(UserMBB, TII->get(UncondBr)).addMBB(*NewMBB); 00935 unsigned MaxDisp = getUnconditionalBrDisp(UncondBr); 00936 ImmBranches.push_back(ImmBranch(&UserMBB->back(), 00937 MaxDisp, false, UncondBr)); 00938 int delta = isThumb ? 2 : 4; 00939 BBSizes[UserMBB->getNumber()] += delta; 00940 AdjustBBOffsetsAfter(UserMBB, delta); 00941 } else { 00942 // What a big block. Find a place within the block to split it. 00943 // This is a little tricky on Thumb since instructions are 2 bytes 00944 // and constant pool entries are 4 bytes: if instruction I references 00945 // island CPE, and instruction I+1 references CPE', it will 00946 // not work well to put CPE as far forward as possible, since then 00947 // CPE' cannot immediately follow it (that location is 2 bytes 00948 // farther away from I+1 than CPE was from I) and we'd need to create 00949 // a new island. So, we make a first guess, then walk through the 00950 // instructions between the one currently being looked at and the 00951 // possible insertion point, and make sure any other instructions 00952 // that reference CPEs will be able to use the same island area; 00953 // if not, we back up the insertion point. 00954 00955 // The 4 in the following is for the unconditional branch we'll be 00956 // inserting (allows for long branch on Thumb). Alignment of the 00957 // island is handled inside OffsetIsInRange. 00958 unsigned BaseInsertOffset = UserOffset + U.MaxDisp -4; 00959 // This could point off the end of the block if we've already got 00960 // constant pool entries following this block; only the last one is 00961 // in the water list. Back past any possible branches (allow for a 00962 // conditional and a maximally long unconditional). 00963 if (BaseInsertOffset >= BBOffsets[UserMBB->getNumber()+1]) 00964 BaseInsertOffset = BBOffsets[UserMBB->getNumber()+1] - 00965 (isThumb ? 6 : 8); 00966 unsigned EndInsertOffset = BaseInsertOffset + 00967 CPEMI->getOperand(2).getImm(); 00968 MachineBasicBlock::iterator MI = UserMI; 00969 ++MI; 00970 unsigned CPUIndex = CPUserIndex+1; 00971 for (unsigned Offset = UserOffset+TII->GetInstSizeInBytes(UserMI); 00972 Offset < BaseInsertOffset; 00973 Offset += TII->GetInstSizeInBytes(MI), 00974 MI = next(MI)) { 00975 if (CPUIndex < CPUsers.size() && CPUsers[CPUIndex].MI == MI) { 00976 if (!OffsetIsInRange(Offset, EndInsertOffset, 00977 CPUsers[CPUIndex].MaxDisp, !isThumb)) { 00978 BaseInsertOffset -= (isThumb ? 2 : 4); 00979 EndInsertOffset -= (isThumb ? 2 : 4); 00980 } 00981 // This is overly conservative, as we don't account for CPEMIs 00982 // being reused within the block, but it doesn't matter much. 00983 EndInsertOffset += CPUsers[CPUIndex].CPEMI->getOperand(2).getImm(); 00984 CPUIndex++; 00985 } 00986 } 00987 DOUT << "Split in middle of big block\n"; 00988 *NewMBB = SplitBlockBeforeInstr(prior(MI)); 00989 } 00990 } 00991 00992 /// HandleConstantPoolUser - Analyze the specified user, checking to see if it 00993 /// is out-of-range. If so, pick it up the constant pool value and move it some 00994 /// place in-range. Return true if we changed any addresses (thus must run 00995 /// another pass of branch lengthening), false otherwise. 00996 bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn, 00997 unsigned CPUserIndex){ 00998 CPUser &U = CPUsers[CPUserIndex]; 00999 MachineInstr *UserMI = U.MI; 01000 MachineInstr *CPEMI = U.CPEMI; 01001 unsigned CPI = CPEMI->getOperand(1).getIndex(); 01002 unsigned Size = CPEMI->getOperand(2).getImm(); 01003 MachineBasicBlock *NewMBB; 01004 // Compute this only once, it's expensive. The 4 or 8 is the value the 01005 // hardware keeps in the PC (2 insns ahead of the reference). 01006 unsigned UserOffset = GetOffsetOf(UserMI) + (isThumb ? 4 : 8); 01007 01008 // Special case: tLEApcrel are two instructions MI's. The actual user is the 01009 // second instruction. 01010 if (UserMI->getOpcode() == ARM::tLEApcrel) 01011 UserOffset += 2; 01012 01013 // See if the current entry is within range, or there is a clone of it 01014 // in range. 01015 int result = LookForExistingCPEntry(U, UserOffset); 01016 if (result==1) return false; 01017 else if (result==2) return true; 01018 01019 // No existing clone of this CPE is within range. 01020 // We will be generating a new clone. Get a UID for it. 01021 unsigned ID = AFI->createConstPoolEntryUId(); 01022 01023 // Look for water where we can place this CPE. We look for the farthest one 01024 // away that will work. Forward references only for now (although later 01025 // we might find some that are backwards). 01026 01027 if (!LookForWater(U, UserOffset, &NewMBB)) { 01028 // No water found. 01029 DOUT << "No water found\n"; 01030 CreateNewWater(CPUserIndex, UserOffset, &NewMBB); 01031 } 01032 01033 // Okay, we know we can put an island before NewMBB now, do it! 01034 MachineBasicBlock *NewIsland = Fn.CreateMachineBasicBlock(); 01035 Fn.insert(NewMBB, NewIsland); 01036 01037 // Update internal data structures to account for the newly inserted MBB. 01038 UpdateForInsertedWaterBlock(NewIsland); 01039 01040 // Decrement the old entry, and remove it if refcount becomes 0. 01041 DecrementOldEntry(CPI, CPEMI); 01042 01043 // Now that we have an island to add the CPE to, clone the original CPE and 01044 // add it to the island. 01045 U.CPEMI = BuildMI(NewIsland, TII->get(ARM::CONSTPOOL_ENTRY)) 01046 .addImm(ID).addConstantPoolIndex(CPI).addImm(Size); 01047 CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1)); 01048 NumCPEs++; 01049 01050 BBOffsets[NewIsland->getNumber()] = BBOffsets[NewMBB->getNumber()]; 01051 // Compensate for .align 2 in thumb mode. 01052 if (isThumb && BBOffsets[NewIsland->getNumber()]%4 != 0) 01053 Size += 2; 01054 // Increase the size of the island block to account for the new entry. 01055 BBSizes[NewIsland->getNumber()] += Size; 01056 AdjustBBOffsetsAfter(NewIsland, Size); 01057 01058 // Finally, change the CPI in the instruction operand to be ID. 01059 for (unsigned i = 0, e = UserMI->getNumOperands(); i != e; ++i) 01060 if (UserMI->getOperand(i).isCPI()) { 01061 UserMI->getOperand(i).setIndex(ID); 01062 break; 01063 } 01064 01065 DOUT << " Moved CPE to #" << ID << " CPI=" << CPI << "\t" << *UserMI; 01066 01067 return true; 01068 } 01069 01070 /// RemoveDeadCPEMI - Remove a dead constant pool entry instruction. Update 01071 /// sizes and offsets of impacted basic blocks. 01072 void ARMConstantIslands::RemoveDeadCPEMI(MachineInstr *CPEMI) { 01073 MachineBasicBlock *CPEBB = CPEMI->getParent(); 01074 unsigned Size = CPEMI->getOperand(2).getImm(); 01075 CPEMI->eraseFromParent(); 01076 BBSizes[CPEBB->getNumber()] -= Size; 01077 // All succeeding offsets have the current size value added in, fix this. 01078 if (CPEBB->empty()) { 01079 // In thumb mode, the size of island may be padded by two to compensate for 01080 // the alignment requirement. Then it will now be 2 when the block is 01081 // empty, so fix this. 01082 // All succeeding offsets have the current size value added in, fix this. 01083 if (BBSizes[CPEBB->getNumber()] != 0) { 01084 Size += BBSizes[CPEBB->getNumber()]; 01085 BBSizes[CPEBB->getNumber()] = 0; 01086 } 01087 } 01088 AdjustBBOffsetsAfter(CPEBB, -Size); 01089 // An island has only one predecessor BB and one successor BB. Check if 01090 // this BB's predecessor jumps directly to this BB's successor. This 01091 // shouldn't happen currently. 01092 assert(!BBIsJumpedOver(CPEBB) && "How did this happen?"); 01093 // FIXME: remove the empty blocks after all the work is done? 01094 } 01095 01096 /// RemoveUnusedCPEntries - Remove constant pool entries whose refcounts 01097 /// are zero. 01098 bool ARMConstantIslands::RemoveUnusedCPEntries() { 01099 unsigned MadeChange = false; 01100 for (unsigned i = 0, e = CPEntries.size(); i != e; ++i) { 01101 std::vector<CPEntry> &CPEs = CPEntries[i]; 01102 for (unsigned j = 0, ee = CPEs.size(); j != ee; ++j) { 01103 if (CPEs[j].RefCount == 0 && CPEs[j].CPEMI) { 01104 RemoveDeadCPEMI(CPEs[j].CPEMI); 01105 CPEs[j].CPEMI = NULL; 01106 MadeChange = true; 01107 } 01108 } 01109 } 01110 return MadeChange; 01111 } 01112 01113 /// BBIsInRange - Returns true if the distance between specific MI and 01114 /// specific BB can fit in MI's displacement field. 01115 bool ARMConstantIslands::BBIsInRange(MachineInstr *MI,MachineBasicBlock *DestBB, 01116 unsigned MaxDisp) { 01117 unsigned PCAdj = isThumb ? 4 : 8; 01118 unsigned BrOffset = GetOffsetOf(MI) + PCAdj; 01119 unsigned DestOffset = BBOffsets[DestBB->getNumber()]; 01120 01121 DOUT << "Branch of destination BB#" << DestBB->getNumber() 01122 << " from BB#" << MI->getParent()->getNumber() 01123 << " max delta=" << MaxDisp 01124 << " from " << GetOffsetOf(MI) << " to " << DestOffset 01125 << " offset " << int(DestOffset-BrOffset) << "\t" << *MI; 01126 01127 if (BrOffset <= DestOffset) { 01128 // Branch before the Dest. 01129 if (DestOffset-BrOffset <= MaxDisp) 01130 return true; 01131 } else { 01132 if (BrOffset-DestOffset <= MaxDisp) 01133 return true; 01134 } 01135 return false; 01136 } 01137 01138 /// FixUpImmediateBr - Fix up an immediate branch whose destination is too far 01139 /// away to fit in its displacement field. 01140 bool ARMConstantIslands::FixUpImmediateBr(MachineFunction &Fn, ImmBranch &Br) { 01141 MachineInstr *MI = Br.MI; 01142 MachineBasicBlock *DestBB = MI->getOperand(0).getMBB(); 01143 01144 // Check to see if the DestBB is already in-range. 01145 if (BBIsInRange(MI, DestBB, Br.MaxDisp)) 01146 return false; 01147 01148 if (!Br.isCond) 01149 return FixUpUnconditionalBr(Fn, Br); 01150 return FixUpConditionalBr(Fn, Br); 01151 } 01152 01153 /// FixUpUnconditionalBr - Fix up an unconditional branch whose destination is 01154 /// too far away to fit in its displacement field. If the LR register has been 01155 /// spilled in the epilogue, then we can use BL to implement a far jump. 01156 /// Otherwise, add an intermediate branch instruction to to a branch. 01157 bool 01158 ARMConstantIslands::FixUpUnconditionalBr(MachineFunction &Fn, ImmBranch &Br) { 01159 MachineInstr *MI = Br.MI; 01160 MachineBasicBlock *MBB = MI->getParent(); 01161 assert(isThumb && "Expected a Thumb function!"); 01162 01163 // Use BL to implement far jump. 01164 Br.MaxDisp = (1 << 21) * 2; 01165 MI->setDesc(TII->get(ARM::tBfar)); 01166 BBSizes[MBB->getNumber()] += 2; 01167 AdjustBBOffsetsAfter(MBB, 2); 01168 HasFarJump = true; 01169 NumUBrFixed++; 01170 01171 DOUT << " Changed B to long jump " << *MI; 01172 01173 return true; 01174 } 01175 01176 /// FixUpConditionalBr - Fix up a conditional branch whose destination is too 01177 /// far away to fit in its displacement field. It is converted to an inverse 01178 /// conditional branch + an unconditional branch to the destination. 01179 bool 01180 ARMConstantIslands::FixUpConditionalBr(MachineFunction &Fn, ImmBranch &Br) { 01181 MachineInstr *MI = Br.MI; 01182 MachineBasicBlock *DestBB = MI->getOperand(0).getMBB(); 01183 01184 // Add a unconditional branch to the destination and invert the branch 01185 // condition to jump over it: 01186 // blt L1 01187 // => 01188 // bge L2 01189 // b L1 01190 // L2: 01191 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(1).getImm(); 01192 CC = ARMCC::getOppositeCondition(CC); 01193 unsigned CCReg = MI->getOperand(2).getReg(); 01194 01195 // If the branch is at the end of its MBB and that has a fall-through block, 01196 // direct the updated conditional branch to the fall-through block. Otherwise, 01197 // split the MBB before the next instruction. 01198 MachineBasicBlock *MBB = MI->getParent(); 01199 MachineInstr *BMI = &MBB->back(); 01200 bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB); 01201 01202 NumCBrFixed++; 01203 if (BMI != MI) { 01204 if (next(MachineBasicBlock::iterator(MI)) == prior(MBB->end()) && 01205 BMI->getOpcode() == Br.UncondBr) { 01206 // Last MI in the BB is a unconditional branch. Can we simply invert the 01207 // condition and swap destinations: 01208 // beq L1 01209 // b L2 01210 // => 01211 // bne L2 01212 // b L1 01213 MachineBasicBlock *NewDest = BMI->getOperand(0).getMBB(); 01214 if (BBIsInRange(MI, NewDest, Br.MaxDisp)) { 01215 DOUT << " Invert Bcc condition and swap its destination with " << *BMI; 01216 BMI->getOperand(0).setMBB(DestBB); 01217 MI->getOperand(0).setMBB(NewDest); 01218 MI->getOperand(1).setImm(CC); 01219 return true; 01220 } 01221 } 01222 } 01223 01224 if (NeedSplit) { 01225 SplitBlockBeforeInstr(MI); 01226 // No need for the branch to the next block. We're adding a unconditional 01227 // branch to the destination. 01228 int delta = TII->GetInstSizeInBytes(&MBB->back()); 01229 BBSizes[MBB->getNumber()] -= delta; 01230 MachineBasicBlock* SplitBB = next(MachineFunction::iterator(MBB)); 01231 AdjustBBOffsetsAfter(SplitBB, -delta); 01232 MBB->back().eraseFromParent(); 01233 // BBOffsets[SplitBB] is wrong temporarily, fixed below 01234 } 01235 MachineBasicBlock *NextBB = next(MachineFunction::iterator(MBB)); 01236 01237 DOUT << " Insert B to BB#" << DestBB->getNumber() 01238 << " also invert condition and change dest. to BB#" 01239 << NextBB->getNumber() << "\n"; 01240 01241 // Insert a new conditional branch and a new unconditional branch. 01242 // Also update the ImmBranch as well as adding a new entry for the new branch. 01243 BuildMI(MBB, TII->get(MI->getOpcode())).addMBB(NextBB) 01244 .addImm(CC).addReg(CCReg); 01245 Br.MI = &MBB->back(); 01246 BBSizes[MBB->getNumber()] += TII->GetInstSizeInBytes(&MBB->back()); 01247 BuildMI(MBB, TII->get(Br.UncondBr)).addMBB(DestBB); 01248 BBSizes[MBB->getNumber()] += TII->GetInstSizeInBytes(&MBB->back()); 01249 unsigned MaxDisp = getUnconditionalBrDisp(Br.UncondBr); 01250 ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr)); 01251 01252 // Remove the old conditional branch. It may or may not still be in MBB. 01253 BBSizes[MI->getParent()->getNumber()] -= TII->GetInstSizeInBytes(MI); 01254 MI->eraseFromParent(); 01255 01256 // The net size change is an addition of one unconditional branch. 01257 int delta = TII->GetInstSizeInBytes(&MBB->back()); 01258 AdjustBBOffsetsAfter(MBB, delta); 01259 return true; 01260 } 01261 01262 /// UndoLRSpillRestore - Remove Thumb push / pop instructions that only spills 01263 /// LR / restores LR to pc. 01264 bool ARMConstantIslands::UndoLRSpillRestore() { 01265 bool MadeChange = false; 01266 for (unsigned i = 0, e = PushPopMIs.size(); i != e; ++i) { 01267 MachineInstr *MI = PushPopMIs[i]; 01268 if (MI->getOpcode() == ARM::tPOP_RET && 01269 MI->getOperand(0).getReg() == ARM::PC && 01270 MI->getNumExplicitOperands() == 1) { 01271 BuildMI(MI->getParent(), TII->get(ARM::tBX_RET)); 01272 MI->eraseFromParent(); 01273 MadeChange = true; 01274 } 01275 } 01276 return MadeChange; 01277 }