1*0b57cec5SDimitry Andric //===- ARMConstantIslandPass.cpp - ARM constant islands -------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file contains a pass that splits the constant pool up into 'islands' 10*0b57cec5SDimitry Andric // which are scattered through-out the function. This is required due to the 11*0b57cec5SDimitry Andric // limited pc-relative displacements that ARM has. 12*0b57cec5SDimitry Andric // 13*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 14*0b57cec5SDimitry Andric 15*0b57cec5SDimitry Andric #include "ARM.h" 16*0b57cec5SDimitry Andric #include "ARMBaseInstrInfo.h" 17*0b57cec5SDimitry Andric #include "ARMBasicBlockInfo.h" 18*0b57cec5SDimitry Andric #include "ARMMachineFunctionInfo.h" 19*0b57cec5SDimitry Andric #include "ARMSubtarget.h" 20*0b57cec5SDimitry Andric #include "MCTargetDesc/ARMBaseInfo.h" 21*0b57cec5SDimitry Andric #include "Thumb2InstrInfo.h" 22*0b57cec5SDimitry Andric #include "Utils/ARMBaseInfo.h" 23*0b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 24*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 25*0b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h" 26*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 27*0b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 28*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 29*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 30*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h" 31*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 32*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 33*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 34*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h" 35*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 36*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 37*0b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h" 38*0b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 39*0b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 40*0b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 41*0b57cec5SDimitry Andric #include "llvm/Pass.h" 42*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 43*0b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 44*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 45*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 46*0b57cec5SDimitry Andric #include "llvm/Support/Format.h" 47*0b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 48*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 49*0b57cec5SDimitry Andric #include <algorithm> 50*0b57cec5SDimitry Andric #include <cassert> 51*0b57cec5SDimitry Andric #include <cstdint> 52*0b57cec5SDimitry Andric #include <iterator> 53*0b57cec5SDimitry Andric #include <utility> 54*0b57cec5SDimitry Andric #include <vector> 55*0b57cec5SDimitry Andric 56*0b57cec5SDimitry Andric using namespace llvm; 57*0b57cec5SDimitry Andric 58*0b57cec5SDimitry Andric #define DEBUG_TYPE "arm-cp-islands" 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric #define ARM_CP_ISLANDS_OPT_NAME \ 61*0b57cec5SDimitry Andric "ARM constant island placement and branch shortening pass" 62*0b57cec5SDimitry Andric STATISTIC(NumCPEs, "Number of constpool entries"); 63*0b57cec5SDimitry Andric STATISTIC(NumSplit, "Number of uncond branches inserted"); 64*0b57cec5SDimitry Andric STATISTIC(NumCBrFixed, "Number of cond branches fixed"); 65*0b57cec5SDimitry Andric STATISTIC(NumUBrFixed, "Number of uncond branches fixed"); 66*0b57cec5SDimitry Andric STATISTIC(NumTBs, "Number of table branches generated"); 67*0b57cec5SDimitry Andric STATISTIC(NumT2CPShrunk, "Number of Thumb2 constantpool instructions shrunk"); 68*0b57cec5SDimitry Andric STATISTIC(NumT2BrShrunk, "Number of Thumb2 immediate branches shrunk"); 69*0b57cec5SDimitry Andric STATISTIC(NumCBZ, "Number of CBZ / CBNZ formed"); 70*0b57cec5SDimitry Andric STATISTIC(NumJTMoved, "Number of jump table destination blocks moved"); 71*0b57cec5SDimitry Andric STATISTIC(NumJTInserted, "Number of jump table intermediate blocks inserted"); 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric static cl::opt<bool> 74*0b57cec5SDimitry Andric AdjustJumpTableBlocks("arm-adjust-jump-tables", cl::Hidden, cl::init(true), 75*0b57cec5SDimitry Andric cl::desc("Adjust basic block layout to better use TB[BH]")); 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric static cl::opt<unsigned> 78*0b57cec5SDimitry Andric CPMaxIteration("arm-constant-island-max-iteration", cl::Hidden, cl::init(30), 79*0b57cec5SDimitry Andric cl::desc("The max number of iteration for converge")); 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric static cl::opt<bool> SynthesizeThumb1TBB( 82*0b57cec5SDimitry Andric "arm-synthesize-thumb-1-tbb", cl::Hidden, cl::init(true), 83*0b57cec5SDimitry Andric cl::desc("Use compressed jump tables in Thumb-1 by synthesizing an " 84*0b57cec5SDimitry Andric "equivalent to the TBB/TBH instructions")); 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric namespace { 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric /// ARMConstantIslands - Due to limited PC-relative displacements, ARM 89*0b57cec5SDimitry Andric /// requires constant pool entries to be scattered among the instructions 90*0b57cec5SDimitry Andric /// inside a function. To do this, it completely ignores the normal LLVM 91*0b57cec5SDimitry Andric /// constant pool; instead, it places constants wherever it feels like with 92*0b57cec5SDimitry Andric /// special instructions. 93*0b57cec5SDimitry Andric /// 94*0b57cec5SDimitry Andric /// The terminology used in this pass includes: 95*0b57cec5SDimitry Andric /// Islands - Clumps of constants placed in the function. 96*0b57cec5SDimitry Andric /// Water - Potential places where an island could be formed. 97*0b57cec5SDimitry Andric /// CPE - A constant pool entry that has been placed somewhere, which 98*0b57cec5SDimitry Andric /// tracks a list of users. 99*0b57cec5SDimitry Andric class ARMConstantIslands : public MachineFunctionPass { 100*0b57cec5SDimitry Andric std::unique_ptr<ARMBasicBlockUtils> BBUtils = nullptr; 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric /// WaterList - A sorted list of basic blocks where islands could be placed 103*0b57cec5SDimitry Andric /// (i.e. blocks that don't fall through to the following block, due 104*0b57cec5SDimitry Andric /// to a return, unreachable, or unconditional branch). 105*0b57cec5SDimitry Andric std::vector<MachineBasicBlock*> WaterList; 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric /// NewWaterList - The subset of WaterList that was created since the 108*0b57cec5SDimitry Andric /// previous iteration by inserting unconditional branches. 109*0b57cec5SDimitry Andric SmallSet<MachineBasicBlock*, 4> NewWaterList; 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric using water_iterator = std::vector<MachineBasicBlock *>::iterator; 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andric /// CPUser - One user of a constant pool, keeping the machine instruction 114*0b57cec5SDimitry Andric /// pointer, the constant pool being referenced, and the max displacement 115*0b57cec5SDimitry Andric /// allowed from the instruction to the CP. The HighWaterMark records the 116*0b57cec5SDimitry Andric /// highest basic block where a new CPEntry can be placed. To ensure this 117*0b57cec5SDimitry Andric /// pass terminates, the CP entries are initially placed at the end of the 118*0b57cec5SDimitry Andric /// function and then move monotonically to lower addresses. The 119*0b57cec5SDimitry Andric /// exception to this rule is when the current CP entry for a particular 120*0b57cec5SDimitry Andric /// CPUser is out of range, but there is another CP entry for the same 121*0b57cec5SDimitry Andric /// constant value in range. We want to use the existing in-range CP 122*0b57cec5SDimitry Andric /// entry, but if it later moves out of range, the search for new water 123*0b57cec5SDimitry Andric /// should resume where it left off. The HighWaterMark is used to record 124*0b57cec5SDimitry Andric /// that point. 125*0b57cec5SDimitry Andric struct CPUser { 126*0b57cec5SDimitry Andric MachineInstr *MI; 127*0b57cec5SDimitry Andric MachineInstr *CPEMI; 128*0b57cec5SDimitry Andric MachineBasicBlock *HighWaterMark; 129*0b57cec5SDimitry Andric unsigned MaxDisp; 130*0b57cec5SDimitry Andric bool NegOk; 131*0b57cec5SDimitry Andric bool IsSoImm; 132*0b57cec5SDimitry Andric bool KnownAlignment = false; 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp, 135*0b57cec5SDimitry Andric bool neg, bool soimm) 136*0b57cec5SDimitry Andric : MI(mi), CPEMI(cpemi), MaxDisp(maxdisp), NegOk(neg), IsSoImm(soimm) { 137*0b57cec5SDimitry Andric HighWaterMark = CPEMI->getParent(); 138*0b57cec5SDimitry Andric } 139*0b57cec5SDimitry Andric 140*0b57cec5SDimitry Andric /// getMaxDisp - Returns the maximum displacement supported by MI. 141*0b57cec5SDimitry Andric /// Correct for unknown alignment. 142*0b57cec5SDimitry Andric /// Conservatively subtract 2 bytes to handle weird alignment effects. 143*0b57cec5SDimitry Andric unsigned getMaxDisp() const { 144*0b57cec5SDimitry Andric return (KnownAlignment ? MaxDisp : MaxDisp - 2) - 2; 145*0b57cec5SDimitry Andric } 146*0b57cec5SDimitry Andric }; 147*0b57cec5SDimitry Andric 148*0b57cec5SDimitry Andric /// CPUsers - Keep track of all of the machine instructions that use various 149*0b57cec5SDimitry Andric /// constant pools and their max displacement. 150*0b57cec5SDimitry Andric std::vector<CPUser> CPUsers; 151*0b57cec5SDimitry Andric 152*0b57cec5SDimitry Andric /// CPEntry - One per constant pool entry, keeping the machine instruction 153*0b57cec5SDimitry Andric /// pointer, the constpool index, and the number of CPUser's which 154*0b57cec5SDimitry Andric /// reference this entry. 155*0b57cec5SDimitry Andric struct CPEntry { 156*0b57cec5SDimitry Andric MachineInstr *CPEMI; 157*0b57cec5SDimitry Andric unsigned CPI; 158*0b57cec5SDimitry Andric unsigned RefCount; 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric CPEntry(MachineInstr *cpemi, unsigned cpi, unsigned rc = 0) 161*0b57cec5SDimitry Andric : CPEMI(cpemi), CPI(cpi), RefCount(rc) {} 162*0b57cec5SDimitry Andric }; 163*0b57cec5SDimitry Andric 164*0b57cec5SDimitry Andric /// CPEntries - Keep track of all of the constant pool entry machine 165*0b57cec5SDimitry Andric /// instructions. For each original constpool index (i.e. those that existed 166*0b57cec5SDimitry Andric /// upon entry to this pass), it keeps a vector of entries. Original 167*0b57cec5SDimitry Andric /// elements are cloned as we go along; the clones are put in the vector of 168*0b57cec5SDimitry Andric /// the original element, but have distinct CPIs. 169*0b57cec5SDimitry Andric /// 170*0b57cec5SDimitry Andric /// The first half of CPEntries contains generic constants, the second half 171*0b57cec5SDimitry Andric /// contains jump tables. Use getCombinedIndex on a generic CPEMI to look up 172*0b57cec5SDimitry Andric /// which vector it will be in here. 173*0b57cec5SDimitry Andric std::vector<std::vector<CPEntry>> CPEntries; 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric /// Maps a JT index to the offset in CPEntries containing copies of that 176*0b57cec5SDimitry Andric /// table. The equivalent map for a CONSTPOOL_ENTRY is the identity. 177*0b57cec5SDimitry Andric DenseMap<int, int> JumpTableEntryIndices; 178*0b57cec5SDimitry Andric 179*0b57cec5SDimitry Andric /// Maps a JT index to the LEA that actually uses the index to calculate its 180*0b57cec5SDimitry Andric /// base address. 181*0b57cec5SDimitry Andric DenseMap<int, int> JumpTableUserIndices; 182*0b57cec5SDimitry Andric 183*0b57cec5SDimitry Andric /// ImmBranch - One per immediate branch, keeping the machine instruction 184*0b57cec5SDimitry Andric /// pointer, conditional or unconditional, the max displacement, 185*0b57cec5SDimitry Andric /// and (if isCond is true) the corresponding unconditional branch 186*0b57cec5SDimitry Andric /// opcode. 187*0b57cec5SDimitry Andric struct ImmBranch { 188*0b57cec5SDimitry Andric MachineInstr *MI; 189*0b57cec5SDimitry Andric unsigned MaxDisp : 31; 190*0b57cec5SDimitry Andric bool isCond : 1; 191*0b57cec5SDimitry Andric unsigned UncondBr; 192*0b57cec5SDimitry Andric 193*0b57cec5SDimitry Andric ImmBranch(MachineInstr *mi, unsigned maxdisp, bool cond, unsigned ubr) 194*0b57cec5SDimitry Andric : MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {} 195*0b57cec5SDimitry Andric }; 196*0b57cec5SDimitry Andric 197*0b57cec5SDimitry Andric /// ImmBranches - Keep track of all the immediate branch instructions. 198*0b57cec5SDimitry Andric std::vector<ImmBranch> ImmBranches; 199*0b57cec5SDimitry Andric 200*0b57cec5SDimitry Andric /// PushPopMIs - Keep track of all the Thumb push / pop instructions. 201*0b57cec5SDimitry Andric SmallVector<MachineInstr*, 4> PushPopMIs; 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric /// T2JumpTables - Keep track of all the Thumb2 jumptable instructions. 204*0b57cec5SDimitry Andric SmallVector<MachineInstr*, 4> T2JumpTables; 205*0b57cec5SDimitry Andric 206*0b57cec5SDimitry Andric /// HasFarJump - True if any far jump instruction has been emitted during 207*0b57cec5SDimitry Andric /// the branch fix up pass. 208*0b57cec5SDimitry Andric bool HasFarJump; 209*0b57cec5SDimitry Andric 210*0b57cec5SDimitry Andric MachineFunction *MF; 211*0b57cec5SDimitry Andric MachineConstantPool *MCP; 212*0b57cec5SDimitry Andric const ARMBaseInstrInfo *TII; 213*0b57cec5SDimitry Andric const ARMSubtarget *STI; 214*0b57cec5SDimitry Andric ARMFunctionInfo *AFI; 215*0b57cec5SDimitry Andric bool isThumb; 216*0b57cec5SDimitry Andric bool isThumb1; 217*0b57cec5SDimitry Andric bool isThumb2; 218*0b57cec5SDimitry Andric bool isPositionIndependentOrROPI; 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric public: 221*0b57cec5SDimitry Andric static char ID; 222*0b57cec5SDimitry Andric 223*0b57cec5SDimitry Andric ARMConstantIslands() : MachineFunctionPass(ID) {} 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 226*0b57cec5SDimitry Andric 227*0b57cec5SDimitry Andric MachineFunctionProperties getRequiredProperties() const override { 228*0b57cec5SDimitry Andric return MachineFunctionProperties().set( 229*0b57cec5SDimitry Andric MachineFunctionProperties::Property::NoVRegs); 230*0b57cec5SDimitry Andric } 231*0b57cec5SDimitry Andric 232*0b57cec5SDimitry Andric StringRef getPassName() const override { 233*0b57cec5SDimitry Andric return ARM_CP_ISLANDS_OPT_NAME; 234*0b57cec5SDimitry Andric } 235*0b57cec5SDimitry Andric 236*0b57cec5SDimitry Andric private: 237*0b57cec5SDimitry Andric void doInitialConstPlacement(std::vector<MachineInstr *> &CPEMIs); 238*0b57cec5SDimitry Andric void doInitialJumpTablePlacement(std::vector<MachineInstr *> &CPEMIs); 239*0b57cec5SDimitry Andric bool BBHasFallthrough(MachineBasicBlock *MBB); 240*0b57cec5SDimitry Andric CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI); 241*0b57cec5SDimitry Andric unsigned getCPELogAlign(const MachineInstr *CPEMI); 242*0b57cec5SDimitry Andric void scanFunctionJumpTables(); 243*0b57cec5SDimitry Andric void initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs); 244*0b57cec5SDimitry Andric MachineBasicBlock *splitBlockBeforeInstr(MachineInstr *MI); 245*0b57cec5SDimitry Andric void updateForInsertedWaterBlock(MachineBasicBlock *NewBB); 246*0b57cec5SDimitry Andric bool decrementCPEReferenceCount(unsigned CPI, MachineInstr* CPEMI); 247*0b57cec5SDimitry Andric unsigned getCombinedIndex(const MachineInstr *CPEMI); 248*0b57cec5SDimitry Andric int findInRangeCPEntry(CPUser& U, unsigned UserOffset); 249*0b57cec5SDimitry Andric bool findAvailableWater(CPUser&U, unsigned UserOffset, 250*0b57cec5SDimitry Andric water_iterator &WaterIter, bool CloserWater); 251*0b57cec5SDimitry Andric void createNewWater(unsigned CPUserIndex, unsigned UserOffset, 252*0b57cec5SDimitry Andric MachineBasicBlock *&NewMBB); 253*0b57cec5SDimitry Andric bool handleConstantPoolUser(unsigned CPUserIndex, bool CloserWater); 254*0b57cec5SDimitry Andric void removeDeadCPEMI(MachineInstr *CPEMI); 255*0b57cec5SDimitry Andric bool removeUnusedCPEntries(); 256*0b57cec5SDimitry Andric bool isCPEntryInRange(MachineInstr *MI, unsigned UserOffset, 257*0b57cec5SDimitry Andric MachineInstr *CPEMI, unsigned Disp, bool NegOk, 258*0b57cec5SDimitry Andric bool DoDump = false); 259*0b57cec5SDimitry Andric bool isWaterInRange(unsigned UserOffset, MachineBasicBlock *Water, 260*0b57cec5SDimitry Andric CPUser &U, unsigned &Growth); 261*0b57cec5SDimitry Andric bool fixupImmediateBr(ImmBranch &Br); 262*0b57cec5SDimitry Andric bool fixupConditionalBr(ImmBranch &Br); 263*0b57cec5SDimitry Andric bool fixupUnconditionalBr(ImmBranch &Br); 264*0b57cec5SDimitry Andric bool undoLRSpillRestore(); 265*0b57cec5SDimitry Andric bool optimizeThumb2Instructions(); 266*0b57cec5SDimitry Andric bool optimizeThumb2Branches(); 267*0b57cec5SDimitry Andric bool reorderThumb2JumpTables(); 268*0b57cec5SDimitry Andric bool preserveBaseRegister(MachineInstr *JumpMI, MachineInstr *LEAMI, 269*0b57cec5SDimitry Andric unsigned &DeadSize, bool &CanDeleteLEA, 270*0b57cec5SDimitry Andric bool &BaseRegKill); 271*0b57cec5SDimitry Andric bool optimizeThumb2JumpTables(); 272*0b57cec5SDimitry Andric MachineBasicBlock *adjustJTTargetBlockForward(MachineBasicBlock *BB, 273*0b57cec5SDimitry Andric MachineBasicBlock *JTBB); 274*0b57cec5SDimitry Andric 275*0b57cec5SDimitry Andric unsigned getUserOffset(CPUser&) const; 276*0b57cec5SDimitry Andric void dumpBBs(); 277*0b57cec5SDimitry Andric void verify(); 278*0b57cec5SDimitry Andric 279*0b57cec5SDimitry Andric bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset, 280*0b57cec5SDimitry Andric unsigned Disp, bool NegativeOK, bool IsSoImm = false); 281*0b57cec5SDimitry Andric bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset, 282*0b57cec5SDimitry Andric const CPUser &U) { 283*0b57cec5SDimitry Andric return isOffsetInRange(UserOffset, TrialOffset, 284*0b57cec5SDimitry Andric U.getMaxDisp(), U.NegOk, U.IsSoImm); 285*0b57cec5SDimitry Andric } 286*0b57cec5SDimitry Andric }; 287*0b57cec5SDimitry Andric 288*0b57cec5SDimitry Andric } // end anonymous namespace 289*0b57cec5SDimitry Andric 290*0b57cec5SDimitry Andric char ARMConstantIslands::ID = 0; 291*0b57cec5SDimitry Andric 292*0b57cec5SDimitry Andric /// verify - check BBOffsets, BBSizes, alignment of islands 293*0b57cec5SDimitry Andric void ARMConstantIslands::verify() { 294*0b57cec5SDimitry Andric #ifndef NDEBUG 295*0b57cec5SDimitry Andric BBInfoVector &BBInfo = BBUtils->getBBInfo(); 296*0b57cec5SDimitry Andric assert(std::is_sorted(MF->begin(), MF->end(), 297*0b57cec5SDimitry Andric [&BBInfo](const MachineBasicBlock &LHS, 298*0b57cec5SDimitry Andric const MachineBasicBlock &RHS) { 299*0b57cec5SDimitry Andric return BBInfo[LHS.getNumber()].postOffset() < 300*0b57cec5SDimitry Andric BBInfo[RHS.getNumber()].postOffset(); 301*0b57cec5SDimitry Andric })); 302*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Verifying " << CPUsers.size() << " CP users.\n"); 303*0b57cec5SDimitry Andric for (unsigned i = 0, e = CPUsers.size(); i != e; ++i) { 304*0b57cec5SDimitry Andric CPUser &U = CPUsers[i]; 305*0b57cec5SDimitry Andric unsigned UserOffset = getUserOffset(U); 306*0b57cec5SDimitry Andric // Verify offset using the real max displacement without the safety 307*0b57cec5SDimitry Andric // adjustment. 308*0b57cec5SDimitry Andric if (isCPEntryInRange(U.MI, UserOffset, U.CPEMI, U.getMaxDisp()+2, U.NegOk, 309*0b57cec5SDimitry Andric /* DoDump = */ true)) { 310*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "OK\n"); 311*0b57cec5SDimitry Andric continue; 312*0b57cec5SDimitry Andric } 313*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Out of range.\n"); 314*0b57cec5SDimitry Andric dumpBBs(); 315*0b57cec5SDimitry Andric LLVM_DEBUG(MF->dump()); 316*0b57cec5SDimitry Andric llvm_unreachable("Constant pool entry out of range!"); 317*0b57cec5SDimitry Andric } 318*0b57cec5SDimitry Andric #endif 319*0b57cec5SDimitry Andric } 320*0b57cec5SDimitry Andric 321*0b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 322*0b57cec5SDimitry Andric /// print block size and offset information - debugging 323*0b57cec5SDimitry Andric LLVM_DUMP_METHOD void ARMConstantIslands::dumpBBs() { 324*0b57cec5SDimitry Andric BBInfoVector &BBInfo = BBUtils->getBBInfo(); 325*0b57cec5SDimitry Andric LLVM_DEBUG({ 326*0b57cec5SDimitry Andric for (unsigned J = 0, E = BBInfo.size(); J !=E; ++J) { 327*0b57cec5SDimitry Andric const BasicBlockInfo &BBI = BBInfo[J]; 328*0b57cec5SDimitry Andric dbgs() << format("%08x %bb.%u\t", BBI.Offset, J) 329*0b57cec5SDimitry Andric << " kb=" << unsigned(BBI.KnownBits) 330*0b57cec5SDimitry Andric << " ua=" << unsigned(BBI.Unalign) 331*0b57cec5SDimitry Andric << " pa=" << unsigned(BBI.PostAlign) 332*0b57cec5SDimitry Andric << format(" size=%#x\n", BBInfo[J].Size); 333*0b57cec5SDimitry Andric } 334*0b57cec5SDimitry Andric }); 335*0b57cec5SDimitry Andric } 336*0b57cec5SDimitry Andric #endif 337*0b57cec5SDimitry Andric 338*0b57cec5SDimitry Andric bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) { 339*0b57cec5SDimitry Andric MF = &mf; 340*0b57cec5SDimitry Andric MCP = mf.getConstantPool(); 341*0b57cec5SDimitry Andric BBUtils = std::unique_ptr<ARMBasicBlockUtils>(new ARMBasicBlockUtils(mf)); 342*0b57cec5SDimitry Andric 343*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "***** ARMConstantIslands: " 344*0b57cec5SDimitry Andric << MCP->getConstants().size() << " CP entries, aligned to " 345*0b57cec5SDimitry Andric << MCP->getConstantPoolAlignment() << " bytes *****\n"); 346*0b57cec5SDimitry Andric 347*0b57cec5SDimitry Andric STI = &static_cast<const ARMSubtarget &>(MF->getSubtarget()); 348*0b57cec5SDimitry Andric TII = STI->getInstrInfo(); 349*0b57cec5SDimitry Andric isPositionIndependentOrROPI = 350*0b57cec5SDimitry Andric STI->getTargetLowering()->isPositionIndependent() || STI->isROPI(); 351*0b57cec5SDimitry Andric AFI = MF->getInfo<ARMFunctionInfo>(); 352*0b57cec5SDimitry Andric 353*0b57cec5SDimitry Andric isThumb = AFI->isThumbFunction(); 354*0b57cec5SDimitry Andric isThumb1 = AFI->isThumb1OnlyFunction(); 355*0b57cec5SDimitry Andric isThumb2 = AFI->isThumb2Function(); 356*0b57cec5SDimitry Andric 357*0b57cec5SDimitry Andric HasFarJump = false; 358*0b57cec5SDimitry Andric bool GenerateTBB = isThumb2 || (isThumb1 && SynthesizeThumb1TBB); 359*0b57cec5SDimitry Andric 360*0b57cec5SDimitry Andric // This pass invalidates liveness information when it splits basic blocks. 361*0b57cec5SDimitry Andric MF->getRegInfo().invalidateLiveness(); 362*0b57cec5SDimitry Andric 363*0b57cec5SDimitry Andric // Renumber all of the machine basic blocks in the function, guaranteeing that 364*0b57cec5SDimitry Andric // the numbers agree with the position of the block in the function. 365*0b57cec5SDimitry Andric MF->RenumberBlocks(); 366*0b57cec5SDimitry Andric 367*0b57cec5SDimitry Andric // Try to reorder and otherwise adjust the block layout to make good use 368*0b57cec5SDimitry Andric // of the TB[BH] instructions. 369*0b57cec5SDimitry Andric bool MadeChange = false; 370*0b57cec5SDimitry Andric if (GenerateTBB && AdjustJumpTableBlocks) { 371*0b57cec5SDimitry Andric scanFunctionJumpTables(); 372*0b57cec5SDimitry Andric MadeChange |= reorderThumb2JumpTables(); 373*0b57cec5SDimitry Andric // Data is out of date, so clear it. It'll be re-computed later. 374*0b57cec5SDimitry Andric T2JumpTables.clear(); 375*0b57cec5SDimitry Andric // Blocks may have shifted around. Keep the numbering up to date. 376*0b57cec5SDimitry Andric MF->RenumberBlocks(); 377*0b57cec5SDimitry Andric } 378*0b57cec5SDimitry Andric 379*0b57cec5SDimitry Andric // Perform the initial placement of the constant pool entries. To start with, 380*0b57cec5SDimitry Andric // we put them all at the end of the function. 381*0b57cec5SDimitry Andric std::vector<MachineInstr*> CPEMIs; 382*0b57cec5SDimitry Andric if (!MCP->isEmpty()) 383*0b57cec5SDimitry Andric doInitialConstPlacement(CPEMIs); 384*0b57cec5SDimitry Andric 385*0b57cec5SDimitry Andric if (MF->getJumpTableInfo()) 386*0b57cec5SDimitry Andric doInitialJumpTablePlacement(CPEMIs); 387*0b57cec5SDimitry Andric 388*0b57cec5SDimitry Andric /// The next UID to take is the first unused one. 389*0b57cec5SDimitry Andric AFI->initPICLabelUId(CPEMIs.size()); 390*0b57cec5SDimitry Andric 391*0b57cec5SDimitry Andric // Do the initial scan of the function, building up information about the 392*0b57cec5SDimitry Andric // sizes of each block, the location of all the water, and finding all of the 393*0b57cec5SDimitry Andric // constant pool users. 394*0b57cec5SDimitry Andric initializeFunctionInfo(CPEMIs); 395*0b57cec5SDimitry Andric CPEMIs.clear(); 396*0b57cec5SDimitry Andric LLVM_DEBUG(dumpBBs()); 397*0b57cec5SDimitry Andric 398*0b57cec5SDimitry Andric // Functions with jump tables need an alignment of 4 because they use the ADR 399*0b57cec5SDimitry Andric // instruction, which aligns the PC to 4 bytes before adding an offset. 400*0b57cec5SDimitry Andric if (!T2JumpTables.empty()) 401*0b57cec5SDimitry Andric MF->ensureAlignment(2); 402*0b57cec5SDimitry Andric 403*0b57cec5SDimitry Andric /// Remove dead constant pool entries. 404*0b57cec5SDimitry Andric MadeChange |= removeUnusedCPEntries(); 405*0b57cec5SDimitry Andric 406*0b57cec5SDimitry Andric // Iteratively place constant pool entries and fix up branches until there 407*0b57cec5SDimitry Andric // is no change. 408*0b57cec5SDimitry Andric unsigned NoCPIters = 0, NoBRIters = 0; 409*0b57cec5SDimitry Andric while (true) { 410*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Beginning CP iteration #" << NoCPIters << '\n'); 411*0b57cec5SDimitry Andric bool CPChange = false; 412*0b57cec5SDimitry Andric for (unsigned i = 0, e = CPUsers.size(); i != e; ++i) 413*0b57cec5SDimitry Andric // For most inputs, it converges in no more than 5 iterations. 414*0b57cec5SDimitry Andric // If it doesn't end in 10, the input may have huge BB or many CPEs. 415*0b57cec5SDimitry Andric // In this case, we will try different heuristics. 416*0b57cec5SDimitry Andric CPChange |= handleConstantPoolUser(i, NoCPIters >= CPMaxIteration / 2); 417*0b57cec5SDimitry Andric if (CPChange && ++NoCPIters > CPMaxIteration) 418*0b57cec5SDimitry Andric report_fatal_error("Constant Island pass failed to converge!"); 419*0b57cec5SDimitry Andric LLVM_DEBUG(dumpBBs()); 420*0b57cec5SDimitry Andric 421*0b57cec5SDimitry Andric // Clear NewWaterList now. If we split a block for branches, it should 422*0b57cec5SDimitry Andric // appear as "new water" for the next iteration of constant pool placement. 423*0b57cec5SDimitry Andric NewWaterList.clear(); 424*0b57cec5SDimitry Andric 425*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Beginning BR iteration #" << NoBRIters << '\n'); 426*0b57cec5SDimitry Andric bool BRChange = false; 427*0b57cec5SDimitry Andric for (unsigned i = 0, e = ImmBranches.size(); i != e; ++i) 428*0b57cec5SDimitry Andric BRChange |= fixupImmediateBr(ImmBranches[i]); 429*0b57cec5SDimitry Andric if (BRChange && ++NoBRIters > 30) 430*0b57cec5SDimitry Andric report_fatal_error("Branch Fix Up pass failed to converge!"); 431*0b57cec5SDimitry Andric LLVM_DEBUG(dumpBBs()); 432*0b57cec5SDimitry Andric 433*0b57cec5SDimitry Andric if (!CPChange && !BRChange) 434*0b57cec5SDimitry Andric break; 435*0b57cec5SDimitry Andric MadeChange = true; 436*0b57cec5SDimitry Andric } 437*0b57cec5SDimitry Andric 438*0b57cec5SDimitry Andric // Shrink 32-bit Thumb2 load and store instructions. 439*0b57cec5SDimitry Andric if (isThumb2 && !STI->prefers32BitThumb()) 440*0b57cec5SDimitry Andric MadeChange |= optimizeThumb2Instructions(); 441*0b57cec5SDimitry Andric 442*0b57cec5SDimitry Andric // Shrink 32-bit branch instructions. 443*0b57cec5SDimitry Andric if (isThumb && STI->hasV8MBaselineOps()) 444*0b57cec5SDimitry Andric MadeChange |= optimizeThumb2Branches(); 445*0b57cec5SDimitry Andric 446*0b57cec5SDimitry Andric // Optimize jump tables using TBB / TBH. 447*0b57cec5SDimitry Andric if (GenerateTBB && !STI->genExecuteOnly()) 448*0b57cec5SDimitry Andric MadeChange |= optimizeThumb2JumpTables(); 449*0b57cec5SDimitry Andric 450*0b57cec5SDimitry Andric // After a while, this might be made debug-only, but it is not expensive. 451*0b57cec5SDimitry Andric verify(); 452*0b57cec5SDimitry Andric 453*0b57cec5SDimitry Andric // If LR has been forced spilled and no far jump (i.e. BL) has been issued, 454*0b57cec5SDimitry Andric // undo the spill / restore of LR if possible. 455*0b57cec5SDimitry Andric if (isThumb && !HasFarJump && AFI->isLRSpilledForFarJump()) 456*0b57cec5SDimitry Andric MadeChange |= undoLRSpillRestore(); 457*0b57cec5SDimitry Andric 458*0b57cec5SDimitry Andric // Save the mapping between original and cloned constpool entries. 459*0b57cec5SDimitry Andric for (unsigned i = 0, e = CPEntries.size(); i != e; ++i) { 460*0b57cec5SDimitry Andric for (unsigned j = 0, je = CPEntries[i].size(); j != je; ++j) { 461*0b57cec5SDimitry Andric const CPEntry & CPE = CPEntries[i][j]; 462*0b57cec5SDimitry Andric if (CPE.CPEMI && CPE.CPEMI->getOperand(1).isCPI()) 463*0b57cec5SDimitry Andric AFI->recordCPEClone(i, CPE.CPI); 464*0b57cec5SDimitry Andric } 465*0b57cec5SDimitry Andric } 466*0b57cec5SDimitry Andric 467*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << '\n'; dumpBBs()); 468*0b57cec5SDimitry Andric 469*0b57cec5SDimitry Andric BBUtils->clear(); 470*0b57cec5SDimitry Andric WaterList.clear(); 471*0b57cec5SDimitry Andric CPUsers.clear(); 472*0b57cec5SDimitry Andric CPEntries.clear(); 473*0b57cec5SDimitry Andric JumpTableEntryIndices.clear(); 474*0b57cec5SDimitry Andric JumpTableUserIndices.clear(); 475*0b57cec5SDimitry Andric ImmBranches.clear(); 476*0b57cec5SDimitry Andric PushPopMIs.clear(); 477*0b57cec5SDimitry Andric T2JumpTables.clear(); 478*0b57cec5SDimitry Andric 479*0b57cec5SDimitry Andric return MadeChange; 480*0b57cec5SDimitry Andric } 481*0b57cec5SDimitry Andric 482*0b57cec5SDimitry Andric /// Perform the initial placement of the regular constant pool entries. 483*0b57cec5SDimitry Andric /// To start with, we put them all at the end of the function. 484*0b57cec5SDimitry Andric void 485*0b57cec5SDimitry Andric ARMConstantIslands::doInitialConstPlacement(std::vector<MachineInstr*> &CPEMIs) { 486*0b57cec5SDimitry Andric // Create the basic block to hold the CPE's. 487*0b57cec5SDimitry Andric MachineBasicBlock *BB = MF->CreateMachineBasicBlock(); 488*0b57cec5SDimitry Andric MF->push_back(BB); 489*0b57cec5SDimitry Andric 490*0b57cec5SDimitry Andric // MachineConstantPool measures alignment in bytes. We measure in log2(bytes). 491*0b57cec5SDimitry Andric unsigned MaxAlign = Log2_32(MCP->getConstantPoolAlignment()); 492*0b57cec5SDimitry Andric 493*0b57cec5SDimitry Andric // Mark the basic block as required by the const-pool. 494*0b57cec5SDimitry Andric BB->setAlignment(MaxAlign); 495*0b57cec5SDimitry Andric 496*0b57cec5SDimitry Andric // The function needs to be as aligned as the basic blocks. The linker may 497*0b57cec5SDimitry Andric // move functions around based on their alignment. 498*0b57cec5SDimitry Andric MF->ensureAlignment(BB->getAlignment()); 499*0b57cec5SDimitry Andric 500*0b57cec5SDimitry Andric // Order the entries in BB by descending alignment. That ensures correct 501*0b57cec5SDimitry Andric // alignment of all entries as long as BB is sufficiently aligned. Keep 502*0b57cec5SDimitry Andric // track of the insertion point for each alignment. We are going to bucket 503*0b57cec5SDimitry Andric // sort the entries as they are created. 504*0b57cec5SDimitry Andric SmallVector<MachineBasicBlock::iterator, 8> InsPoint(MaxAlign + 1, BB->end()); 505*0b57cec5SDimitry Andric 506*0b57cec5SDimitry Andric // Add all of the constants from the constant pool to the end block, use an 507*0b57cec5SDimitry Andric // identity mapping of CPI's to CPE's. 508*0b57cec5SDimitry Andric const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants(); 509*0b57cec5SDimitry Andric 510*0b57cec5SDimitry Andric const DataLayout &TD = MF->getDataLayout(); 511*0b57cec5SDimitry Andric for (unsigned i = 0, e = CPs.size(); i != e; ++i) { 512*0b57cec5SDimitry Andric unsigned Size = TD.getTypeAllocSize(CPs[i].getType()); 513*0b57cec5SDimitry Andric unsigned Align = CPs[i].getAlignment(); 514*0b57cec5SDimitry Andric assert(isPowerOf2_32(Align) && "Invalid alignment"); 515*0b57cec5SDimitry Andric // Verify that all constant pool entries are a multiple of their alignment. 516*0b57cec5SDimitry Andric // If not, we would have to pad them out so that instructions stay aligned. 517*0b57cec5SDimitry Andric assert((Size % Align) == 0 && "CP Entry not multiple of 4 bytes!"); 518*0b57cec5SDimitry Andric 519*0b57cec5SDimitry Andric // Insert CONSTPOOL_ENTRY before entries with a smaller alignment. 520*0b57cec5SDimitry Andric unsigned LogAlign = Log2_32(Align); 521*0b57cec5SDimitry Andric MachineBasicBlock::iterator InsAt = InsPoint[LogAlign]; 522*0b57cec5SDimitry Andric MachineInstr *CPEMI = 523*0b57cec5SDimitry Andric BuildMI(*BB, InsAt, DebugLoc(), TII->get(ARM::CONSTPOOL_ENTRY)) 524*0b57cec5SDimitry Andric .addImm(i).addConstantPoolIndex(i).addImm(Size); 525*0b57cec5SDimitry Andric CPEMIs.push_back(CPEMI); 526*0b57cec5SDimitry Andric 527*0b57cec5SDimitry Andric // Ensure that future entries with higher alignment get inserted before 528*0b57cec5SDimitry Andric // CPEMI. This is bucket sort with iterators. 529*0b57cec5SDimitry Andric for (unsigned a = LogAlign + 1; a <= MaxAlign; ++a) 530*0b57cec5SDimitry Andric if (InsPoint[a] == InsAt) 531*0b57cec5SDimitry Andric InsPoint[a] = CPEMI; 532*0b57cec5SDimitry Andric 533*0b57cec5SDimitry Andric // Add a new CPEntry, but no corresponding CPUser yet. 534*0b57cec5SDimitry Andric CPEntries.emplace_back(1, CPEntry(CPEMI, i)); 535*0b57cec5SDimitry Andric ++NumCPEs; 536*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Moved CPI#" << i << " to end of function, size = " 537*0b57cec5SDimitry Andric << Size << ", align = " << Align << '\n'); 538*0b57cec5SDimitry Andric } 539*0b57cec5SDimitry Andric LLVM_DEBUG(BB->dump()); 540*0b57cec5SDimitry Andric } 541*0b57cec5SDimitry Andric 542*0b57cec5SDimitry Andric /// Do initial placement of the jump tables. Because Thumb2's TBB and TBH 543*0b57cec5SDimitry Andric /// instructions can be made more efficient if the jump table immediately 544*0b57cec5SDimitry Andric /// follows the instruction, it's best to place them immediately next to their 545*0b57cec5SDimitry Andric /// jumps to begin with. In almost all cases they'll never be moved from that 546*0b57cec5SDimitry Andric /// position. 547*0b57cec5SDimitry Andric void ARMConstantIslands::doInitialJumpTablePlacement( 548*0b57cec5SDimitry Andric std::vector<MachineInstr *> &CPEMIs) { 549*0b57cec5SDimitry Andric unsigned i = CPEntries.size(); 550*0b57cec5SDimitry Andric auto MJTI = MF->getJumpTableInfo(); 551*0b57cec5SDimitry Andric const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 552*0b57cec5SDimitry Andric 553*0b57cec5SDimitry Andric MachineBasicBlock *LastCorrectlyNumberedBB = nullptr; 554*0b57cec5SDimitry Andric for (MachineBasicBlock &MBB : *MF) { 555*0b57cec5SDimitry Andric auto MI = MBB.getLastNonDebugInstr(); 556*0b57cec5SDimitry Andric if (MI == MBB.end()) 557*0b57cec5SDimitry Andric continue; 558*0b57cec5SDimitry Andric 559*0b57cec5SDimitry Andric unsigned JTOpcode; 560*0b57cec5SDimitry Andric switch (MI->getOpcode()) { 561*0b57cec5SDimitry Andric default: 562*0b57cec5SDimitry Andric continue; 563*0b57cec5SDimitry Andric case ARM::BR_JTadd: 564*0b57cec5SDimitry Andric case ARM::BR_JTr: 565*0b57cec5SDimitry Andric case ARM::tBR_JTr: 566*0b57cec5SDimitry Andric case ARM::BR_JTm_i12: 567*0b57cec5SDimitry Andric case ARM::BR_JTm_rs: 568*0b57cec5SDimitry Andric JTOpcode = ARM::JUMPTABLE_ADDRS; 569*0b57cec5SDimitry Andric break; 570*0b57cec5SDimitry Andric case ARM::t2BR_JT: 571*0b57cec5SDimitry Andric JTOpcode = ARM::JUMPTABLE_INSTS; 572*0b57cec5SDimitry Andric break; 573*0b57cec5SDimitry Andric case ARM::tTBB_JT: 574*0b57cec5SDimitry Andric case ARM::t2TBB_JT: 575*0b57cec5SDimitry Andric JTOpcode = ARM::JUMPTABLE_TBB; 576*0b57cec5SDimitry Andric break; 577*0b57cec5SDimitry Andric case ARM::tTBH_JT: 578*0b57cec5SDimitry Andric case ARM::t2TBH_JT: 579*0b57cec5SDimitry Andric JTOpcode = ARM::JUMPTABLE_TBH; 580*0b57cec5SDimitry Andric break; 581*0b57cec5SDimitry Andric } 582*0b57cec5SDimitry Andric 583*0b57cec5SDimitry Andric unsigned NumOps = MI->getDesc().getNumOperands(); 584*0b57cec5SDimitry Andric MachineOperand JTOp = 585*0b57cec5SDimitry Andric MI->getOperand(NumOps - (MI->isPredicable() ? 2 : 1)); 586*0b57cec5SDimitry Andric unsigned JTI = JTOp.getIndex(); 587*0b57cec5SDimitry Andric unsigned Size = JT[JTI].MBBs.size() * sizeof(uint32_t); 588*0b57cec5SDimitry Andric MachineBasicBlock *JumpTableBB = MF->CreateMachineBasicBlock(); 589*0b57cec5SDimitry Andric MF->insert(std::next(MachineFunction::iterator(MBB)), JumpTableBB); 590*0b57cec5SDimitry Andric MachineInstr *CPEMI = BuildMI(*JumpTableBB, JumpTableBB->begin(), 591*0b57cec5SDimitry Andric DebugLoc(), TII->get(JTOpcode)) 592*0b57cec5SDimitry Andric .addImm(i++) 593*0b57cec5SDimitry Andric .addJumpTableIndex(JTI) 594*0b57cec5SDimitry Andric .addImm(Size); 595*0b57cec5SDimitry Andric CPEMIs.push_back(CPEMI); 596*0b57cec5SDimitry Andric CPEntries.emplace_back(1, CPEntry(CPEMI, JTI)); 597*0b57cec5SDimitry Andric JumpTableEntryIndices.insert(std::make_pair(JTI, CPEntries.size() - 1)); 598*0b57cec5SDimitry Andric if (!LastCorrectlyNumberedBB) 599*0b57cec5SDimitry Andric LastCorrectlyNumberedBB = &MBB; 600*0b57cec5SDimitry Andric } 601*0b57cec5SDimitry Andric 602*0b57cec5SDimitry Andric // If we did anything then we need to renumber the subsequent blocks. 603*0b57cec5SDimitry Andric if (LastCorrectlyNumberedBB) 604*0b57cec5SDimitry Andric MF->RenumberBlocks(LastCorrectlyNumberedBB); 605*0b57cec5SDimitry Andric } 606*0b57cec5SDimitry Andric 607*0b57cec5SDimitry Andric /// BBHasFallthrough - Return true if the specified basic block can fallthrough 608*0b57cec5SDimitry Andric /// into the block immediately after it. 609*0b57cec5SDimitry Andric bool ARMConstantIslands::BBHasFallthrough(MachineBasicBlock *MBB) { 610*0b57cec5SDimitry Andric // Get the next machine basic block in the function. 611*0b57cec5SDimitry Andric MachineFunction::iterator MBBI = MBB->getIterator(); 612*0b57cec5SDimitry Andric // Can't fall off end of function. 613*0b57cec5SDimitry Andric if (std::next(MBBI) == MBB->getParent()->end()) 614*0b57cec5SDimitry Andric return false; 615*0b57cec5SDimitry Andric 616*0b57cec5SDimitry Andric MachineBasicBlock *NextBB = &*std::next(MBBI); 617*0b57cec5SDimitry Andric if (!MBB->isSuccessor(NextBB)) 618*0b57cec5SDimitry Andric return false; 619*0b57cec5SDimitry Andric 620*0b57cec5SDimitry Andric // Try to analyze the end of the block. A potential fallthrough may already 621*0b57cec5SDimitry Andric // have an unconditional branch for whatever reason. 622*0b57cec5SDimitry Andric MachineBasicBlock *TBB, *FBB; 623*0b57cec5SDimitry Andric SmallVector<MachineOperand, 4> Cond; 624*0b57cec5SDimitry Andric bool TooDifficult = TII->analyzeBranch(*MBB, TBB, FBB, Cond); 625*0b57cec5SDimitry Andric return TooDifficult || FBB == nullptr; 626*0b57cec5SDimitry Andric } 627*0b57cec5SDimitry Andric 628*0b57cec5SDimitry Andric /// findConstPoolEntry - Given the constpool index and CONSTPOOL_ENTRY MI, 629*0b57cec5SDimitry Andric /// look up the corresponding CPEntry. 630*0b57cec5SDimitry Andric ARMConstantIslands::CPEntry * 631*0b57cec5SDimitry Andric ARMConstantIslands::findConstPoolEntry(unsigned CPI, 632*0b57cec5SDimitry Andric const MachineInstr *CPEMI) { 633*0b57cec5SDimitry Andric std::vector<CPEntry> &CPEs = CPEntries[CPI]; 634*0b57cec5SDimitry Andric // Number of entries per constpool index should be small, just do a 635*0b57cec5SDimitry Andric // linear search. 636*0b57cec5SDimitry Andric for (unsigned i = 0, e = CPEs.size(); i != e; ++i) { 637*0b57cec5SDimitry Andric if (CPEs[i].CPEMI == CPEMI) 638*0b57cec5SDimitry Andric return &CPEs[i]; 639*0b57cec5SDimitry Andric } 640*0b57cec5SDimitry Andric return nullptr; 641*0b57cec5SDimitry Andric } 642*0b57cec5SDimitry Andric 643*0b57cec5SDimitry Andric /// getCPELogAlign - Returns the required alignment of the constant pool entry 644*0b57cec5SDimitry Andric /// represented by CPEMI. Alignment is measured in log2(bytes) units. 645*0b57cec5SDimitry Andric unsigned ARMConstantIslands::getCPELogAlign(const MachineInstr *CPEMI) { 646*0b57cec5SDimitry Andric switch (CPEMI->getOpcode()) { 647*0b57cec5SDimitry Andric case ARM::CONSTPOOL_ENTRY: 648*0b57cec5SDimitry Andric break; 649*0b57cec5SDimitry Andric case ARM::JUMPTABLE_TBB: 650*0b57cec5SDimitry Andric return isThumb1 ? 2 : 0; 651*0b57cec5SDimitry Andric case ARM::JUMPTABLE_TBH: 652*0b57cec5SDimitry Andric return isThumb1 ? 2 : 1; 653*0b57cec5SDimitry Andric case ARM::JUMPTABLE_INSTS: 654*0b57cec5SDimitry Andric return 1; 655*0b57cec5SDimitry Andric case ARM::JUMPTABLE_ADDRS: 656*0b57cec5SDimitry Andric return 2; 657*0b57cec5SDimitry Andric default: 658*0b57cec5SDimitry Andric llvm_unreachable("unknown constpool entry kind"); 659*0b57cec5SDimitry Andric } 660*0b57cec5SDimitry Andric 661*0b57cec5SDimitry Andric unsigned CPI = getCombinedIndex(CPEMI); 662*0b57cec5SDimitry Andric assert(CPI < MCP->getConstants().size() && "Invalid constant pool index."); 663*0b57cec5SDimitry Andric unsigned Align = MCP->getConstants()[CPI].getAlignment(); 664*0b57cec5SDimitry Andric assert(isPowerOf2_32(Align) && "Invalid CPE alignment"); 665*0b57cec5SDimitry Andric return Log2_32(Align); 666*0b57cec5SDimitry Andric } 667*0b57cec5SDimitry Andric 668*0b57cec5SDimitry Andric /// scanFunctionJumpTables - Do a scan of the function, building up 669*0b57cec5SDimitry Andric /// information about the sizes of each block and the locations of all 670*0b57cec5SDimitry Andric /// the jump tables. 671*0b57cec5SDimitry Andric void ARMConstantIslands::scanFunctionJumpTables() { 672*0b57cec5SDimitry Andric for (MachineBasicBlock &MBB : *MF) { 673*0b57cec5SDimitry Andric for (MachineInstr &I : MBB) 674*0b57cec5SDimitry Andric if (I.isBranch() && 675*0b57cec5SDimitry Andric (I.getOpcode() == ARM::t2BR_JT || I.getOpcode() == ARM::tBR_JTr)) 676*0b57cec5SDimitry Andric T2JumpTables.push_back(&I); 677*0b57cec5SDimitry Andric } 678*0b57cec5SDimitry Andric } 679*0b57cec5SDimitry Andric 680*0b57cec5SDimitry Andric /// initializeFunctionInfo - Do the initial scan of the function, building up 681*0b57cec5SDimitry Andric /// information about the sizes of each block, the location of all the water, 682*0b57cec5SDimitry Andric /// and finding all of the constant pool users. 683*0b57cec5SDimitry Andric void ARMConstantIslands:: 684*0b57cec5SDimitry Andric initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) { 685*0b57cec5SDimitry Andric 686*0b57cec5SDimitry Andric BBUtils->computeAllBlockSizes(); 687*0b57cec5SDimitry Andric BBInfoVector &BBInfo = BBUtils->getBBInfo(); 688*0b57cec5SDimitry Andric // The known bits of the entry block offset are determined by the function 689*0b57cec5SDimitry Andric // alignment. 690*0b57cec5SDimitry Andric BBInfo.front().KnownBits = MF->getAlignment(); 691*0b57cec5SDimitry Andric 692*0b57cec5SDimitry Andric // Compute block offsets and known bits. 693*0b57cec5SDimitry Andric BBUtils->adjustBBOffsetsAfter(&MF->front()); 694*0b57cec5SDimitry Andric 695*0b57cec5SDimitry Andric // Now go back through the instructions and build up our data structures. 696*0b57cec5SDimitry Andric for (MachineBasicBlock &MBB : *MF) { 697*0b57cec5SDimitry Andric // If this block doesn't fall through into the next MBB, then this is 698*0b57cec5SDimitry Andric // 'water' that a constant pool island could be placed. 699*0b57cec5SDimitry Andric if (!BBHasFallthrough(&MBB)) 700*0b57cec5SDimitry Andric WaterList.push_back(&MBB); 701*0b57cec5SDimitry Andric 702*0b57cec5SDimitry Andric for (MachineInstr &I : MBB) { 703*0b57cec5SDimitry Andric if (I.isDebugInstr()) 704*0b57cec5SDimitry Andric continue; 705*0b57cec5SDimitry Andric 706*0b57cec5SDimitry Andric unsigned Opc = I.getOpcode(); 707*0b57cec5SDimitry Andric if (I.isBranch()) { 708*0b57cec5SDimitry Andric bool isCond = false; 709*0b57cec5SDimitry Andric unsigned Bits = 0; 710*0b57cec5SDimitry Andric unsigned Scale = 1; 711*0b57cec5SDimitry Andric int UOpc = Opc; 712*0b57cec5SDimitry Andric switch (Opc) { 713*0b57cec5SDimitry Andric default: 714*0b57cec5SDimitry Andric continue; // Ignore other JT branches 715*0b57cec5SDimitry Andric case ARM::t2BR_JT: 716*0b57cec5SDimitry Andric case ARM::tBR_JTr: 717*0b57cec5SDimitry Andric T2JumpTables.push_back(&I); 718*0b57cec5SDimitry Andric continue; // Does not get an entry in ImmBranches 719*0b57cec5SDimitry Andric case ARM::Bcc: 720*0b57cec5SDimitry Andric isCond = true; 721*0b57cec5SDimitry Andric UOpc = ARM::B; 722*0b57cec5SDimitry Andric LLVM_FALLTHROUGH; 723*0b57cec5SDimitry Andric case ARM::B: 724*0b57cec5SDimitry Andric Bits = 24; 725*0b57cec5SDimitry Andric Scale = 4; 726*0b57cec5SDimitry Andric break; 727*0b57cec5SDimitry Andric case ARM::tBcc: 728*0b57cec5SDimitry Andric isCond = true; 729*0b57cec5SDimitry Andric UOpc = ARM::tB; 730*0b57cec5SDimitry Andric Bits = 8; 731*0b57cec5SDimitry Andric Scale = 2; 732*0b57cec5SDimitry Andric break; 733*0b57cec5SDimitry Andric case ARM::tB: 734*0b57cec5SDimitry Andric Bits = 11; 735*0b57cec5SDimitry Andric Scale = 2; 736*0b57cec5SDimitry Andric break; 737*0b57cec5SDimitry Andric case ARM::t2Bcc: 738*0b57cec5SDimitry Andric isCond = true; 739*0b57cec5SDimitry Andric UOpc = ARM::t2B; 740*0b57cec5SDimitry Andric Bits = 20; 741*0b57cec5SDimitry Andric Scale = 2; 742*0b57cec5SDimitry Andric break; 743*0b57cec5SDimitry Andric case ARM::t2B: 744*0b57cec5SDimitry Andric Bits = 24; 745*0b57cec5SDimitry Andric Scale = 2; 746*0b57cec5SDimitry Andric break; 747*0b57cec5SDimitry Andric } 748*0b57cec5SDimitry Andric 749*0b57cec5SDimitry Andric // Record this immediate branch. 750*0b57cec5SDimitry Andric unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale; 751*0b57cec5SDimitry Andric ImmBranches.push_back(ImmBranch(&I, MaxOffs, isCond, UOpc)); 752*0b57cec5SDimitry Andric } 753*0b57cec5SDimitry Andric 754*0b57cec5SDimitry Andric if (Opc == ARM::tPUSH || Opc == ARM::tPOP_RET) 755*0b57cec5SDimitry Andric PushPopMIs.push_back(&I); 756*0b57cec5SDimitry Andric 757*0b57cec5SDimitry Andric if (Opc == ARM::CONSTPOOL_ENTRY || Opc == ARM::JUMPTABLE_ADDRS || 758*0b57cec5SDimitry Andric Opc == ARM::JUMPTABLE_INSTS || Opc == ARM::JUMPTABLE_TBB || 759*0b57cec5SDimitry Andric Opc == ARM::JUMPTABLE_TBH) 760*0b57cec5SDimitry Andric continue; 761*0b57cec5SDimitry Andric 762*0b57cec5SDimitry Andric // Scan the instructions for constant pool operands. 763*0b57cec5SDimitry Andric for (unsigned op = 0, e = I.getNumOperands(); op != e; ++op) 764*0b57cec5SDimitry Andric if (I.getOperand(op).isCPI() || I.getOperand(op).isJTI()) { 765*0b57cec5SDimitry Andric // We found one. The addressing mode tells us the max displacement 766*0b57cec5SDimitry Andric // from the PC that this instruction permits. 767*0b57cec5SDimitry Andric 768*0b57cec5SDimitry Andric // Basic size info comes from the TSFlags field. 769*0b57cec5SDimitry Andric unsigned Bits = 0; 770*0b57cec5SDimitry Andric unsigned Scale = 1; 771*0b57cec5SDimitry Andric bool NegOk = false; 772*0b57cec5SDimitry Andric bool IsSoImm = false; 773*0b57cec5SDimitry Andric 774*0b57cec5SDimitry Andric switch (Opc) { 775*0b57cec5SDimitry Andric default: 776*0b57cec5SDimitry Andric llvm_unreachable("Unknown addressing mode for CP reference!"); 777*0b57cec5SDimitry Andric 778*0b57cec5SDimitry Andric // Taking the address of a CP entry. 779*0b57cec5SDimitry Andric case ARM::LEApcrel: 780*0b57cec5SDimitry Andric case ARM::LEApcrelJT: 781*0b57cec5SDimitry Andric // This takes a SoImm, which is 8 bit immediate rotated. We'll 782*0b57cec5SDimitry Andric // pretend the maximum offset is 255 * 4. Since each instruction 783*0b57cec5SDimitry Andric // 4 byte wide, this is always correct. We'll check for other 784*0b57cec5SDimitry Andric // displacements that fits in a SoImm as well. 785*0b57cec5SDimitry Andric Bits = 8; 786*0b57cec5SDimitry Andric Scale = 4; 787*0b57cec5SDimitry Andric NegOk = true; 788*0b57cec5SDimitry Andric IsSoImm = true; 789*0b57cec5SDimitry Andric break; 790*0b57cec5SDimitry Andric case ARM::t2LEApcrel: 791*0b57cec5SDimitry Andric case ARM::t2LEApcrelJT: 792*0b57cec5SDimitry Andric Bits = 12; 793*0b57cec5SDimitry Andric NegOk = true; 794*0b57cec5SDimitry Andric break; 795*0b57cec5SDimitry Andric case ARM::tLEApcrel: 796*0b57cec5SDimitry Andric case ARM::tLEApcrelJT: 797*0b57cec5SDimitry Andric Bits = 8; 798*0b57cec5SDimitry Andric Scale = 4; 799*0b57cec5SDimitry Andric break; 800*0b57cec5SDimitry Andric 801*0b57cec5SDimitry Andric case ARM::LDRBi12: 802*0b57cec5SDimitry Andric case ARM::LDRi12: 803*0b57cec5SDimitry Andric case ARM::LDRcp: 804*0b57cec5SDimitry Andric case ARM::t2LDRpci: 805*0b57cec5SDimitry Andric case ARM::t2LDRHpci: 806*0b57cec5SDimitry Andric case ARM::t2LDRBpci: 807*0b57cec5SDimitry Andric Bits = 12; // +-offset_12 808*0b57cec5SDimitry Andric NegOk = true; 809*0b57cec5SDimitry Andric break; 810*0b57cec5SDimitry Andric 811*0b57cec5SDimitry Andric case ARM::tLDRpci: 812*0b57cec5SDimitry Andric Bits = 8; 813*0b57cec5SDimitry Andric Scale = 4; // +(offset_8*4) 814*0b57cec5SDimitry Andric break; 815*0b57cec5SDimitry Andric 816*0b57cec5SDimitry Andric case ARM::VLDRD: 817*0b57cec5SDimitry Andric case ARM::VLDRS: 818*0b57cec5SDimitry Andric Bits = 8; 819*0b57cec5SDimitry Andric Scale = 4; // +-(offset_8*4) 820*0b57cec5SDimitry Andric NegOk = true; 821*0b57cec5SDimitry Andric break; 822*0b57cec5SDimitry Andric case ARM::VLDRH: 823*0b57cec5SDimitry Andric Bits = 8; 824*0b57cec5SDimitry Andric Scale = 2; // +-(offset_8*2) 825*0b57cec5SDimitry Andric NegOk = true; 826*0b57cec5SDimitry Andric break; 827*0b57cec5SDimitry Andric 828*0b57cec5SDimitry Andric case ARM::tLDRHi: 829*0b57cec5SDimitry Andric Bits = 5; 830*0b57cec5SDimitry Andric Scale = 2; // +(offset_5*2) 831*0b57cec5SDimitry Andric break; 832*0b57cec5SDimitry Andric } 833*0b57cec5SDimitry Andric 834*0b57cec5SDimitry Andric // Remember that this is a user of a CP entry. 835*0b57cec5SDimitry Andric unsigned CPI = I.getOperand(op).getIndex(); 836*0b57cec5SDimitry Andric if (I.getOperand(op).isJTI()) { 837*0b57cec5SDimitry Andric JumpTableUserIndices.insert(std::make_pair(CPI, CPUsers.size())); 838*0b57cec5SDimitry Andric CPI = JumpTableEntryIndices[CPI]; 839*0b57cec5SDimitry Andric } 840*0b57cec5SDimitry Andric 841*0b57cec5SDimitry Andric MachineInstr *CPEMI = CPEMIs[CPI]; 842*0b57cec5SDimitry Andric unsigned MaxOffs = ((1 << Bits)-1) * Scale; 843*0b57cec5SDimitry Andric CPUsers.push_back(CPUser(&I, CPEMI, MaxOffs, NegOk, IsSoImm)); 844*0b57cec5SDimitry Andric 845*0b57cec5SDimitry Andric // Increment corresponding CPEntry reference count. 846*0b57cec5SDimitry Andric CPEntry *CPE = findConstPoolEntry(CPI, CPEMI); 847*0b57cec5SDimitry Andric assert(CPE && "Cannot find a corresponding CPEntry!"); 848*0b57cec5SDimitry Andric CPE->RefCount++; 849*0b57cec5SDimitry Andric 850*0b57cec5SDimitry Andric // Instructions can only use one CP entry, don't bother scanning the 851*0b57cec5SDimitry Andric // rest of the operands. 852*0b57cec5SDimitry Andric break; 853*0b57cec5SDimitry Andric } 854*0b57cec5SDimitry Andric } 855*0b57cec5SDimitry Andric } 856*0b57cec5SDimitry Andric } 857*0b57cec5SDimitry Andric 858*0b57cec5SDimitry Andric /// CompareMBBNumbers - Little predicate function to sort the WaterList by MBB 859*0b57cec5SDimitry Andric /// ID. 860*0b57cec5SDimitry Andric static bool CompareMBBNumbers(const MachineBasicBlock *LHS, 861*0b57cec5SDimitry Andric const MachineBasicBlock *RHS) { 862*0b57cec5SDimitry Andric return LHS->getNumber() < RHS->getNumber(); 863*0b57cec5SDimitry Andric } 864*0b57cec5SDimitry Andric 865*0b57cec5SDimitry Andric /// updateForInsertedWaterBlock - When a block is newly inserted into the 866*0b57cec5SDimitry Andric /// machine function, it upsets all of the block numbers. Renumber the blocks 867*0b57cec5SDimitry Andric /// and update the arrays that parallel this numbering. 868*0b57cec5SDimitry Andric void ARMConstantIslands::updateForInsertedWaterBlock(MachineBasicBlock *NewBB) { 869*0b57cec5SDimitry Andric // Renumber the MBB's to keep them consecutive. 870*0b57cec5SDimitry Andric NewBB->getParent()->RenumberBlocks(NewBB); 871*0b57cec5SDimitry Andric 872*0b57cec5SDimitry Andric // Insert an entry into BBInfo to align it properly with the (newly 873*0b57cec5SDimitry Andric // renumbered) block numbers. 874*0b57cec5SDimitry Andric BBUtils->insert(NewBB->getNumber(), BasicBlockInfo()); 875*0b57cec5SDimitry Andric 876*0b57cec5SDimitry Andric // Next, update WaterList. Specifically, we need to add NewMBB as having 877*0b57cec5SDimitry Andric // available water after it. 878*0b57cec5SDimitry Andric water_iterator IP = llvm::lower_bound(WaterList, NewBB, CompareMBBNumbers); 879*0b57cec5SDimitry Andric WaterList.insert(IP, NewBB); 880*0b57cec5SDimitry Andric } 881*0b57cec5SDimitry Andric 882*0b57cec5SDimitry Andric /// Split the basic block containing MI into two blocks, which are joined by 883*0b57cec5SDimitry Andric /// an unconditional branch. Update data structures and renumber blocks to 884*0b57cec5SDimitry Andric /// account for this change and returns the newly created block. 885*0b57cec5SDimitry Andric MachineBasicBlock *ARMConstantIslands::splitBlockBeforeInstr(MachineInstr *MI) { 886*0b57cec5SDimitry Andric MachineBasicBlock *OrigBB = MI->getParent(); 887*0b57cec5SDimitry Andric 888*0b57cec5SDimitry Andric // Create a new MBB for the code after the OrigBB. 889*0b57cec5SDimitry Andric MachineBasicBlock *NewBB = 890*0b57cec5SDimitry Andric MF->CreateMachineBasicBlock(OrigBB->getBasicBlock()); 891*0b57cec5SDimitry Andric MachineFunction::iterator MBBI = ++OrigBB->getIterator(); 892*0b57cec5SDimitry Andric MF->insert(MBBI, NewBB); 893*0b57cec5SDimitry Andric 894*0b57cec5SDimitry Andric // Splice the instructions starting with MI over to NewBB. 895*0b57cec5SDimitry Andric NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end()); 896*0b57cec5SDimitry Andric 897*0b57cec5SDimitry Andric // Add an unconditional branch from OrigBB to NewBB. 898*0b57cec5SDimitry Andric // Note the new unconditional branch is not being recorded. 899*0b57cec5SDimitry Andric // There doesn't seem to be meaningful DebugInfo available; this doesn't 900*0b57cec5SDimitry Andric // correspond to anything in the source. 901*0b57cec5SDimitry Andric unsigned Opc = isThumb ? (isThumb2 ? ARM::t2B : ARM::tB) : ARM::B; 902*0b57cec5SDimitry Andric if (!isThumb) 903*0b57cec5SDimitry Andric BuildMI(OrigBB, DebugLoc(), TII->get(Opc)).addMBB(NewBB); 904*0b57cec5SDimitry Andric else 905*0b57cec5SDimitry Andric BuildMI(OrigBB, DebugLoc(), TII->get(Opc)) 906*0b57cec5SDimitry Andric .addMBB(NewBB) 907*0b57cec5SDimitry Andric .add(predOps(ARMCC::AL)); 908*0b57cec5SDimitry Andric ++NumSplit; 909*0b57cec5SDimitry Andric 910*0b57cec5SDimitry Andric // Update the CFG. All succs of OrigBB are now succs of NewBB. 911*0b57cec5SDimitry Andric NewBB->transferSuccessors(OrigBB); 912*0b57cec5SDimitry Andric 913*0b57cec5SDimitry Andric // OrigBB branches to NewBB. 914*0b57cec5SDimitry Andric OrigBB->addSuccessor(NewBB); 915*0b57cec5SDimitry Andric 916*0b57cec5SDimitry Andric // Update internal data structures to account for the newly inserted MBB. 917*0b57cec5SDimitry Andric // This is almost the same as updateForInsertedWaterBlock, except that 918*0b57cec5SDimitry Andric // the Water goes after OrigBB, not NewBB. 919*0b57cec5SDimitry Andric MF->RenumberBlocks(NewBB); 920*0b57cec5SDimitry Andric 921*0b57cec5SDimitry Andric // Insert an entry into BBInfo to align it properly with the (newly 922*0b57cec5SDimitry Andric // renumbered) block numbers. 923*0b57cec5SDimitry Andric BBUtils->insert(NewBB->getNumber(), BasicBlockInfo()); 924*0b57cec5SDimitry Andric 925*0b57cec5SDimitry Andric // Next, update WaterList. Specifically, we need to add OrigMBB as having 926*0b57cec5SDimitry Andric // available water after it (but not if it's already there, which happens 927*0b57cec5SDimitry Andric // when splitting before a conditional branch that is followed by an 928*0b57cec5SDimitry Andric // unconditional branch - in that case we want to insert NewBB). 929*0b57cec5SDimitry Andric water_iterator IP = llvm::lower_bound(WaterList, OrigBB, CompareMBBNumbers); 930*0b57cec5SDimitry Andric MachineBasicBlock* WaterBB = *IP; 931*0b57cec5SDimitry Andric if (WaterBB == OrigBB) 932*0b57cec5SDimitry Andric WaterList.insert(std::next(IP), NewBB); 933*0b57cec5SDimitry Andric else 934*0b57cec5SDimitry Andric WaterList.insert(IP, OrigBB); 935*0b57cec5SDimitry Andric NewWaterList.insert(OrigBB); 936*0b57cec5SDimitry Andric 937*0b57cec5SDimitry Andric // Figure out how large the OrigBB is. As the first half of the original 938*0b57cec5SDimitry Andric // block, it cannot contain a tablejump. The size includes 939*0b57cec5SDimitry Andric // the new jump we added. (It should be possible to do this without 940*0b57cec5SDimitry Andric // recounting everything, but it's very confusing, and this is rarely 941*0b57cec5SDimitry Andric // executed.) 942*0b57cec5SDimitry Andric BBUtils->computeBlockSize(OrigBB); 943*0b57cec5SDimitry Andric 944*0b57cec5SDimitry Andric // Figure out how large the NewMBB is. As the second half of the original 945*0b57cec5SDimitry Andric // block, it may contain a tablejump. 946*0b57cec5SDimitry Andric BBUtils->computeBlockSize(NewBB); 947*0b57cec5SDimitry Andric 948*0b57cec5SDimitry Andric // All BBOffsets following these blocks must be modified. 949*0b57cec5SDimitry Andric BBUtils->adjustBBOffsetsAfter(OrigBB); 950*0b57cec5SDimitry Andric 951*0b57cec5SDimitry Andric return NewBB; 952*0b57cec5SDimitry Andric } 953*0b57cec5SDimitry Andric 954*0b57cec5SDimitry Andric /// getUserOffset - Compute the offset of U.MI as seen by the hardware 955*0b57cec5SDimitry Andric /// displacement computation. Update U.KnownAlignment to match its current 956*0b57cec5SDimitry Andric /// basic block location. 957*0b57cec5SDimitry Andric unsigned ARMConstantIslands::getUserOffset(CPUser &U) const { 958*0b57cec5SDimitry Andric unsigned UserOffset = BBUtils->getOffsetOf(U.MI); 959*0b57cec5SDimitry Andric 960*0b57cec5SDimitry Andric SmallVectorImpl<BasicBlockInfo> &BBInfo = BBUtils->getBBInfo(); 961*0b57cec5SDimitry Andric const BasicBlockInfo &BBI = BBInfo[U.MI->getParent()->getNumber()]; 962*0b57cec5SDimitry Andric unsigned KnownBits = BBI.internalKnownBits(); 963*0b57cec5SDimitry Andric 964*0b57cec5SDimitry Andric // The value read from PC is offset from the actual instruction address. 965*0b57cec5SDimitry Andric UserOffset += (isThumb ? 4 : 8); 966*0b57cec5SDimitry Andric 967*0b57cec5SDimitry Andric // Because of inline assembly, we may not know the alignment (mod 4) of U.MI. 968*0b57cec5SDimitry Andric // Make sure U.getMaxDisp() returns a constrained range. 969*0b57cec5SDimitry Andric U.KnownAlignment = (KnownBits >= 2); 970*0b57cec5SDimitry Andric 971*0b57cec5SDimitry Andric // On Thumb, offsets==2 mod 4 are rounded down by the hardware for 972*0b57cec5SDimitry Andric // purposes of the displacement computation; compensate for that here. 973*0b57cec5SDimitry Andric // For unknown alignments, getMaxDisp() constrains the range instead. 974*0b57cec5SDimitry Andric if (isThumb && U.KnownAlignment) 975*0b57cec5SDimitry Andric UserOffset &= ~3u; 976*0b57cec5SDimitry Andric 977*0b57cec5SDimitry Andric return UserOffset; 978*0b57cec5SDimitry Andric } 979*0b57cec5SDimitry Andric 980*0b57cec5SDimitry Andric /// isOffsetInRange - Checks whether UserOffset (the location of a constant pool 981*0b57cec5SDimitry Andric /// reference) is within MaxDisp of TrialOffset (a proposed location of a 982*0b57cec5SDimitry Andric /// constant pool entry). 983*0b57cec5SDimitry Andric /// UserOffset is computed by getUserOffset above to include PC adjustments. If 984*0b57cec5SDimitry Andric /// the mod 4 alignment of UserOffset is not known, the uncertainty must be 985*0b57cec5SDimitry Andric /// subtracted from MaxDisp instead. CPUser::getMaxDisp() does that. 986*0b57cec5SDimitry Andric bool ARMConstantIslands::isOffsetInRange(unsigned UserOffset, 987*0b57cec5SDimitry Andric unsigned TrialOffset, unsigned MaxDisp, 988*0b57cec5SDimitry Andric bool NegativeOK, bool IsSoImm) { 989*0b57cec5SDimitry Andric if (UserOffset <= TrialOffset) { 990*0b57cec5SDimitry Andric // User before the Trial. 991*0b57cec5SDimitry Andric if (TrialOffset - UserOffset <= MaxDisp) 992*0b57cec5SDimitry Andric return true; 993*0b57cec5SDimitry Andric // FIXME: Make use full range of soimm values. 994*0b57cec5SDimitry Andric } else if (NegativeOK) { 995*0b57cec5SDimitry Andric if (UserOffset - TrialOffset <= MaxDisp) 996*0b57cec5SDimitry Andric return true; 997*0b57cec5SDimitry Andric // FIXME: Make use full range of soimm values. 998*0b57cec5SDimitry Andric } 999*0b57cec5SDimitry Andric return false; 1000*0b57cec5SDimitry Andric } 1001*0b57cec5SDimitry Andric 1002*0b57cec5SDimitry Andric /// isWaterInRange - Returns true if a CPE placed after the specified 1003*0b57cec5SDimitry Andric /// Water (a basic block) will be in range for the specific MI. 1004*0b57cec5SDimitry Andric /// 1005*0b57cec5SDimitry Andric /// Compute how much the function will grow by inserting a CPE after Water. 1006*0b57cec5SDimitry Andric bool ARMConstantIslands::isWaterInRange(unsigned UserOffset, 1007*0b57cec5SDimitry Andric MachineBasicBlock* Water, CPUser &U, 1008*0b57cec5SDimitry Andric unsigned &Growth) { 1009*0b57cec5SDimitry Andric BBInfoVector &BBInfo = BBUtils->getBBInfo(); 1010*0b57cec5SDimitry Andric unsigned CPELogAlign = getCPELogAlign(U.CPEMI); 1011*0b57cec5SDimitry Andric unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset(CPELogAlign); 1012*0b57cec5SDimitry Andric unsigned NextBlockOffset, NextBlockAlignment; 1013*0b57cec5SDimitry Andric MachineFunction::const_iterator NextBlock = Water->getIterator(); 1014*0b57cec5SDimitry Andric if (++NextBlock == MF->end()) { 1015*0b57cec5SDimitry Andric NextBlockOffset = BBInfo[Water->getNumber()].postOffset(); 1016*0b57cec5SDimitry Andric NextBlockAlignment = 0; 1017*0b57cec5SDimitry Andric } else { 1018*0b57cec5SDimitry Andric NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset; 1019*0b57cec5SDimitry Andric NextBlockAlignment = NextBlock->getAlignment(); 1020*0b57cec5SDimitry Andric } 1021*0b57cec5SDimitry Andric unsigned Size = U.CPEMI->getOperand(2).getImm(); 1022*0b57cec5SDimitry Andric unsigned CPEEnd = CPEOffset + Size; 1023*0b57cec5SDimitry Andric 1024*0b57cec5SDimitry Andric // The CPE may be able to hide in the alignment padding before the next 1025*0b57cec5SDimitry Andric // block. It may also cause more padding to be required if it is more aligned 1026*0b57cec5SDimitry Andric // that the next block. 1027*0b57cec5SDimitry Andric if (CPEEnd > NextBlockOffset) { 1028*0b57cec5SDimitry Andric Growth = CPEEnd - NextBlockOffset; 1029*0b57cec5SDimitry Andric // Compute the padding that would go at the end of the CPE to align the next 1030*0b57cec5SDimitry Andric // block. 1031*0b57cec5SDimitry Andric Growth += OffsetToAlignment(CPEEnd, 1ULL << NextBlockAlignment); 1032*0b57cec5SDimitry Andric 1033*0b57cec5SDimitry Andric // If the CPE is to be inserted before the instruction, that will raise 1034*0b57cec5SDimitry Andric // the offset of the instruction. Also account for unknown alignment padding 1035*0b57cec5SDimitry Andric // in blocks between CPE and the user. 1036*0b57cec5SDimitry Andric if (CPEOffset < UserOffset) 1037*0b57cec5SDimitry Andric UserOffset += Growth + UnknownPadding(MF->getAlignment(), CPELogAlign); 1038*0b57cec5SDimitry Andric } else 1039*0b57cec5SDimitry Andric // CPE fits in existing padding. 1040*0b57cec5SDimitry Andric Growth = 0; 1041*0b57cec5SDimitry Andric 1042*0b57cec5SDimitry Andric return isOffsetInRange(UserOffset, CPEOffset, U); 1043*0b57cec5SDimitry Andric } 1044*0b57cec5SDimitry Andric 1045*0b57cec5SDimitry Andric /// isCPEntryInRange - Returns true if the distance between specific MI and 1046*0b57cec5SDimitry Andric /// specific ConstPool entry instruction can fit in MI's displacement field. 1047*0b57cec5SDimitry Andric bool ARMConstantIslands::isCPEntryInRange(MachineInstr *MI, unsigned UserOffset, 1048*0b57cec5SDimitry Andric MachineInstr *CPEMI, unsigned MaxDisp, 1049*0b57cec5SDimitry Andric bool NegOk, bool DoDump) { 1050*0b57cec5SDimitry Andric unsigned CPEOffset = BBUtils->getOffsetOf(CPEMI); 1051*0b57cec5SDimitry Andric 1052*0b57cec5SDimitry Andric if (DoDump) { 1053*0b57cec5SDimitry Andric LLVM_DEBUG({ 1054*0b57cec5SDimitry Andric BBInfoVector &BBInfo = BBUtils->getBBInfo(); 1055*0b57cec5SDimitry Andric unsigned Block = MI->getParent()->getNumber(); 1056*0b57cec5SDimitry Andric const BasicBlockInfo &BBI = BBInfo[Block]; 1057*0b57cec5SDimitry Andric dbgs() << "User of CPE#" << CPEMI->getOperand(0).getImm() 1058*0b57cec5SDimitry Andric << " max delta=" << MaxDisp 1059*0b57cec5SDimitry Andric << format(" insn address=%#x", UserOffset) << " in " 1060*0b57cec5SDimitry Andric << printMBBReference(*MI->getParent()) << ": " 1061*0b57cec5SDimitry Andric << format("%#x-%x\t", BBI.Offset, BBI.postOffset()) << *MI 1062*0b57cec5SDimitry Andric << format("CPE address=%#x offset=%+d: ", CPEOffset, 1063*0b57cec5SDimitry Andric int(CPEOffset - UserOffset)); 1064*0b57cec5SDimitry Andric }); 1065*0b57cec5SDimitry Andric } 1066*0b57cec5SDimitry Andric 1067*0b57cec5SDimitry Andric return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk); 1068*0b57cec5SDimitry Andric } 1069*0b57cec5SDimitry Andric 1070*0b57cec5SDimitry Andric #ifndef NDEBUG 1071*0b57cec5SDimitry Andric /// BBIsJumpedOver - Return true of the specified basic block's only predecessor 1072*0b57cec5SDimitry Andric /// unconditionally branches to its only successor. 1073*0b57cec5SDimitry Andric static bool BBIsJumpedOver(MachineBasicBlock *MBB) { 1074*0b57cec5SDimitry Andric if (MBB->pred_size() != 1 || MBB->succ_size() != 1) 1075*0b57cec5SDimitry Andric return false; 1076*0b57cec5SDimitry Andric 1077*0b57cec5SDimitry Andric MachineBasicBlock *Succ = *MBB->succ_begin(); 1078*0b57cec5SDimitry Andric MachineBasicBlock *Pred = *MBB->pred_begin(); 1079*0b57cec5SDimitry Andric MachineInstr *PredMI = &Pred->back(); 1080*0b57cec5SDimitry Andric if (PredMI->getOpcode() == ARM::B || PredMI->getOpcode() == ARM::tB 1081*0b57cec5SDimitry Andric || PredMI->getOpcode() == ARM::t2B) 1082*0b57cec5SDimitry Andric return PredMI->getOperand(0).getMBB() == Succ; 1083*0b57cec5SDimitry Andric return false; 1084*0b57cec5SDimitry Andric } 1085*0b57cec5SDimitry Andric #endif // NDEBUG 1086*0b57cec5SDimitry Andric 1087*0b57cec5SDimitry Andric /// decrementCPEReferenceCount - find the constant pool entry with index CPI 1088*0b57cec5SDimitry Andric /// and instruction CPEMI, and decrement its refcount. If the refcount 1089*0b57cec5SDimitry Andric /// becomes 0 remove the entry and instruction. Returns true if we removed 1090*0b57cec5SDimitry Andric /// the entry, false if we didn't. 1091*0b57cec5SDimitry Andric bool ARMConstantIslands::decrementCPEReferenceCount(unsigned CPI, 1092*0b57cec5SDimitry Andric MachineInstr *CPEMI) { 1093*0b57cec5SDimitry Andric // Find the old entry. Eliminate it if it is no longer used. 1094*0b57cec5SDimitry Andric CPEntry *CPE = findConstPoolEntry(CPI, CPEMI); 1095*0b57cec5SDimitry Andric assert(CPE && "Unexpected!"); 1096*0b57cec5SDimitry Andric if (--CPE->RefCount == 0) { 1097*0b57cec5SDimitry Andric removeDeadCPEMI(CPEMI); 1098*0b57cec5SDimitry Andric CPE->CPEMI = nullptr; 1099*0b57cec5SDimitry Andric --NumCPEs; 1100*0b57cec5SDimitry Andric return true; 1101*0b57cec5SDimitry Andric } 1102*0b57cec5SDimitry Andric return false; 1103*0b57cec5SDimitry Andric } 1104*0b57cec5SDimitry Andric 1105*0b57cec5SDimitry Andric unsigned ARMConstantIslands::getCombinedIndex(const MachineInstr *CPEMI) { 1106*0b57cec5SDimitry Andric if (CPEMI->getOperand(1).isCPI()) 1107*0b57cec5SDimitry Andric return CPEMI->getOperand(1).getIndex(); 1108*0b57cec5SDimitry Andric 1109*0b57cec5SDimitry Andric return JumpTableEntryIndices[CPEMI->getOperand(1).getIndex()]; 1110*0b57cec5SDimitry Andric } 1111*0b57cec5SDimitry Andric 1112*0b57cec5SDimitry Andric /// LookForCPEntryInRange - see if the currently referenced CPE is in range; 1113*0b57cec5SDimitry Andric /// if not, see if an in-range clone of the CPE is in range, and if so, 1114*0b57cec5SDimitry Andric /// change the data structures so the user references the clone. Returns: 1115*0b57cec5SDimitry Andric /// 0 = no existing entry found 1116*0b57cec5SDimitry Andric /// 1 = entry found, and there were no code insertions or deletions 1117*0b57cec5SDimitry Andric /// 2 = entry found, and there were code insertions or deletions 1118*0b57cec5SDimitry Andric int ARMConstantIslands::findInRangeCPEntry(CPUser& U, unsigned UserOffset) { 1119*0b57cec5SDimitry Andric MachineInstr *UserMI = U.MI; 1120*0b57cec5SDimitry Andric MachineInstr *CPEMI = U.CPEMI; 1121*0b57cec5SDimitry Andric 1122*0b57cec5SDimitry Andric // Check to see if the CPE is already in-range. 1123*0b57cec5SDimitry Andric if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk, 1124*0b57cec5SDimitry Andric true)) { 1125*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "In range\n"); 1126*0b57cec5SDimitry Andric return 1; 1127*0b57cec5SDimitry Andric } 1128*0b57cec5SDimitry Andric 1129*0b57cec5SDimitry Andric // No. Look for previously created clones of the CPE that are in range. 1130*0b57cec5SDimitry Andric unsigned CPI = getCombinedIndex(CPEMI); 1131*0b57cec5SDimitry Andric std::vector<CPEntry> &CPEs = CPEntries[CPI]; 1132*0b57cec5SDimitry Andric for (unsigned i = 0, e = CPEs.size(); i != e; ++i) { 1133*0b57cec5SDimitry Andric // We already tried this one 1134*0b57cec5SDimitry Andric if (CPEs[i].CPEMI == CPEMI) 1135*0b57cec5SDimitry Andric continue; 1136*0b57cec5SDimitry Andric // Removing CPEs can leave empty entries, skip 1137*0b57cec5SDimitry Andric if (CPEs[i].CPEMI == nullptr) 1138*0b57cec5SDimitry Andric continue; 1139*0b57cec5SDimitry Andric if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI, U.getMaxDisp(), 1140*0b57cec5SDimitry Andric U.NegOk)) { 1141*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#" 1142*0b57cec5SDimitry Andric << CPEs[i].CPI << "\n"); 1143*0b57cec5SDimitry Andric // Point the CPUser node to the replacement 1144*0b57cec5SDimitry Andric U.CPEMI = CPEs[i].CPEMI; 1145*0b57cec5SDimitry Andric // Change the CPI in the instruction operand to refer to the clone. 1146*0b57cec5SDimitry Andric for (unsigned j = 0, e = UserMI->getNumOperands(); j != e; ++j) 1147*0b57cec5SDimitry Andric if (UserMI->getOperand(j).isCPI()) { 1148*0b57cec5SDimitry Andric UserMI->getOperand(j).setIndex(CPEs[i].CPI); 1149*0b57cec5SDimitry Andric break; 1150*0b57cec5SDimitry Andric } 1151*0b57cec5SDimitry Andric // Adjust the refcount of the clone... 1152*0b57cec5SDimitry Andric CPEs[i].RefCount++; 1153*0b57cec5SDimitry Andric // ...and the original. If we didn't remove the old entry, none of the 1154*0b57cec5SDimitry Andric // addresses changed, so we don't need another pass. 1155*0b57cec5SDimitry Andric return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1; 1156*0b57cec5SDimitry Andric } 1157*0b57cec5SDimitry Andric } 1158*0b57cec5SDimitry Andric return 0; 1159*0b57cec5SDimitry Andric } 1160*0b57cec5SDimitry Andric 1161*0b57cec5SDimitry Andric /// getUnconditionalBrDisp - Returns the maximum displacement that can fit in 1162*0b57cec5SDimitry Andric /// the specific unconditional branch instruction. 1163*0b57cec5SDimitry Andric static inline unsigned getUnconditionalBrDisp(int Opc) { 1164*0b57cec5SDimitry Andric switch (Opc) { 1165*0b57cec5SDimitry Andric case ARM::tB: 1166*0b57cec5SDimitry Andric return ((1<<10)-1)*2; 1167*0b57cec5SDimitry Andric case ARM::t2B: 1168*0b57cec5SDimitry Andric return ((1<<23)-1)*2; 1169*0b57cec5SDimitry Andric default: 1170*0b57cec5SDimitry Andric break; 1171*0b57cec5SDimitry Andric } 1172*0b57cec5SDimitry Andric 1173*0b57cec5SDimitry Andric return ((1<<23)-1)*4; 1174*0b57cec5SDimitry Andric } 1175*0b57cec5SDimitry Andric 1176*0b57cec5SDimitry Andric /// findAvailableWater - Look for an existing entry in the WaterList in which 1177*0b57cec5SDimitry Andric /// we can place the CPE referenced from U so it's within range of U's MI. 1178*0b57cec5SDimitry Andric /// Returns true if found, false if not. If it returns true, WaterIter 1179*0b57cec5SDimitry Andric /// is set to the WaterList entry. For Thumb, prefer water that will not 1180*0b57cec5SDimitry Andric /// introduce padding to water that will. To ensure that this pass 1181*0b57cec5SDimitry Andric /// terminates, the CPE location for a particular CPUser is only allowed to 1182*0b57cec5SDimitry Andric /// move to a lower address, so search backward from the end of the list and 1183*0b57cec5SDimitry Andric /// prefer the first water that is in range. 1184*0b57cec5SDimitry Andric bool ARMConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset, 1185*0b57cec5SDimitry Andric water_iterator &WaterIter, 1186*0b57cec5SDimitry Andric bool CloserWater) { 1187*0b57cec5SDimitry Andric if (WaterList.empty()) 1188*0b57cec5SDimitry Andric return false; 1189*0b57cec5SDimitry Andric 1190*0b57cec5SDimitry Andric unsigned BestGrowth = ~0u; 1191*0b57cec5SDimitry Andric // The nearest water without splitting the UserBB is right after it. 1192*0b57cec5SDimitry Andric // If the distance is still large (we have a big BB), then we need to split it 1193*0b57cec5SDimitry Andric // if we don't converge after certain iterations. This helps the following 1194*0b57cec5SDimitry Andric // situation to converge: 1195*0b57cec5SDimitry Andric // BB0: 1196*0b57cec5SDimitry Andric // Big BB 1197*0b57cec5SDimitry Andric // BB1: 1198*0b57cec5SDimitry Andric // Constant Pool 1199*0b57cec5SDimitry Andric // When a CP access is out of range, BB0 may be used as water. However, 1200*0b57cec5SDimitry Andric // inserting islands between BB0 and BB1 makes other accesses out of range. 1201*0b57cec5SDimitry Andric MachineBasicBlock *UserBB = U.MI->getParent(); 1202*0b57cec5SDimitry Andric BBInfoVector &BBInfo = BBUtils->getBBInfo(); 1203*0b57cec5SDimitry Andric unsigned MinNoSplitDisp = 1204*0b57cec5SDimitry Andric BBInfo[UserBB->getNumber()].postOffset(getCPELogAlign(U.CPEMI)); 1205*0b57cec5SDimitry Andric if (CloserWater && MinNoSplitDisp > U.getMaxDisp() / 2) 1206*0b57cec5SDimitry Andric return false; 1207*0b57cec5SDimitry Andric for (water_iterator IP = std::prev(WaterList.end()), B = WaterList.begin();; 1208*0b57cec5SDimitry Andric --IP) { 1209*0b57cec5SDimitry Andric MachineBasicBlock* WaterBB = *IP; 1210*0b57cec5SDimitry Andric // Check if water is in range and is either at a lower address than the 1211*0b57cec5SDimitry Andric // current "high water mark" or a new water block that was created since 1212*0b57cec5SDimitry Andric // the previous iteration by inserting an unconditional branch. In the 1213*0b57cec5SDimitry Andric // latter case, we want to allow resetting the high water mark back to 1214*0b57cec5SDimitry Andric // this new water since we haven't seen it before. Inserting branches 1215*0b57cec5SDimitry Andric // should be relatively uncommon and when it does happen, we want to be 1216*0b57cec5SDimitry Andric // sure to take advantage of it for all the CPEs near that block, so that 1217*0b57cec5SDimitry Andric // we don't insert more branches than necessary. 1218*0b57cec5SDimitry Andric // When CloserWater is true, we try to find the lowest address after (or 1219*0b57cec5SDimitry Andric // equal to) user MI's BB no matter of padding growth. 1220*0b57cec5SDimitry Andric unsigned Growth; 1221*0b57cec5SDimitry Andric if (isWaterInRange(UserOffset, WaterBB, U, Growth) && 1222*0b57cec5SDimitry Andric (WaterBB->getNumber() < U.HighWaterMark->getNumber() || 1223*0b57cec5SDimitry Andric NewWaterList.count(WaterBB) || WaterBB == U.MI->getParent()) && 1224*0b57cec5SDimitry Andric Growth < BestGrowth) { 1225*0b57cec5SDimitry Andric // This is the least amount of required padding seen so far. 1226*0b57cec5SDimitry Andric BestGrowth = Growth; 1227*0b57cec5SDimitry Andric WaterIter = IP; 1228*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Found water after " << printMBBReference(*WaterBB) 1229*0b57cec5SDimitry Andric << " Growth=" << Growth << '\n'); 1230*0b57cec5SDimitry Andric 1231*0b57cec5SDimitry Andric if (CloserWater && WaterBB == U.MI->getParent()) 1232*0b57cec5SDimitry Andric return true; 1233*0b57cec5SDimitry Andric // Keep looking unless it is perfect and we're not looking for the lowest 1234*0b57cec5SDimitry Andric // possible address. 1235*0b57cec5SDimitry Andric if (!CloserWater && BestGrowth == 0) 1236*0b57cec5SDimitry Andric return true; 1237*0b57cec5SDimitry Andric } 1238*0b57cec5SDimitry Andric if (IP == B) 1239*0b57cec5SDimitry Andric break; 1240*0b57cec5SDimitry Andric } 1241*0b57cec5SDimitry Andric return BestGrowth != ~0u; 1242*0b57cec5SDimitry Andric } 1243*0b57cec5SDimitry Andric 1244*0b57cec5SDimitry Andric /// createNewWater - No existing WaterList entry will work for 1245*0b57cec5SDimitry Andric /// CPUsers[CPUserIndex], so create a place to put the CPE. The end of the 1246*0b57cec5SDimitry Andric /// block is used if in range, and the conditional branch munged so control 1247*0b57cec5SDimitry Andric /// flow is correct. Otherwise the block is split to create a hole with an 1248*0b57cec5SDimitry Andric /// unconditional branch around it. In either case NewMBB is set to a 1249*0b57cec5SDimitry Andric /// block following which the new island can be inserted (the WaterList 1250*0b57cec5SDimitry Andric /// is not adjusted). 1251*0b57cec5SDimitry Andric void ARMConstantIslands::createNewWater(unsigned CPUserIndex, 1252*0b57cec5SDimitry Andric unsigned UserOffset, 1253*0b57cec5SDimitry Andric MachineBasicBlock *&NewMBB) { 1254*0b57cec5SDimitry Andric CPUser &U = CPUsers[CPUserIndex]; 1255*0b57cec5SDimitry Andric MachineInstr *UserMI = U.MI; 1256*0b57cec5SDimitry Andric MachineInstr *CPEMI = U.CPEMI; 1257*0b57cec5SDimitry Andric unsigned CPELogAlign = getCPELogAlign(CPEMI); 1258*0b57cec5SDimitry Andric MachineBasicBlock *UserMBB = UserMI->getParent(); 1259*0b57cec5SDimitry Andric BBInfoVector &BBInfo = BBUtils->getBBInfo(); 1260*0b57cec5SDimitry Andric const BasicBlockInfo &UserBBI = BBInfo[UserMBB->getNumber()]; 1261*0b57cec5SDimitry Andric 1262*0b57cec5SDimitry Andric // If the block does not end in an unconditional branch already, and if the 1263*0b57cec5SDimitry Andric // end of the block is within range, make new water there. (The addition 1264*0b57cec5SDimitry Andric // below is for the unconditional branch we will be adding: 4 bytes on ARM + 1265*0b57cec5SDimitry Andric // Thumb2, 2 on Thumb1. 1266*0b57cec5SDimitry Andric if (BBHasFallthrough(UserMBB)) { 1267*0b57cec5SDimitry Andric // Size of branch to insert. 1268*0b57cec5SDimitry Andric unsigned Delta = isThumb1 ? 2 : 4; 1269*0b57cec5SDimitry Andric // Compute the offset where the CPE will begin. 1270*0b57cec5SDimitry Andric unsigned CPEOffset = UserBBI.postOffset(CPELogAlign) + Delta; 1271*0b57cec5SDimitry Andric 1272*0b57cec5SDimitry Andric if (isOffsetInRange(UserOffset, CPEOffset, U)) { 1273*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Split at end of " << printMBBReference(*UserMBB) 1274*0b57cec5SDimitry Andric << format(", expected CPE offset %#x\n", CPEOffset)); 1275*0b57cec5SDimitry Andric NewMBB = &*++UserMBB->getIterator(); 1276*0b57cec5SDimitry Andric // Add an unconditional branch from UserMBB to fallthrough block. Record 1277*0b57cec5SDimitry Andric // it for branch lengthening; this new branch will not get out of range, 1278*0b57cec5SDimitry Andric // but if the preceding conditional branch is out of range, the targets 1279*0b57cec5SDimitry Andric // will be exchanged, and the altered branch may be out of range, so the 1280*0b57cec5SDimitry Andric // machinery has to know about it. 1281*0b57cec5SDimitry Andric int UncondBr = isThumb ? ((isThumb2) ? ARM::t2B : ARM::tB) : ARM::B; 1282*0b57cec5SDimitry Andric if (!isThumb) 1283*0b57cec5SDimitry Andric BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB); 1284*0b57cec5SDimitry Andric else 1285*0b57cec5SDimitry Andric BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)) 1286*0b57cec5SDimitry Andric .addMBB(NewMBB) 1287*0b57cec5SDimitry Andric .add(predOps(ARMCC::AL)); 1288*0b57cec5SDimitry Andric unsigned MaxDisp = getUnconditionalBrDisp(UncondBr); 1289*0b57cec5SDimitry Andric ImmBranches.push_back(ImmBranch(&UserMBB->back(), 1290*0b57cec5SDimitry Andric MaxDisp, false, UncondBr)); 1291*0b57cec5SDimitry Andric BBUtils->computeBlockSize(UserMBB); 1292*0b57cec5SDimitry Andric BBUtils->adjustBBOffsetsAfter(UserMBB); 1293*0b57cec5SDimitry Andric return; 1294*0b57cec5SDimitry Andric } 1295*0b57cec5SDimitry Andric } 1296*0b57cec5SDimitry Andric 1297*0b57cec5SDimitry Andric // What a big block. Find a place within the block to split it. This is a 1298*0b57cec5SDimitry Andric // little tricky on Thumb1 since instructions are 2 bytes and constant pool 1299*0b57cec5SDimitry Andric // entries are 4 bytes: if instruction I references island CPE, and 1300*0b57cec5SDimitry Andric // instruction I+1 references CPE', it will not work well to put CPE as far 1301*0b57cec5SDimitry Andric // forward as possible, since then CPE' cannot immediately follow it (that 1302*0b57cec5SDimitry Andric // location is 2 bytes farther away from I+1 than CPE was from I) and we'd 1303*0b57cec5SDimitry Andric // need to create a new island. So, we make a first guess, then walk through 1304*0b57cec5SDimitry Andric // the instructions between the one currently being looked at and the 1305*0b57cec5SDimitry Andric // possible insertion point, and make sure any other instructions that 1306*0b57cec5SDimitry Andric // reference CPEs will be able to use the same island area; if not, we back 1307*0b57cec5SDimitry Andric // up the insertion point. 1308*0b57cec5SDimitry Andric 1309*0b57cec5SDimitry Andric // Try to split the block so it's fully aligned. Compute the latest split 1310*0b57cec5SDimitry Andric // point where we can add a 4-byte branch instruction, and then align to 1311*0b57cec5SDimitry Andric // LogAlign which is the largest possible alignment in the function. 1312*0b57cec5SDimitry Andric unsigned LogAlign = MF->getAlignment(); 1313*0b57cec5SDimitry Andric assert(LogAlign >= CPELogAlign && "Over-aligned constant pool entry"); 1314*0b57cec5SDimitry Andric unsigned KnownBits = UserBBI.internalKnownBits(); 1315*0b57cec5SDimitry Andric unsigned UPad = UnknownPadding(LogAlign, KnownBits); 1316*0b57cec5SDimitry Andric unsigned BaseInsertOffset = UserOffset + U.getMaxDisp() - UPad; 1317*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << format("Split in middle of big block before %#x", 1318*0b57cec5SDimitry Andric BaseInsertOffset)); 1319*0b57cec5SDimitry Andric 1320*0b57cec5SDimitry Andric // The 4 in the following is for the unconditional branch we'll be inserting 1321*0b57cec5SDimitry Andric // (allows for long branch on Thumb1). Alignment of the island is handled 1322*0b57cec5SDimitry Andric // inside isOffsetInRange. 1323*0b57cec5SDimitry Andric BaseInsertOffset -= 4; 1324*0b57cec5SDimitry Andric 1325*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << format(", adjusted to %#x", BaseInsertOffset) 1326*0b57cec5SDimitry Andric << " la=" << LogAlign << " kb=" << KnownBits 1327*0b57cec5SDimitry Andric << " up=" << UPad << '\n'); 1328*0b57cec5SDimitry Andric 1329*0b57cec5SDimitry Andric // This could point off the end of the block if we've already got constant 1330*0b57cec5SDimitry Andric // pool entries following this block; only the last one is in the water list. 1331*0b57cec5SDimitry Andric // Back past any possible branches (allow for a conditional and a maximally 1332*0b57cec5SDimitry Andric // long unconditional). 1333*0b57cec5SDimitry Andric if (BaseInsertOffset + 8 >= UserBBI.postOffset()) { 1334*0b57cec5SDimitry Andric // Ensure BaseInsertOffset is larger than the offset of the instruction 1335*0b57cec5SDimitry Andric // following UserMI so that the loop which searches for the split point 1336*0b57cec5SDimitry Andric // iterates at least once. 1337*0b57cec5SDimitry Andric BaseInsertOffset = 1338*0b57cec5SDimitry Andric std::max(UserBBI.postOffset() - UPad - 8, 1339*0b57cec5SDimitry Andric UserOffset + TII->getInstSizeInBytes(*UserMI) + 1); 1340*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << format("Move inside block: %#x\n", BaseInsertOffset)); 1341*0b57cec5SDimitry Andric } 1342*0b57cec5SDimitry Andric unsigned EndInsertOffset = BaseInsertOffset + 4 + UPad + 1343*0b57cec5SDimitry Andric CPEMI->getOperand(2).getImm(); 1344*0b57cec5SDimitry Andric MachineBasicBlock::iterator MI = UserMI; 1345*0b57cec5SDimitry Andric ++MI; 1346*0b57cec5SDimitry Andric unsigned CPUIndex = CPUserIndex+1; 1347*0b57cec5SDimitry Andric unsigned NumCPUsers = CPUsers.size(); 1348*0b57cec5SDimitry Andric MachineInstr *LastIT = nullptr; 1349*0b57cec5SDimitry Andric for (unsigned Offset = UserOffset + TII->getInstSizeInBytes(*UserMI); 1350*0b57cec5SDimitry Andric Offset < BaseInsertOffset; 1351*0b57cec5SDimitry Andric Offset += TII->getInstSizeInBytes(*MI), MI = std::next(MI)) { 1352*0b57cec5SDimitry Andric assert(MI != UserMBB->end() && "Fell off end of block"); 1353*0b57cec5SDimitry Andric if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == &*MI) { 1354*0b57cec5SDimitry Andric CPUser &U = CPUsers[CPUIndex]; 1355*0b57cec5SDimitry Andric if (!isOffsetInRange(Offset, EndInsertOffset, U)) { 1356*0b57cec5SDimitry Andric // Shift intertion point by one unit of alignment so it is within reach. 1357*0b57cec5SDimitry Andric BaseInsertOffset -= 1u << LogAlign; 1358*0b57cec5SDimitry Andric EndInsertOffset -= 1u << LogAlign; 1359*0b57cec5SDimitry Andric } 1360*0b57cec5SDimitry Andric // This is overly conservative, as we don't account for CPEMIs being 1361*0b57cec5SDimitry Andric // reused within the block, but it doesn't matter much. Also assume CPEs 1362*0b57cec5SDimitry Andric // are added in order with alignment padding. We may eventually be able 1363*0b57cec5SDimitry Andric // to pack the aligned CPEs better. 1364*0b57cec5SDimitry Andric EndInsertOffset += U.CPEMI->getOperand(2).getImm(); 1365*0b57cec5SDimitry Andric CPUIndex++; 1366*0b57cec5SDimitry Andric } 1367*0b57cec5SDimitry Andric 1368*0b57cec5SDimitry Andric // Remember the last IT instruction. 1369*0b57cec5SDimitry Andric if (MI->getOpcode() == ARM::t2IT) 1370*0b57cec5SDimitry Andric LastIT = &*MI; 1371*0b57cec5SDimitry Andric } 1372*0b57cec5SDimitry Andric 1373*0b57cec5SDimitry Andric --MI; 1374*0b57cec5SDimitry Andric 1375*0b57cec5SDimitry Andric // Avoid splitting an IT block. 1376*0b57cec5SDimitry Andric if (LastIT) { 1377*0b57cec5SDimitry Andric unsigned PredReg = 0; 1378*0b57cec5SDimitry Andric ARMCC::CondCodes CC = getITInstrPredicate(*MI, PredReg); 1379*0b57cec5SDimitry Andric if (CC != ARMCC::AL) 1380*0b57cec5SDimitry Andric MI = LastIT; 1381*0b57cec5SDimitry Andric } 1382*0b57cec5SDimitry Andric 1383*0b57cec5SDimitry Andric // Avoid splitting a MOVW+MOVT pair with a relocation on Windows. 1384*0b57cec5SDimitry Andric // On Windows, this instruction pair is covered by one single 1385*0b57cec5SDimitry Andric // IMAGE_REL_ARM_MOV32T relocation which covers both instructions. If a 1386*0b57cec5SDimitry Andric // constant island is injected inbetween them, the relocation will clobber 1387*0b57cec5SDimitry Andric // the instruction and fail to update the MOVT instruction. 1388*0b57cec5SDimitry Andric // (These instructions are bundled up until right before the ConstantIslands 1389*0b57cec5SDimitry Andric // pass.) 1390*0b57cec5SDimitry Andric if (STI->isTargetWindows() && isThumb && MI->getOpcode() == ARM::t2MOVTi16 && 1391*0b57cec5SDimitry Andric (MI->getOperand(2).getTargetFlags() & ARMII::MO_OPTION_MASK) == 1392*0b57cec5SDimitry Andric ARMII::MO_HI16) { 1393*0b57cec5SDimitry Andric --MI; 1394*0b57cec5SDimitry Andric assert(MI->getOpcode() == ARM::t2MOVi16 && 1395*0b57cec5SDimitry Andric (MI->getOperand(1).getTargetFlags() & ARMII::MO_OPTION_MASK) == 1396*0b57cec5SDimitry Andric ARMII::MO_LO16); 1397*0b57cec5SDimitry Andric } 1398*0b57cec5SDimitry Andric 1399*0b57cec5SDimitry Andric // We really must not split an IT block. 1400*0b57cec5SDimitry Andric LLVM_DEBUG(unsigned PredReg; assert( 1401*0b57cec5SDimitry Andric !isThumb || getITInstrPredicate(*MI, PredReg) == ARMCC::AL)); 1402*0b57cec5SDimitry Andric 1403*0b57cec5SDimitry Andric NewMBB = splitBlockBeforeInstr(&*MI); 1404*0b57cec5SDimitry Andric } 1405*0b57cec5SDimitry Andric 1406*0b57cec5SDimitry Andric /// handleConstantPoolUser - Analyze the specified user, checking to see if it 1407*0b57cec5SDimitry Andric /// is out-of-range. If so, pick up the constant pool value and move it some 1408*0b57cec5SDimitry Andric /// place in-range. Return true if we changed any addresses (thus must run 1409*0b57cec5SDimitry Andric /// another pass of branch lengthening), false otherwise. 1410*0b57cec5SDimitry Andric bool ARMConstantIslands::handleConstantPoolUser(unsigned CPUserIndex, 1411*0b57cec5SDimitry Andric bool CloserWater) { 1412*0b57cec5SDimitry Andric CPUser &U = CPUsers[CPUserIndex]; 1413*0b57cec5SDimitry Andric MachineInstr *UserMI = U.MI; 1414*0b57cec5SDimitry Andric MachineInstr *CPEMI = U.CPEMI; 1415*0b57cec5SDimitry Andric unsigned CPI = getCombinedIndex(CPEMI); 1416*0b57cec5SDimitry Andric unsigned Size = CPEMI->getOperand(2).getImm(); 1417*0b57cec5SDimitry Andric // Compute this only once, it's expensive. 1418*0b57cec5SDimitry Andric unsigned UserOffset = getUserOffset(U); 1419*0b57cec5SDimitry Andric 1420*0b57cec5SDimitry Andric // See if the current entry is within range, or there is a clone of it 1421*0b57cec5SDimitry Andric // in range. 1422*0b57cec5SDimitry Andric int result = findInRangeCPEntry(U, UserOffset); 1423*0b57cec5SDimitry Andric if (result==1) return false; 1424*0b57cec5SDimitry Andric else if (result==2) return true; 1425*0b57cec5SDimitry Andric 1426*0b57cec5SDimitry Andric // No existing clone of this CPE is within range. 1427*0b57cec5SDimitry Andric // We will be generating a new clone. Get a UID for it. 1428*0b57cec5SDimitry Andric unsigned ID = AFI->createPICLabelUId(); 1429*0b57cec5SDimitry Andric 1430*0b57cec5SDimitry Andric // Look for water where we can place this CPE. 1431*0b57cec5SDimitry Andric MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock(); 1432*0b57cec5SDimitry Andric MachineBasicBlock *NewMBB; 1433*0b57cec5SDimitry Andric water_iterator IP; 1434*0b57cec5SDimitry Andric if (findAvailableWater(U, UserOffset, IP, CloserWater)) { 1435*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Found water in range\n"); 1436*0b57cec5SDimitry Andric MachineBasicBlock *WaterBB = *IP; 1437*0b57cec5SDimitry Andric 1438*0b57cec5SDimitry Andric // If the original WaterList entry was "new water" on this iteration, 1439*0b57cec5SDimitry Andric // propagate that to the new island. This is just keeping NewWaterList 1440*0b57cec5SDimitry Andric // updated to match the WaterList, which will be updated below. 1441*0b57cec5SDimitry Andric if (NewWaterList.erase(WaterBB)) 1442*0b57cec5SDimitry Andric NewWaterList.insert(NewIsland); 1443*0b57cec5SDimitry Andric 1444*0b57cec5SDimitry Andric // The new CPE goes before the following block (NewMBB). 1445*0b57cec5SDimitry Andric NewMBB = &*++WaterBB->getIterator(); 1446*0b57cec5SDimitry Andric } else { 1447*0b57cec5SDimitry Andric // No water found. 1448*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "No water found\n"); 1449*0b57cec5SDimitry Andric createNewWater(CPUserIndex, UserOffset, NewMBB); 1450*0b57cec5SDimitry Andric 1451*0b57cec5SDimitry Andric // splitBlockBeforeInstr adds to WaterList, which is important when it is 1452*0b57cec5SDimitry Andric // called while handling branches so that the water will be seen on the 1453*0b57cec5SDimitry Andric // next iteration for constant pools, but in this context, we don't want 1454*0b57cec5SDimitry Andric // it. Check for this so it will be removed from the WaterList. 1455*0b57cec5SDimitry Andric // Also remove any entry from NewWaterList. 1456*0b57cec5SDimitry Andric MachineBasicBlock *WaterBB = &*--NewMBB->getIterator(); 1457*0b57cec5SDimitry Andric IP = find(WaterList, WaterBB); 1458*0b57cec5SDimitry Andric if (IP != WaterList.end()) 1459*0b57cec5SDimitry Andric NewWaterList.erase(WaterBB); 1460*0b57cec5SDimitry Andric 1461*0b57cec5SDimitry Andric // We are adding new water. Update NewWaterList. 1462*0b57cec5SDimitry Andric NewWaterList.insert(NewIsland); 1463*0b57cec5SDimitry Andric } 1464*0b57cec5SDimitry Andric // Always align the new block because CP entries can be smaller than 4 1465*0b57cec5SDimitry Andric // bytes. Be careful not to decrease the existing alignment, e.g. NewMBB may 1466*0b57cec5SDimitry Andric // be an already aligned constant pool block. 1467*0b57cec5SDimitry Andric const unsigned Align = isThumb ? 1 : 2; 1468*0b57cec5SDimitry Andric if (NewMBB->getAlignment() < Align) 1469*0b57cec5SDimitry Andric NewMBB->setAlignment(Align); 1470*0b57cec5SDimitry Andric 1471*0b57cec5SDimitry Andric // Remove the original WaterList entry; we want subsequent insertions in 1472*0b57cec5SDimitry Andric // this vicinity to go after the one we're about to insert. This 1473*0b57cec5SDimitry Andric // considerably reduces the number of times we have to move the same CPE 1474*0b57cec5SDimitry Andric // more than once and is also important to ensure the algorithm terminates. 1475*0b57cec5SDimitry Andric if (IP != WaterList.end()) 1476*0b57cec5SDimitry Andric WaterList.erase(IP); 1477*0b57cec5SDimitry Andric 1478*0b57cec5SDimitry Andric // Okay, we know we can put an island before NewMBB now, do it! 1479*0b57cec5SDimitry Andric MF->insert(NewMBB->getIterator(), NewIsland); 1480*0b57cec5SDimitry Andric 1481*0b57cec5SDimitry Andric // Update internal data structures to account for the newly inserted MBB. 1482*0b57cec5SDimitry Andric updateForInsertedWaterBlock(NewIsland); 1483*0b57cec5SDimitry Andric 1484*0b57cec5SDimitry Andric // Now that we have an island to add the CPE to, clone the original CPE and 1485*0b57cec5SDimitry Andric // add it to the island. 1486*0b57cec5SDimitry Andric U.HighWaterMark = NewIsland; 1487*0b57cec5SDimitry Andric U.CPEMI = BuildMI(NewIsland, DebugLoc(), CPEMI->getDesc()) 1488*0b57cec5SDimitry Andric .addImm(ID) 1489*0b57cec5SDimitry Andric .add(CPEMI->getOperand(1)) 1490*0b57cec5SDimitry Andric .addImm(Size); 1491*0b57cec5SDimitry Andric CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1)); 1492*0b57cec5SDimitry Andric ++NumCPEs; 1493*0b57cec5SDimitry Andric 1494*0b57cec5SDimitry Andric // Decrement the old entry, and remove it if refcount becomes 0. 1495*0b57cec5SDimitry Andric decrementCPEReferenceCount(CPI, CPEMI); 1496*0b57cec5SDimitry Andric 1497*0b57cec5SDimitry Andric // Mark the basic block as aligned as required by the const-pool entry. 1498*0b57cec5SDimitry Andric NewIsland->setAlignment(getCPELogAlign(U.CPEMI)); 1499*0b57cec5SDimitry Andric 1500*0b57cec5SDimitry Andric // Increase the size of the island block to account for the new entry. 1501*0b57cec5SDimitry Andric BBUtils->adjustBBSize(NewIsland, Size); 1502*0b57cec5SDimitry Andric BBUtils->adjustBBOffsetsAfter(&*--NewIsland->getIterator()); 1503*0b57cec5SDimitry Andric 1504*0b57cec5SDimitry Andric // Finally, change the CPI in the instruction operand to be ID. 1505*0b57cec5SDimitry Andric for (unsigned i = 0, e = UserMI->getNumOperands(); i != e; ++i) 1506*0b57cec5SDimitry Andric if (UserMI->getOperand(i).isCPI()) { 1507*0b57cec5SDimitry Andric UserMI->getOperand(i).setIndex(ID); 1508*0b57cec5SDimitry Andric break; 1509*0b57cec5SDimitry Andric } 1510*0b57cec5SDimitry Andric 1511*0b57cec5SDimitry Andric LLVM_DEBUG( 1512*0b57cec5SDimitry Andric dbgs() << " Moved CPE to #" << ID << " CPI=" << CPI 1513*0b57cec5SDimitry Andric << format(" offset=%#x\n", 1514*0b57cec5SDimitry Andric BBUtils->getBBInfo()[NewIsland->getNumber()].Offset)); 1515*0b57cec5SDimitry Andric 1516*0b57cec5SDimitry Andric return true; 1517*0b57cec5SDimitry Andric } 1518*0b57cec5SDimitry Andric 1519*0b57cec5SDimitry Andric /// removeDeadCPEMI - Remove a dead constant pool entry instruction. Update 1520*0b57cec5SDimitry Andric /// sizes and offsets of impacted basic blocks. 1521*0b57cec5SDimitry Andric void ARMConstantIslands::removeDeadCPEMI(MachineInstr *CPEMI) { 1522*0b57cec5SDimitry Andric MachineBasicBlock *CPEBB = CPEMI->getParent(); 1523*0b57cec5SDimitry Andric unsigned Size = CPEMI->getOperand(2).getImm(); 1524*0b57cec5SDimitry Andric CPEMI->eraseFromParent(); 1525*0b57cec5SDimitry Andric BBInfoVector &BBInfo = BBUtils->getBBInfo(); 1526*0b57cec5SDimitry Andric BBUtils->adjustBBSize(CPEBB, -Size); 1527*0b57cec5SDimitry Andric // All succeeding offsets have the current size value added in, fix this. 1528*0b57cec5SDimitry Andric if (CPEBB->empty()) { 1529*0b57cec5SDimitry Andric BBInfo[CPEBB->getNumber()].Size = 0; 1530*0b57cec5SDimitry Andric 1531*0b57cec5SDimitry Andric // This block no longer needs to be aligned. 1532*0b57cec5SDimitry Andric CPEBB->setAlignment(0); 1533*0b57cec5SDimitry Andric } else 1534*0b57cec5SDimitry Andric // Entries are sorted by descending alignment, so realign from the front. 1535*0b57cec5SDimitry Andric CPEBB->setAlignment(getCPELogAlign(&*CPEBB->begin())); 1536*0b57cec5SDimitry Andric 1537*0b57cec5SDimitry Andric BBUtils->adjustBBOffsetsAfter(CPEBB); 1538*0b57cec5SDimitry Andric // An island has only one predecessor BB and one successor BB. Check if 1539*0b57cec5SDimitry Andric // this BB's predecessor jumps directly to this BB's successor. This 1540*0b57cec5SDimitry Andric // shouldn't happen currently. 1541*0b57cec5SDimitry Andric assert(!BBIsJumpedOver(CPEBB) && "How did this happen?"); 1542*0b57cec5SDimitry Andric // FIXME: remove the empty blocks after all the work is done? 1543*0b57cec5SDimitry Andric } 1544*0b57cec5SDimitry Andric 1545*0b57cec5SDimitry Andric /// removeUnusedCPEntries - Remove constant pool entries whose refcounts 1546*0b57cec5SDimitry Andric /// are zero. 1547*0b57cec5SDimitry Andric bool ARMConstantIslands::removeUnusedCPEntries() { 1548*0b57cec5SDimitry Andric unsigned MadeChange = false; 1549*0b57cec5SDimitry Andric for (unsigned i = 0, e = CPEntries.size(); i != e; ++i) { 1550*0b57cec5SDimitry Andric std::vector<CPEntry> &CPEs = CPEntries[i]; 1551*0b57cec5SDimitry Andric for (unsigned j = 0, ee = CPEs.size(); j != ee; ++j) { 1552*0b57cec5SDimitry Andric if (CPEs[j].RefCount == 0 && CPEs[j].CPEMI) { 1553*0b57cec5SDimitry Andric removeDeadCPEMI(CPEs[j].CPEMI); 1554*0b57cec5SDimitry Andric CPEs[j].CPEMI = nullptr; 1555*0b57cec5SDimitry Andric MadeChange = true; 1556*0b57cec5SDimitry Andric } 1557*0b57cec5SDimitry Andric } 1558*0b57cec5SDimitry Andric } 1559*0b57cec5SDimitry Andric return MadeChange; 1560*0b57cec5SDimitry Andric } 1561*0b57cec5SDimitry Andric 1562*0b57cec5SDimitry Andric 1563*0b57cec5SDimitry Andric /// fixupImmediateBr - Fix up an immediate branch whose destination is too far 1564*0b57cec5SDimitry Andric /// away to fit in its displacement field. 1565*0b57cec5SDimitry Andric bool ARMConstantIslands::fixupImmediateBr(ImmBranch &Br) { 1566*0b57cec5SDimitry Andric MachineInstr *MI = Br.MI; 1567*0b57cec5SDimitry Andric MachineBasicBlock *DestBB = MI->getOperand(0).getMBB(); 1568*0b57cec5SDimitry Andric 1569*0b57cec5SDimitry Andric // Check to see if the DestBB is already in-range. 1570*0b57cec5SDimitry Andric if (BBUtils->isBBInRange(MI, DestBB, Br.MaxDisp)) 1571*0b57cec5SDimitry Andric return false; 1572*0b57cec5SDimitry Andric 1573*0b57cec5SDimitry Andric if (!Br.isCond) 1574*0b57cec5SDimitry Andric return fixupUnconditionalBr(Br); 1575*0b57cec5SDimitry Andric return fixupConditionalBr(Br); 1576*0b57cec5SDimitry Andric } 1577*0b57cec5SDimitry Andric 1578*0b57cec5SDimitry Andric /// fixupUnconditionalBr - Fix up an unconditional branch whose destination is 1579*0b57cec5SDimitry Andric /// too far away to fit in its displacement field. If the LR register has been 1580*0b57cec5SDimitry Andric /// spilled in the epilogue, then we can use BL to implement a far jump. 1581*0b57cec5SDimitry Andric /// Otherwise, add an intermediate branch instruction to a branch. 1582*0b57cec5SDimitry Andric bool 1583*0b57cec5SDimitry Andric ARMConstantIslands::fixupUnconditionalBr(ImmBranch &Br) { 1584*0b57cec5SDimitry Andric MachineInstr *MI = Br.MI; 1585*0b57cec5SDimitry Andric MachineBasicBlock *MBB = MI->getParent(); 1586*0b57cec5SDimitry Andric if (!isThumb1) 1587*0b57cec5SDimitry Andric llvm_unreachable("fixupUnconditionalBr is Thumb1 only!"); 1588*0b57cec5SDimitry Andric 1589*0b57cec5SDimitry Andric if (!AFI->isLRSpilled()) 1590*0b57cec5SDimitry Andric report_fatal_error("underestimated function size"); 1591*0b57cec5SDimitry Andric 1592*0b57cec5SDimitry Andric // Use BL to implement far jump. 1593*0b57cec5SDimitry Andric Br.MaxDisp = (1 << 21) * 2; 1594*0b57cec5SDimitry Andric MI->setDesc(TII->get(ARM::tBfar)); 1595*0b57cec5SDimitry Andric BBInfoVector &BBInfo = BBUtils->getBBInfo(); 1596*0b57cec5SDimitry Andric BBInfo[MBB->getNumber()].Size += 2; 1597*0b57cec5SDimitry Andric BBUtils->adjustBBOffsetsAfter(MBB); 1598*0b57cec5SDimitry Andric HasFarJump = true; 1599*0b57cec5SDimitry Andric ++NumUBrFixed; 1600*0b57cec5SDimitry Andric 1601*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Changed B to long jump " << *MI); 1602*0b57cec5SDimitry Andric 1603*0b57cec5SDimitry Andric return true; 1604*0b57cec5SDimitry Andric } 1605*0b57cec5SDimitry Andric 1606*0b57cec5SDimitry Andric /// fixupConditionalBr - Fix up a conditional branch whose destination is too 1607*0b57cec5SDimitry Andric /// far away to fit in its displacement field. It is converted to an inverse 1608*0b57cec5SDimitry Andric /// conditional branch + an unconditional branch to the destination. 1609*0b57cec5SDimitry Andric bool 1610*0b57cec5SDimitry Andric ARMConstantIslands::fixupConditionalBr(ImmBranch &Br) { 1611*0b57cec5SDimitry Andric MachineInstr *MI = Br.MI; 1612*0b57cec5SDimitry Andric MachineBasicBlock *DestBB = MI->getOperand(0).getMBB(); 1613*0b57cec5SDimitry Andric 1614*0b57cec5SDimitry Andric // Add an unconditional branch to the destination and invert the branch 1615*0b57cec5SDimitry Andric // condition to jump over it: 1616*0b57cec5SDimitry Andric // blt L1 1617*0b57cec5SDimitry Andric // => 1618*0b57cec5SDimitry Andric // bge L2 1619*0b57cec5SDimitry Andric // b L1 1620*0b57cec5SDimitry Andric // L2: 1621*0b57cec5SDimitry Andric ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(1).getImm(); 1622*0b57cec5SDimitry Andric CC = ARMCC::getOppositeCondition(CC); 1623*0b57cec5SDimitry Andric unsigned CCReg = MI->getOperand(2).getReg(); 1624*0b57cec5SDimitry Andric 1625*0b57cec5SDimitry Andric // If the branch is at the end of its MBB and that has a fall-through block, 1626*0b57cec5SDimitry Andric // direct the updated conditional branch to the fall-through block. Otherwise, 1627*0b57cec5SDimitry Andric // split the MBB before the next instruction. 1628*0b57cec5SDimitry Andric MachineBasicBlock *MBB = MI->getParent(); 1629*0b57cec5SDimitry Andric MachineInstr *BMI = &MBB->back(); 1630*0b57cec5SDimitry Andric bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB); 1631*0b57cec5SDimitry Andric 1632*0b57cec5SDimitry Andric ++NumCBrFixed; 1633*0b57cec5SDimitry Andric if (BMI != MI) { 1634*0b57cec5SDimitry Andric if (std::next(MachineBasicBlock::iterator(MI)) == std::prev(MBB->end()) && 1635*0b57cec5SDimitry Andric BMI->getOpcode() == Br.UncondBr) { 1636*0b57cec5SDimitry Andric // Last MI in the BB is an unconditional branch. Can we simply invert the 1637*0b57cec5SDimitry Andric // condition and swap destinations: 1638*0b57cec5SDimitry Andric // beq L1 1639*0b57cec5SDimitry Andric // b L2 1640*0b57cec5SDimitry Andric // => 1641*0b57cec5SDimitry Andric // bne L2 1642*0b57cec5SDimitry Andric // b L1 1643*0b57cec5SDimitry Andric MachineBasicBlock *NewDest = BMI->getOperand(0).getMBB(); 1644*0b57cec5SDimitry Andric if (BBUtils->isBBInRange(MI, NewDest, Br.MaxDisp)) { 1645*0b57cec5SDimitry Andric LLVM_DEBUG( 1646*0b57cec5SDimitry Andric dbgs() << " Invert Bcc condition and swap its destination with " 1647*0b57cec5SDimitry Andric << *BMI); 1648*0b57cec5SDimitry Andric BMI->getOperand(0).setMBB(DestBB); 1649*0b57cec5SDimitry Andric MI->getOperand(0).setMBB(NewDest); 1650*0b57cec5SDimitry Andric MI->getOperand(1).setImm(CC); 1651*0b57cec5SDimitry Andric return true; 1652*0b57cec5SDimitry Andric } 1653*0b57cec5SDimitry Andric } 1654*0b57cec5SDimitry Andric } 1655*0b57cec5SDimitry Andric 1656*0b57cec5SDimitry Andric if (NeedSplit) { 1657*0b57cec5SDimitry Andric splitBlockBeforeInstr(MI); 1658*0b57cec5SDimitry Andric // No need for the branch to the next block. We're adding an unconditional 1659*0b57cec5SDimitry Andric // branch to the destination. 1660*0b57cec5SDimitry Andric int delta = TII->getInstSizeInBytes(MBB->back()); 1661*0b57cec5SDimitry Andric BBUtils->adjustBBSize(MBB, -delta); 1662*0b57cec5SDimitry Andric MBB->back().eraseFromParent(); 1663*0b57cec5SDimitry Andric 1664*0b57cec5SDimitry Andric // The conditional successor will be swapped between the BBs after this, so 1665*0b57cec5SDimitry Andric // update CFG. 1666*0b57cec5SDimitry Andric MBB->addSuccessor(DestBB); 1667*0b57cec5SDimitry Andric std::next(MBB->getIterator())->removeSuccessor(DestBB); 1668*0b57cec5SDimitry Andric 1669*0b57cec5SDimitry Andric // BBInfo[SplitBB].Offset is wrong temporarily, fixed below 1670*0b57cec5SDimitry Andric } 1671*0b57cec5SDimitry Andric MachineBasicBlock *NextBB = &*++MBB->getIterator(); 1672*0b57cec5SDimitry Andric 1673*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Insert B to " << printMBBReference(*DestBB) 1674*0b57cec5SDimitry Andric << " also invert condition and change dest. to " 1675*0b57cec5SDimitry Andric << printMBBReference(*NextBB) << "\n"); 1676*0b57cec5SDimitry Andric 1677*0b57cec5SDimitry Andric // Insert a new conditional branch and a new unconditional branch. 1678*0b57cec5SDimitry Andric // Also update the ImmBranch as well as adding a new entry for the new branch. 1679*0b57cec5SDimitry Andric BuildMI(MBB, DebugLoc(), TII->get(MI->getOpcode())) 1680*0b57cec5SDimitry Andric .addMBB(NextBB).addImm(CC).addReg(CCReg); 1681*0b57cec5SDimitry Andric Br.MI = &MBB->back(); 1682*0b57cec5SDimitry Andric BBUtils->adjustBBSize(MBB, TII->getInstSizeInBytes(MBB->back())); 1683*0b57cec5SDimitry Andric if (isThumb) 1684*0b57cec5SDimitry Andric BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)) 1685*0b57cec5SDimitry Andric .addMBB(DestBB) 1686*0b57cec5SDimitry Andric .add(predOps(ARMCC::AL)); 1687*0b57cec5SDimitry Andric else 1688*0b57cec5SDimitry Andric BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB); 1689*0b57cec5SDimitry Andric BBUtils->adjustBBSize(MBB, TII->getInstSizeInBytes(MBB->back())); 1690*0b57cec5SDimitry Andric unsigned MaxDisp = getUnconditionalBrDisp(Br.UncondBr); 1691*0b57cec5SDimitry Andric ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr)); 1692*0b57cec5SDimitry Andric 1693*0b57cec5SDimitry Andric // Remove the old conditional branch. It may or may not still be in MBB. 1694*0b57cec5SDimitry Andric BBUtils->adjustBBSize(MI->getParent(), -TII->getInstSizeInBytes(*MI)); 1695*0b57cec5SDimitry Andric MI->eraseFromParent(); 1696*0b57cec5SDimitry Andric BBUtils->adjustBBOffsetsAfter(MBB); 1697*0b57cec5SDimitry Andric return true; 1698*0b57cec5SDimitry Andric } 1699*0b57cec5SDimitry Andric 1700*0b57cec5SDimitry Andric /// undoLRSpillRestore - Remove Thumb push / pop instructions that only spills 1701*0b57cec5SDimitry Andric /// LR / restores LR to pc. FIXME: This is done here because it's only possible 1702*0b57cec5SDimitry Andric /// to do this if tBfar is not used. 1703*0b57cec5SDimitry Andric bool ARMConstantIslands::undoLRSpillRestore() { 1704*0b57cec5SDimitry Andric bool MadeChange = false; 1705*0b57cec5SDimitry Andric for (unsigned i = 0, e = PushPopMIs.size(); i != e; ++i) { 1706*0b57cec5SDimitry Andric MachineInstr *MI = PushPopMIs[i]; 1707*0b57cec5SDimitry Andric // First two operands are predicates. 1708*0b57cec5SDimitry Andric if (MI->getOpcode() == ARM::tPOP_RET && 1709*0b57cec5SDimitry Andric MI->getOperand(2).getReg() == ARM::PC && 1710*0b57cec5SDimitry Andric MI->getNumExplicitOperands() == 3) { 1711*0b57cec5SDimitry Andric // Create the new insn and copy the predicate from the old. 1712*0b57cec5SDimitry Andric BuildMI(MI->getParent(), MI->getDebugLoc(), TII->get(ARM::tBX_RET)) 1713*0b57cec5SDimitry Andric .add(MI->getOperand(0)) 1714*0b57cec5SDimitry Andric .add(MI->getOperand(1)); 1715*0b57cec5SDimitry Andric MI->eraseFromParent(); 1716*0b57cec5SDimitry Andric MadeChange = true; 1717*0b57cec5SDimitry Andric } else if (MI->getOpcode() == ARM::tPUSH && 1718*0b57cec5SDimitry Andric MI->getOperand(2).getReg() == ARM::LR && 1719*0b57cec5SDimitry Andric MI->getNumExplicitOperands() == 3) { 1720*0b57cec5SDimitry Andric // Just remove the push. 1721*0b57cec5SDimitry Andric MI->eraseFromParent(); 1722*0b57cec5SDimitry Andric MadeChange = true; 1723*0b57cec5SDimitry Andric } 1724*0b57cec5SDimitry Andric } 1725*0b57cec5SDimitry Andric return MadeChange; 1726*0b57cec5SDimitry Andric } 1727*0b57cec5SDimitry Andric 1728*0b57cec5SDimitry Andric bool ARMConstantIslands::optimizeThumb2Instructions() { 1729*0b57cec5SDimitry Andric bool MadeChange = false; 1730*0b57cec5SDimitry Andric 1731*0b57cec5SDimitry Andric // Shrink ADR and LDR from constantpool. 1732*0b57cec5SDimitry Andric for (unsigned i = 0, e = CPUsers.size(); i != e; ++i) { 1733*0b57cec5SDimitry Andric CPUser &U = CPUsers[i]; 1734*0b57cec5SDimitry Andric unsigned Opcode = U.MI->getOpcode(); 1735*0b57cec5SDimitry Andric unsigned NewOpc = 0; 1736*0b57cec5SDimitry Andric unsigned Scale = 1; 1737*0b57cec5SDimitry Andric unsigned Bits = 0; 1738*0b57cec5SDimitry Andric switch (Opcode) { 1739*0b57cec5SDimitry Andric default: break; 1740*0b57cec5SDimitry Andric case ARM::t2LEApcrel: 1741*0b57cec5SDimitry Andric if (isARMLowRegister(U.MI->getOperand(0).getReg())) { 1742*0b57cec5SDimitry Andric NewOpc = ARM::tLEApcrel; 1743*0b57cec5SDimitry Andric Bits = 8; 1744*0b57cec5SDimitry Andric Scale = 4; 1745*0b57cec5SDimitry Andric } 1746*0b57cec5SDimitry Andric break; 1747*0b57cec5SDimitry Andric case ARM::t2LDRpci: 1748*0b57cec5SDimitry Andric if (isARMLowRegister(U.MI->getOperand(0).getReg())) { 1749*0b57cec5SDimitry Andric NewOpc = ARM::tLDRpci; 1750*0b57cec5SDimitry Andric Bits = 8; 1751*0b57cec5SDimitry Andric Scale = 4; 1752*0b57cec5SDimitry Andric } 1753*0b57cec5SDimitry Andric break; 1754*0b57cec5SDimitry Andric } 1755*0b57cec5SDimitry Andric 1756*0b57cec5SDimitry Andric if (!NewOpc) 1757*0b57cec5SDimitry Andric continue; 1758*0b57cec5SDimitry Andric 1759*0b57cec5SDimitry Andric unsigned UserOffset = getUserOffset(U); 1760*0b57cec5SDimitry Andric unsigned MaxOffs = ((1 << Bits) - 1) * Scale; 1761*0b57cec5SDimitry Andric 1762*0b57cec5SDimitry Andric // Be conservative with inline asm. 1763*0b57cec5SDimitry Andric if (!U.KnownAlignment) 1764*0b57cec5SDimitry Andric MaxOffs -= 2; 1765*0b57cec5SDimitry Andric 1766*0b57cec5SDimitry Andric // FIXME: Check if offset is multiple of scale if scale is not 4. 1767*0b57cec5SDimitry Andric if (isCPEntryInRange(U.MI, UserOffset, U.CPEMI, MaxOffs, false, true)) { 1768*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Shrink: " << *U.MI); 1769*0b57cec5SDimitry Andric U.MI->setDesc(TII->get(NewOpc)); 1770*0b57cec5SDimitry Andric MachineBasicBlock *MBB = U.MI->getParent(); 1771*0b57cec5SDimitry Andric BBUtils->adjustBBSize(MBB, -2); 1772*0b57cec5SDimitry Andric BBUtils->adjustBBOffsetsAfter(MBB); 1773*0b57cec5SDimitry Andric ++NumT2CPShrunk; 1774*0b57cec5SDimitry Andric MadeChange = true; 1775*0b57cec5SDimitry Andric } 1776*0b57cec5SDimitry Andric } 1777*0b57cec5SDimitry Andric 1778*0b57cec5SDimitry Andric return MadeChange; 1779*0b57cec5SDimitry Andric } 1780*0b57cec5SDimitry Andric 1781*0b57cec5SDimitry Andric bool ARMConstantIslands::optimizeThumb2Branches() { 1782*0b57cec5SDimitry Andric bool MadeChange = false; 1783*0b57cec5SDimitry Andric 1784*0b57cec5SDimitry Andric // The order in which branches appear in ImmBranches is approximately their 1785*0b57cec5SDimitry Andric // order within the function body. By visiting later branches first, we reduce 1786*0b57cec5SDimitry Andric // the distance between earlier forward branches and their targets, making it 1787*0b57cec5SDimitry Andric // more likely that the cbn?z optimization, which can only apply to forward 1788*0b57cec5SDimitry Andric // branches, will succeed. 1789*0b57cec5SDimitry Andric for (unsigned i = ImmBranches.size(); i != 0; --i) { 1790*0b57cec5SDimitry Andric ImmBranch &Br = ImmBranches[i-1]; 1791*0b57cec5SDimitry Andric unsigned Opcode = Br.MI->getOpcode(); 1792*0b57cec5SDimitry Andric unsigned NewOpc = 0; 1793*0b57cec5SDimitry Andric unsigned Scale = 1; 1794*0b57cec5SDimitry Andric unsigned Bits = 0; 1795*0b57cec5SDimitry Andric switch (Opcode) { 1796*0b57cec5SDimitry Andric default: break; 1797*0b57cec5SDimitry Andric case ARM::t2B: 1798*0b57cec5SDimitry Andric NewOpc = ARM::tB; 1799*0b57cec5SDimitry Andric Bits = 11; 1800*0b57cec5SDimitry Andric Scale = 2; 1801*0b57cec5SDimitry Andric break; 1802*0b57cec5SDimitry Andric case ARM::t2Bcc: 1803*0b57cec5SDimitry Andric NewOpc = ARM::tBcc; 1804*0b57cec5SDimitry Andric Bits = 8; 1805*0b57cec5SDimitry Andric Scale = 2; 1806*0b57cec5SDimitry Andric break; 1807*0b57cec5SDimitry Andric } 1808*0b57cec5SDimitry Andric if (NewOpc) { 1809*0b57cec5SDimitry Andric unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale; 1810*0b57cec5SDimitry Andric MachineBasicBlock *DestBB = Br.MI->getOperand(0).getMBB(); 1811*0b57cec5SDimitry Andric if (BBUtils->isBBInRange(Br.MI, DestBB, MaxOffs)) { 1812*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Shrink branch: " << *Br.MI); 1813*0b57cec5SDimitry Andric Br.MI->setDesc(TII->get(NewOpc)); 1814*0b57cec5SDimitry Andric MachineBasicBlock *MBB = Br.MI->getParent(); 1815*0b57cec5SDimitry Andric BBUtils->adjustBBSize(MBB, -2); 1816*0b57cec5SDimitry Andric BBUtils->adjustBBOffsetsAfter(MBB); 1817*0b57cec5SDimitry Andric ++NumT2BrShrunk; 1818*0b57cec5SDimitry Andric MadeChange = true; 1819*0b57cec5SDimitry Andric } 1820*0b57cec5SDimitry Andric } 1821*0b57cec5SDimitry Andric 1822*0b57cec5SDimitry Andric Opcode = Br.MI->getOpcode(); 1823*0b57cec5SDimitry Andric if (Opcode != ARM::tBcc) 1824*0b57cec5SDimitry Andric continue; 1825*0b57cec5SDimitry Andric 1826*0b57cec5SDimitry Andric // If the conditional branch doesn't kill CPSR, then CPSR can be liveout 1827*0b57cec5SDimitry Andric // so this transformation is not safe. 1828*0b57cec5SDimitry Andric if (!Br.MI->killsRegister(ARM::CPSR)) 1829*0b57cec5SDimitry Andric continue; 1830*0b57cec5SDimitry Andric 1831*0b57cec5SDimitry Andric NewOpc = 0; 1832*0b57cec5SDimitry Andric unsigned PredReg = 0; 1833*0b57cec5SDimitry Andric ARMCC::CondCodes Pred = getInstrPredicate(*Br.MI, PredReg); 1834*0b57cec5SDimitry Andric if (Pred == ARMCC::EQ) 1835*0b57cec5SDimitry Andric NewOpc = ARM::tCBZ; 1836*0b57cec5SDimitry Andric else if (Pred == ARMCC::NE) 1837*0b57cec5SDimitry Andric NewOpc = ARM::tCBNZ; 1838*0b57cec5SDimitry Andric if (!NewOpc) 1839*0b57cec5SDimitry Andric continue; 1840*0b57cec5SDimitry Andric MachineBasicBlock *DestBB = Br.MI->getOperand(0).getMBB(); 1841*0b57cec5SDimitry Andric // Check if the distance is within 126. Subtract starting offset by 2 1842*0b57cec5SDimitry Andric // because the cmp will be eliminated. 1843*0b57cec5SDimitry Andric unsigned BrOffset = BBUtils->getOffsetOf(Br.MI) + 4 - 2; 1844*0b57cec5SDimitry Andric BBInfoVector &BBInfo = BBUtils->getBBInfo(); 1845*0b57cec5SDimitry Andric unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset; 1846*0b57cec5SDimitry Andric if (BrOffset >= DestOffset || (DestOffset - BrOffset) > 126) 1847*0b57cec5SDimitry Andric continue; 1848*0b57cec5SDimitry Andric 1849*0b57cec5SDimitry Andric // Search backwards to find a tCMPi8 1850*0b57cec5SDimitry Andric auto *TRI = STI->getRegisterInfo(); 1851*0b57cec5SDimitry Andric MachineInstr *CmpMI = findCMPToFoldIntoCBZ(Br.MI, TRI); 1852*0b57cec5SDimitry Andric if (!CmpMI || CmpMI->getOpcode() != ARM::tCMPi8) 1853*0b57cec5SDimitry Andric continue; 1854*0b57cec5SDimitry Andric 1855*0b57cec5SDimitry Andric unsigned Reg = CmpMI->getOperand(0).getReg(); 1856*0b57cec5SDimitry Andric 1857*0b57cec5SDimitry Andric // Check for Kill flags on Reg. If they are present remove them and set kill 1858*0b57cec5SDimitry Andric // on the new CBZ. 1859*0b57cec5SDimitry Andric MachineBasicBlock::iterator KillMI = Br.MI; 1860*0b57cec5SDimitry Andric bool RegKilled = false; 1861*0b57cec5SDimitry Andric do { 1862*0b57cec5SDimitry Andric --KillMI; 1863*0b57cec5SDimitry Andric if (KillMI->killsRegister(Reg, TRI)) { 1864*0b57cec5SDimitry Andric KillMI->clearRegisterKills(Reg, TRI); 1865*0b57cec5SDimitry Andric RegKilled = true; 1866*0b57cec5SDimitry Andric break; 1867*0b57cec5SDimitry Andric } 1868*0b57cec5SDimitry Andric } while (KillMI != CmpMI); 1869*0b57cec5SDimitry Andric 1870*0b57cec5SDimitry Andric // Create the new CBZ/CBNZ 1871*0b57cec5SDimitry Andric MachineBasicBlock *MBB = Br.MI->getParent(); 1872*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Fold: " << *CmpMI << " and: " << *Br.MI); 1873*0b57cec5SDimitry Andric MachineInstr *NewBR = 1874*0b57cec5SDimitry Andric BuildMI(*MBB, Br.MI, Br.MI->getDebugLoc(), TII->get(NewOpc)) 1875*0b57cec5SDimitry Andric .addReg(Reg, getKillRegState(RegKilled)) 1876*0b57cec5SDimitry Andric .addMBB(DestBB, Br.MI->getOperand(0).getTargetFlags()); 1877*0b57cec5SDimitry Andric CmpMI->eraseFromParent(); 1878*0b57cec5SDimitry Andric Br.MI->eraseFromParent(); 1879*0b57cec5SDimitry Andric Br.MI = NewBR; 1880*0b57cec5SDimitry Andric BBInfo[MBB->getNumber()].Size -= 2; 1881*0b57cec5SDimitry Andric BBUtils->adjustBBOffsetsAfter(MBB); 1882*0b57cec5SDimitry Andric ++NumCBZ; 1883*0b57cec5SDimitry Andric MadeChange = true; 1884*0b57cec5SDimitry Andric } 1885*0b57cec5SDimitry Andric 1886*0b57cec5SDimitry Andric return MadeChange; 1887*0b57cec5SDimitry Andric } 1888*0b57cec5SDimitry Andric 1889*0b57cec5SDimitry Andric static bool isSimpleIndexCalc(MachineInstr &I, unsigned EntryReg, 1890*0b57cec5SDimitry Andric unsigned BaseReg) { 1891*0b57cec5SDimitry Andric if (I.getOpcode() != ARM::t2ADDrs) 1892*0b57cec5SDimitry Andric return false; 1893*0b57cec5SDimitry Andric 1894*0b57cec5SDimitry Andric if (I.getOperand(0).getReg() != EntryReg) 1895*0b57cec5SDimitry Andric return false; 1896*0b57cec5SDimitry Andric 1897*0b57cec5SDimitry Andric if (I.getOperand(1).getReg() != BaseReg) 1898*0b57cec5SDimitry Andric return false; 1899*0b57cec5SDimitry Andric 1900*0b57cec5SDimitry Andric // FIXME: what about CC and IdxReg? 1901*0b57cec5SDimitry Andric return true; 1902*0b57cec5SDimitry Andric } 1903*0b57cec5SDimitry Andric 1904*0b57cec5SDimitry Andric /// While trying to form a TBB/TBH instruction, we may (if the table 1905*0b57cec5SDimitry Andric /// doesn't immediately follow the BR_JT) need access to the start of the 1906*0b57cec5SDimitry Andric /// jump-table. We know one instruction that produces such a register; this 1907*0b57cec5SDimitry Andric /// function works out whether that definition can be preserved to the BR_JT, 1908*0b57cec5SDimitry Andric /// possibly by removing an intervening addition (which is usually needed to 1909*0b57cec5SDimitry Andric /// calculate the actual entry to jump to). 1910*0b57cec5SDimitry Andric bool ARMConstantIslands::preserveBaseRegister(MachineInstr *JumpMI, 1911*0b57cec5SDimitry Andric MachineInstr *LEAMI, 1912*0b57cec5SDimitry Andric unsigned &DeadSize, 1913*0b57cec5SDimitry Andric bool &CanDeleteLEA, 1914*0b57cec5SDimitry Andric bool &BaseRegKill) { 1915*0b57cec5SDimitry Andric if (JumpMI->getParent() != LEAMI->getParent()) 1916*0b57cec5SDimitry Andric return false; 1917*0b57cec5SDimitry Andric 1918*0b57cec5SDimitry Andric // Now we hope that we have at least these instructions in the basic block: 1919*0b57cec5SDimitry Andric // BaseReg = t2LEA ... 1920*0b57cec5SDimitry Andric // [...] 1921*0b57cec5SDimitry Andric // EntryReg = t2ADDrs BaseReg, ... 1922*0b57cec5SDimitry Andric // [...] 1923*0b57cec5SDimitry Andric // t2BR_JT EntryReg 1924*0b57cec5SDimitry Andric // 1925*0b57cec5SDimitry Andric // We have to be very conservative about what we recognise here though. The 1926*0b57cec5SDimitry Andric // main perturbing factors to watch out for are: 1927*0b57cec5SDimitry Andric // + Spills at any point in the chain: not direct problems but we would 1928*0b57cec5SDimitry Andric // expect a blocking Def of the spilled register so in practice what we 1929*0b57cec5SDimitry Andric // can do is limited. 1930*0b57cec5SDimitry Andric // + EntryReg == BaseReg: this is the one situation we should allow a Def 1931*0b57cec5SDimitry Andric // of BaseReg, but only if the t2ADDrs can be removed. 1932*0b57cec5SDimitry Andric // + Some instruction other than t2ADDrs computing the entry. Not seen in 1933*0b57cec5SDimitry Andric // the wild, but we should be careful. 1934*0b57cec5SDimitry Andric unsigned EntryReg = JumpMI->getOperand(0).getReg(); 1935*0b57cec5SDimitry Andric unsigned BaseReg = LEAMI->getOperand(0).getReg(); 1936*0b57cec5SDimitry Andric 1937*0b57cec5SDimitry Andric CanDeleteLEA = true; 1938*0b57cec5SDimitry Andric BaseRegKill = false; 1939*0b57cec5SDimitry Andric MachineInstr *RemovableAdd = nullptr; 1940*0b57cec5SDimitry Andric MachineBasicBlock::iterator I(LEAMI); 1941*0b57cec5SDimitry Andric for (++I; &*I != JumpMI; ++I) { 1942*0b57cec5SDimitry Andric if (isSimpleIndexCalc(*I, EntryReg, BaseReg)) { 1943*0b57cec5SDimitry Andric RemovableAdd = &*I; 1944*0b57cec5SDimitry Andric break; 1945*0b57cec5SDimitry Andric } 1946*0b57cec5SDimitry Andric 1947*0b57cec5SDimitry Andric for (unsigned K = 0, E = I->getNumOperands(); K != E; ++K) { 1948*0b57cec5SDimitry Andric const MachineOperand &MO = I->getOperand(K); 1949*0b57cec5SDimitry Andric if (!MO.isReg() || !MO.getReg()) 1950*0b57cec5SDimitry Andric continue; 1951*0b57cec5SDimitry Andric if (MO.isDef() && MO.getReg() == BaseReg) 1952*0b57cec5SDimitry Andric return false; 1953*0b57cec5SDimitry Andric if (MO.isUse() && MO.getReg() == BaseReg) { 1954*0b57cec5SDimitry Andric BaseRegKill = BaseRegKill || MO.isKill(); 1955*0b57cec5SDimitry Andric CanDeleteLEA = false; 1956*0b57cec5SDimitry Andric } 1957*0b57cec5SDimitry Andric } 1958*0b57cec5SDimitry Andric } 1959*0b57cec5SDimitry Andric 1960*0b57cec5SDimitry Andric if (!RemovableAdd) 1961*0b57cec5SDimitry Andric return true; 1962*0b57cec5SDimitry Andric 1963*0b57cec5SDimitry Andric // Check the add really is removable, and that nothing else in the block 1964*0b57cec5SDimitry Andric // clobbers BaseReg. 1965*0b57cec5SDimitry Andric for (++I; &*I != JumpMI; ++I) { 1966*0b57cec5SDimitry Andric for (unsigned K = 0, E = I->getNumOperands(); K != E; ++K) { 1967*0b57cec5SDimitry Andric const MachineOperand &MO = I->getOperand(K); 1968*0b57cec5SDimitry Andric if (!MO.isReg() || !MO.getReg()) 1969*0b57cec5SDimitry Andric continue; 1970*0b57cec5SDimitry Andric if (MO.isDef() && MO.getReg() == BaseReg) 1971*0b57cec5SDimitry Andric return false; 1972*0b57cec5SDimitry Andric if (MO.isUse() && MO.getReg() == EntryReg) 1973*0b57cec5SDimitry Andric RemovableAdd = nullptr; 1974*0b57cec5SDimitry Andric } 1975*0b57cec5SDimitry Andric } 1976*0b57cec5SDimitry Andric 1977*0b57cec5SDimitry Andric if (RemovableAdd) { 1978*0b57cec5SDimitry Andric RemovableAdd->eraseFromParent(); 1979*0b57cec5SDimitry Andric DeadSize += isThumb2 ? 4 : 2; 1980*0b57cec5SDimitry Andric } else if (BaseReg == EntryReg) { 1981*0b57cec5SDimitry Andric // The add wasn't removable, but clobbered the base for the TBB. So we can't 1982*0b57cec5SDimitry Andric // preserve it. 1983*0b57cec5SDimitry Andric return false; 1984*0b57cec5SDimitry Andric } 1985*0b57cec5SDimitry Andric 1986*0b57cec5SDimitry Andric // We reached the end of the block without seeing another definition of 1987*0b57cec5SDimitry Andric // BaseReg (except, possibly the t2ADDrs, which was removed). BaseReg can be 1988*0b57cec5SDimitry Andric // used in the TBB/TBH if necessary. 1989*0b57cec5SDimitry Andric return true; 1990*0b57cec5SDimitry Andric } 1991*0b57cec5SDimitry Andric 1992*0b57cec5SDimitry Andric /// Returns whether CPEMI is the first instruction in the block 1993*0b57cec5SDimitry Andric /// immediately following JTMI (assumed to be a TBB or TBH terminator). If so, 1994*0b57cec5SDimitry Andric /// we can switch the first register to PC and usually remove the address 1995*0b57cec5SDimitry Andric /// calculation that preceded it. 1996*0b57cec5SDimitry Andric static bool jumpTableFollowsTB(MachineInstr *JTMI, MachineInstr *CPEMI) { 1997*0b57cec5SDimitry Andric MachineFunction::iterator MBB = JTMI->getParent()->getIterator(); 1998*0b57cec5SDimitry Andric MachineFunction *MF = MBB->getParent(); 1999*0b57cec5SDimitry Andric ++MBB; 2000*0b57cec5SDimitry Andric 2001*0b57cec5SDimitry Andric return MBB != MF->end() && MBB->begin() != MBB->end() && 2002*0b57cec5SDimitry Andric &*MBB->begin() == CPEMI; 2003*0b57cec5SDimitry Andric } 2004*0b57cec5SDimitry Andric 2005*0b57cec5SDimitry Andric static void RemoveDeadAddBetweenLEAAndJT(MachineInstr *LEAMI, 2006*0b57cec5SDimitry Andric MachineInstr *JumpMI, 2007*0b57cec5SDimitry Andric unsigned &DeadSize) { 2008*0b57cec5SDimitry Andric // Remove a dead add between the LEA and JT, which used to compute EntryReg, 2009*0b57cec5SDimitry Andric // but the JT now uses PC. Finds the last ADD (if any) that def's EntryReg 2010*0b57cec5SDimitry Andric // and is not clobbered / used. 2011*0b57cec5SDimitry Andric MachineInstr *RemovableAdd = nullptr; 2012*0b57cec5SDimitry Andric unsigned EntryReg = JumpMI->getOperand(0).getReg(); 2013*0b57cec5SDimitry Andric 2014*0b57cec5SDimitry Andric // Find the last ADD to set EntryReg 2015*0b57cec5SDimitry Andric MachineBasicBlock::iterator I(LEAMI); 2016*0b57cec5SDimitry Andric for (++I; &*I != JumpMI; ++I) { 2017*0b57cec5SDimitry Andric if (I->getOpcode() == ARM::t2ADDrs && I->getOperand(0).getReg() == EntryReg) 2018*0b57cec5SDimitry Andric RemovableAdd = &*I; 2019*0b57cec5SDimitry Andric } 2020*0b57cec5SDimitry Andric 2021*0b57cec5SDimitry Andric if (!RemovableAdd) 2022*0b57cec5SDimitry Andric return; 2023*0b57cec5SDimitry Andric 2024*0b57cec5SDimitry Andric // Ensure EntryReg is not clobbered or used. 2025*0b57cec5SDimitry Andric MachineBasicBlock::iterator J(RemovableAdd); 2026*0b57cec5SDimitry Andric for (++J; &*J != JumpMI; ++J) { 2027*0b57cec5SDimitry Andric for (unsigned K = 0, E = J->getNumOperands(); K != E; ++K) { 2028*0b57cec5SDimitry Andric const MachineOperand &MO = J->getOperand(K); 2029*0b57cec5SDimitry Andric if (!MO.isReg() || !MO.getReg()) 2030*0b57cec5SDimitry Andric continue; 2031*0b57cec5SDimitry Andric if (MO.isDef() && MO.getReg() == EntryReg) 2032*0b57cec5SDimitry Andric return; 2033*0b57cec5SDimitry Andric if (MO.isUse() && MO.getReg() == EntryReg) 2034*0b57cec5SDimitry Andric return; 2035*0b57cec5SDimitry Andric } 2036*0b57cec5SDimitry Andric } 2037*0b57cec5SDimitry Andric 2038*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Removing Dead Add: " << *RemovableAdd); 2039*0b57cec5SDimitry Andric RemovableAdd->eraseFromParent(); 2040*0b57cec5SDimitry Andric DeadSize += 4; 2041*0b57cec5SDimitry Andric } 2042*0b57cec5SDimitry Andric 2043*0b57cec5SDimitry Andric /// optimizeThumb2JumpTables - Use tbb / tbh instructions to generate smaller 2044*0b57cec5SDimitry Andric /// jumptables when it's possible. 2045*0b57cec5SDimitry Andric bool ARMConstantIslands::optimizeThumb2JumpTables() { 2046*0b57cec5SDimitry Andric bool MadeChange = false; 2047*0b57cec5SDimitry Andric 2048*0b57cec5SDimitry Andric // FIXME: After the tables are shrunk, can we get rid some of the 2049*0b57cec5SDimitry Andric // constantpool tables? 2050*0b57cec5SDimitry Andric MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 2051*0b57cec5SDimitry Andric if (!MJTI) return false; 2052*0b57cec5SDimitry Andric 2053*0b57cec5SDimitry Andric const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 2054*0b57cec5SDimitry Andric for (unsigned i = 0, e = T2JumpTables.size(); i != e; ++i) { 2055*0b57cec5SDimitry Andric MachineInstr *MI = T2JumpTables[i]; 2056*0b57cec5SDimitry Andric const MCInstrDesc &MCID = MI->getDesc(); 2057*0b57cec5SDimitry Andric unsigned NumOps = MCID.getNumOperands(); 2058*0b57cec5SDimitry Andric unsigned JTOpIdx = NumOps - (MI->isPredicable() ? 2 : 1); 2059*0b57cec5SDimitry Andric MachineOperand JTOP = MI->getOperand(JTOpIdx); 2060*0b57cec5SDimitry Andric unsigned JTI = JTOP.getIndex(); 2061*0b57cec5SDimitry Andric assert(JTI < JT.size()); 2062*0b57cec5SDimitry Andric 2063*0b57cec5SDimitry Andric bool ByteOk = true; 2064*0b57cec5SDimitry Andric bool HalfWordOk = true; 2065*0b57cec5SDimitry Andric unsigned JTOffset = BBUtils->getOffsetOf(MI) + 4; 2066*0b57cec5SDimitry Andric const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 2067*0b57cec5SDimitry Andric BBInfoVector &BBInfo = BBUtils->getBBInfo(); 2068*0b57cec5SDimitry Andric for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) { 2069*0b57cec5SDimitry Andric MachineBasicBlock *MBB = JTBBs[j]; 2070*0b57cec5SDimitry Andric unsigned DstOffset = BBInfo[MBB->getNumber()].Offset; 2071*0b57cec5SDimitry Andric // Negative offset is not ok. FIXME: We should change BB layout to make 2072*0b57cec5SDimitry Andric // sure all the branches are forward. 2073*0b57cec5SDimitry Andric if (ByteOk && (DstOffset - JTOffset) > ((1<<8)-1)*2) 2074*0b57cec5SDimitry Andric ByteOk = false; 2075*0b57cec5SDimitry Andric unsigned TBHLimit = ((1<<16)-1)*2; 2076*0b57cec5SDimitry Andric if (HalfWordOk && (DstOffset - JTOffset) > TBHLimit) 2077*0b57cec5SDimitry Andric HalfWordOk = false; 2078*0b57cec5SDimitry Andric if (!ByteOk && !HalfWordOk) 2079*0b57cec5SDimitry Andric break; 2080*0b57cec5SDimitry Andric } 2081*0b57cec5SDimitry Andric 2082*0b57cec5SDimitry Andric if (!ByteOk && !HalfWordOk) 2083*0b57cec5SDimitry Andric continue; 2084*0b57cec5SDimitry Andric 2085*0b57cec5SDimitry Andric CPUser &User = CPUsers[JumpTableUserIndices[JTI]]; 2086*0b57cec5SDimitry Andric MachineBasicBlock *MBB = MI->getParent(); 2087*0b57cec5SDimitry Andric if (!MI->getOperand(0).isKill()) // FIXME: needed now? 2088*0b57cec5SDimitry Andric continue; 2089*0b57cec5SDimitry Andric 2090*0b57cec5SDimitry Andric unsigned DeadSize = 0; 2091*0b57cec5SDimitry Andric bool CanDeleteLEA = false; 2092*0b57cec5SDimitry Andric bool BaseRegKill = false; 2093*0b57cec5SDimitry Andric 2094*0b57cec5SDimitry Andric unsigned IdxReg = ~0U; 2095*0b57cec5SDimitry Andric bool IdxRegKill = true; 2096*0b57cec5SDimitry Andric if (isThumb2) { 2097*0b57cec5SDimitry Andric IdxReg = MI->getOperand(1).getReg(); 2098*0b57cec5SDimitry Andric IdxRegKill = MI->getOperand(1).isKill(); 2099*0b57cec5SDimitry Andric 2100*0b57cec5SDimitry Andric bool PreservedBaseReg = 2101*0b57cec5SDimitry Andric preserveBaseRegister(MI, User.MI, DeadSize, CanDeleteLEA, BaseRegKill); 2102*0b57cec5SDimitry Andric if (!jumpTableFollowsTB(MI, User.CPEMI) && !PreservedBaseReg) 2103*0b57cec5SDimitry Andric continue; 2104*0b57cec5SDimitry Andric } else { 2105*0b57cec5SDimitry Andric // We're in thumb-1 mode, so we must have something like: 2106*0b57cec5SDimitry Andric // %idx = tLSLri %idx, 2 2107*0b57cec5SDimitry Andric // %base = tLEApcrelJT 2108*0b57cec5SDimitry Andric // %t = tLDRr %base, %idx 2109*0b57cec5SDimitry Andric unsigned BaseReg = User.MI->getOperand(0).getReg(); 2110*0b57cec5SDimitry Andric 2111*0b57cec5SDimitry Andric if (User.MI->getIterator() == User.MI->getParent()->begin()) 2112*0b57cec5SDimitry Andric continue; 2113*0b57cec5SDimitry Andric MachineInstr *Shift = User.MI->getPrevNode(); 2114*0b57cec5SDimitry Andric if (Shift->getOpcode() != ARM::tLSLri || 2115*0b57cec5SDimitry Andric Shift->getOperand(3).getImm() != 2 || 2116*0b57cec5SDimitry Andric !Shift->getOperand(2).isKill()) 2117*0b57cec5SDimitry Andric continue; 2118*0b57cec5SDimitry Andric IdxReg = Shift->getOperand(2).getReg(); 2119*0b57cec5SDimitry Andric unsigned ShiftedIdxReg = Shift->getOperand(0).getReg(); 2120*0b57cec5SDimitry Andric 2121*0b57cec5SDimitry Andric // It's important that IdxReg is live until the actual TBB/TBH. Most of 2122*0b57cec5SDimitry Andric // the range is checked later, but the LEA might still clobber it and not 2123*0b57cec5SDimitry Andric // actually get removed. 2124*0b57cec5SDimitry Andric if (BaseReg == IdxReg && !jumpTableFollowsTB(MI, User.CPEMI)) 2125*0b57cec5SDimitry Andric continue; 2126*0b57cec5SDimitry Andric 2127*0b57cec5SDimitry Andric MachineInstr *Load = User.MI->getNextNode(); 2128*0b57cec5SDimitry Andric if (Load->getOpcode() != ARM::tLDRr) 2129*0b57cec5SDimitry Andric continue; 2130*0b57cec5SDimitry Andric if (Load->getOperand(1).getReg() != BaseReg || 2131*0b57cec5SDimitry Andric Load->getOperand(2).getReg() != ShiftedIdxReg || 2132*0b57cec5SDimitry Andric !Load->getOperand(2).isKill()) 2133*0b57cec5SDimitry Andric continue; 2134*0b57cec5SDimitry Andric 2135*0b57cec5SDimitry Andric // If we're in PIC mode, there should be another ADD following. 2136*0b57cec5SDimitry Andric auto *TRI = STI->getRegisterInfo(); 2137*0b57cec5SDimitry Andric 2138*0b57cec5SDimitry Andric // %base cannot be redefined after the load as it will appear before 2139*0b57cec5SDimitry Andric // TBB/TBH like: 2140*0b57cec5SDimitry Andric // %base = 2141*0b57cec5SDimitry Andric // %base = 2142*0b57cec5SDimitry Andric // tBB %base, %idx 2143*0b57cec5SDimitry Andric if (registerDefinedBetween(BaseReg, Load->getNextNode(), MBB->end(), TRI)) 2144*0b57cec5SDimitry Andric continue; 2145*0b57cec5SDimitry Andric 2146*0b57cec5SDimitry Andric if (isPositionIndependentOrROPI) { 2147*0b57cec5SDimitry Andric MachineInstr *Add = Load->getNextNode(); 2148*0b57cec5SDimitry Andric if (Add->getOpcode() != ARM::tADDrr || 2149*0b57cec5SDimitry Andric Add->getOperand(2).getReg() != BaseReg || 2150*0b57cec5SDimitry Andric Add->getOperand(3).getReg() != Load->getOperand(0).getReg() || 2151*0b57cec5SDimitry Andric !Add->getOperand(3).isKill()) 2152*0b57cec5SDimitry Andric continue; 2153*0b57cec5SDimitry Andric if (Add->getOperand(0).getReg() != MI->getOperand(0).getReg()) 2154*0b57cec5SDimitry Andric continue; 2155*0b57cec5SDimitry Andric if (registerDefinedBetween(IdxReg, Add->getNextNode(), MI, TRI)) 2156*0b57cec5SDimitry Andric // IdxReg gets redefined in the middle of the sequence. 2157*0b57cec5SDimitry Andric continue; 2158*0b57cec5SDimitry Andric Add->eraseFromParent(); 2159*0b57cec5SDimitry Andric DeadSize += 2; 2160*0b57cec5SDimitry Andric } else { 2161*0b57cec5SDimitry Andric if (Load->getOperand(0).getReg() != MI->getOperand(0).getReg()) 2162*0b57cec5SDimitry Andric continue; 2163*0b57cec5SDimitry Andric if (registerDefinedBetween(IdxReg, Load->getNextNode(), MI, TRI)) 2164*0b57cec5SDimitry Andric // IdxReg gets redefined in the middle of the sequence. 2165*0b57cec5SDimitry Andric continue; 2166*0b57cec5SDimitry Andric } 2167*0b57cec5SDimitry Andric 2168*0b57cec5SDimitry Andric // Now safe to delete the load and lsl. The LEA will be removed later. 2169*0b57cec5SDimitry Andric CanDeleteLEA = true; 2170*0b57cec5SDimitry Andric Shift->eraseFromParent(); 2171*0b57cec5SDimitry Andric Load->eraseFromParent(); 2172*0b57cec5SDimitry Andric DeadSize += 4; 2173*0b57cec5SDimitry Andric } 2174*0b57cec5SDimitry Andric 2175*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Shrink JT: " << *MI); 2176*0b57cec5SDimitry Andric MachineInstr *CPEMI = User.CPEMI; 2177*0b57cec5SDimitry Andric unsigned Opc = ByteOk ? ARM::t2TBB_JT : ARM::t2TBH_JT; 2178*0b57cec5SDimitry Andric if (!isThumb2) 2179*0b57cec5SDimitry Andric Opc = ByteOk ? ARM::tTBB_JT : ARM::tTBH_JT; 2180*0b57cec5SDimitry Andric 2181*0b57cec5SDimitry Andric MachineBasicBlock::iterator MI_JT = MI; 2182*0b57cec5SDimitry Andric MachineInstr *NewJTMI = 2183*0b57cec5SDimitry Andric BuildMI(*MBB, MI_JT, MI->getDebugLoc(), TII->get(Opc)) 2184*0b57cec5SDimitry Andric .addReg(User.MI->getOperand(0).getReg(), 2185*0b57cec5SDimitry Andric getKillRegState(BaseRegKill)) 2186*0b57cec5SDimitry Andric .addReg(IdxReg, getKillRegState(IdxRegKill)) 2187*0b57cec5SDimitry Andric .addJumpTableIndex(JTI, JTOP.getTargetFlags()) 2188*0b57cec5SDimitry Andric .addImm(CPEMI->getOperand(0).getImm()); 2189*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << ": " << *NewJTMI); 2190*0b57cec5SDimitry Andric 2191*0b57cec5SDimitry Andric unsigned JTOpc = ByteOk ? ARM::JUMPTABLE_TBB : ARM::JUMPTABLE_TBH; 2192*0b57cec5SDimitry Andric CPEMI->setDesc(TII->get(JTOpc)); 2193*0b57cec5SDimitry Andric 2194*0b57cec5SDimitry Andric if (jumpTableFollowsTB(MI, User.CPEMI)) { 2195*0b57cec5SDimitry Andric NewJTMI->getOperand(0).setReg(ARM::PC); 2196*0b57cec5SDimitry Andric NewJTMI->getOperand(0).setIsKill(false); 2197*0b57cec5SDimitry Andric 2198*0b57cec5SDimitry Andric if (CanDeleteLEA) { 2199*0b57cec5SDimitry Andric if (isThumb2) 2200*0b57cec5SDimitry Andric RemoveDeadAddBetweenLEAAndJT(User.MI, MI, DeadSize); 2201*0b57cec5SDimitry Andric 2202*0b57cec5SDimitry Andric User.MI->eraseFromParent(); 2203*0b57cec5SDimitry Andric DeadSize += isThumb2 ? 4 : 2; 2204*0b57cec5SDimitry Andric 2205*0b57cec5SDimitry Andric // The LEA was eliminated, the TBB instruction becomes the only new user 2206*0b57cec5SDimitry Andric // of the jump table. 2207*0b57cec5SDimitry Andric User.MI = NewJTMI; 2208*0b57cec5SDimitry Andric User.MaxDisp = 4; 2209*0b57cec5SDimitry Andric User.NegOk = false; 2210*0b57cec5SDimitry Andric User.IsSoImm = false; 2211*0b57cec5SDimitry Andric User.KnownAlignment = false; 2212*0b57cec5SDimitry Andric } else { 2213*0b57cec5SDimitry Andric // The LEA couldn't be eliminated, so we must add another CPUser to 2214*0b57cec5SDimitry Andric // record the TBB or TBH use. 2215*0b57cec5SDimitry Andric int CPEntryIdx = JumpTableEntryIndices[JTI]; 2216*0b57cec5SDimitry Andric auto &CPEs = CPEntries[CPEntryIdx]; 2217*0b57cec5SDimitry Andric auto Entry = 2218*0b57cec5SDimitry Andric find_if(CPEs, [&](CPEntry &E) { return E.CPEMI == User.CPEMI; }); 2219*0b57cec5SDimitry Andric ++Entry->RefCount; 2220*0b57cec5SDimitry Andric CPUsers.emplace_back(CPUser(NewJTMI, User.CPEMI, 4, false, false)); 2221*0b57cec5SDimitry Andric } 2222*0b57cec5SDimitry Andric } 2223*0b57cec5SDimitry Andric 2224*0b57cec5SDimitry Andric unsigned NewSize = TII->getInstSizeInBytes(*NewJTMI); 2225*0b57cec5SDimitry Andric unsigned OrigSize = TII->getInstSizeInBytes(*MI); 2226*0b57cec5SDimitry Andric MI->eraseFromParent(); 2227*0b57cec5SDimitry Andric 2228*0b57cec5SDimitry Andric int Delta = OrigSize - NewSize + DeadSize; 2229*0b57cec5SDimitry Andric BBInfo[MBB->getNumber()].Size -= Delta; 2230*0b57cec5SDimitry Andric BBUtils->adjustBBOffsetsAfter(MBB); 2231*0b57cec5SDimitry Andric 2232*0b57cec5SDimitry Andric ++NumTBs; 2233*0b57cec5SDimitry Andric MadeChange = true; 2234*0b57cec5SDimitry Andric } 2235*0b57cec5SDimitry Andric 2236*0b57cec5SDimitry Andric return MadeChange; 2237*0b57cec5SDimitry Andric } 2238*0b57cec5SDimitry Andric 2239*0b57cec5SDimitry Andric /// reorderThumb2JumpTables - Adjust the function's block layout to ensure that 2240*0b57cec5SDimitry Andric /// jump tables always branch forwards, since that's what tbb and tbh need. 2241*0b57cec5SDimitry Andric bool ARMConstantIslands::reorderThumb2JumpTables() { 2242*0b57cec5SDimitry Andric bool MadeChange = false; 2243*0b57cec5SDimitry Andric 2244*0b57cec5SDimitry Andric MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 2245*0b57cec5SDimitry Andric if (!MJTI) return false; 2246*0b57cec5SDimitry Andric 2247*0b57cec5SDimitry Andric const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 2248*0b57cec5SDimitry Andric for (unsigned i = 0, e = T2JumpTables.size(); i != e; ++i) { 2249*0b57cec5SDimitry Andric MachineInstr *MI = T2JumpTables[i]; 2250*0b57cec5SDimitry Andric const MCInstrDesc &MCID = MI->getDesc(); 2251*0b57cec5SDimitry Andric unsigned NumOps = MCID.getNumOperands(); 2252*0b57cec5SDimitry Andric unsigned JTOpIdx = NumOps - (MI->isPredicable() ? 2 : 1); 2253*0b57cec5SDimitry Andric MachineOperand JTOP = MI->getOperand(JTOpIdx); 2254*0b57cec5SDimitry Andric unsigned JTI = JTOP.getIndex(); 2255*0b57cec5SDimitry Andric assert(JTI < JT.size()); 2256*0b57cec5SDimitry Andric 2257*0b57cec5SDimitry Andric // We prefer if target blocks for the jump table come after the jump 2258*0b57cec5SDimitry Andric // instruction so we can use TB[BH]. Loop through the target blocks 2259*0b57cec5SDimitry Andric // and try to adjust them such that that's true. 2260*0b57cec5SDimitry Andric int JTNumber = MI->getParent()->getNumber(); 2261*0b57cec5SDimitry Andric const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 2262*0b57cec5SDimitry Andric for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) { 2263*0b57cec5SDimitry Andric MachineBasicBlock *MBB = JTBBs[j]; 2264*0b57cec5SDimitry Andric int DTNumber = MBB->getNumber(); 2265*0b57cec5SDimitry Andric 2266*0b57cec5SDimitry Andric if (DTNumber < JTNumber) { 2267*0b57cec5SDimitry Andric // The destination precedes the switch. Try to move the block forward 2268*0b57cec5SDimitry Andric // so we have a positive offset. 2269*0b57cec5SDimitry Andric MachineBasicBlock *NewBB = 2270*0b57cec5SDimitry Andric adjustJTTargetBlockForward(MBB, MI->getParent()); 2271*0b57cec5SDimitry Andric if (NewBB) 2272*0b57cec5SDimitry Andric MJTI->ReplaceMBBInJumpTable(JTI, JTBBs[j], NewBB); 2273*0b57cec5SDimitry Andric MadeChange = true; 2274*0b57cec5SDimitry Andric } 2275*0b57cec5SDimitry Andric } 2276*0b57cec5SDimitry Andric } 2277*0b57cec5SDimitry Andric 2278*0b57cec5SDimitry Andric return MadeChange; 2279*0b57cec5SDimitry Andric } 2280*0b57cec5SDimitry Andric 2281*0b57cec5SDimitry Andric MachineBasicBlock *ARMConstantIslands:: 2282*0b57cec5SDimitry Andric adjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock *JTBB) { 2283*0b57cec5SDimitry Andric // If the destination block is terminated by an unconditional branch, 2284*0b57cec5SDimitry Andric // try to move it; otherwise, create a new block following the jump 2285*0b57cec5SDimitry Andric // table that branches back to the actual target. This is a very simple 2286*0b57cec5SDimitry Andric // heuristic. FIXME: We can definitely improve it. 2287*0b57cec5SDimitry Andric MachineBasicBlock *TBB = nullptr, *FBB = nullptr; 2288*0b57cec5SDimitry Andric SmallVector<MachineOperand, 4> Cond; 2289*0b57cec5SDimitry Andric SmallVector<MachineOperand, 4> CondPrior; 2290*0b57cec5SDimitry Andric MachineFunction::iterator BBi = BB->getIterator(); 2291*0b57cec5SDimitry Andric MachineFunction::iterator OldPrior = std::prev(BBi); 2292*0b57cec5SDimitry Andric 2293*0b57cec5SDimitry Andric // If the block terminator isn't analyzable, don't try to move the block 2294*0b57cec5SDimitry Andric bool B = TII->analyzeBranch(*BB, TBB, FBB, Cond); 2295*0b57cec5SDimitry Andric 2296*0b57cec5SDimitry Andric // If the block ends in an unconditional branch, move it. The prior block 2297*0b57cec5SDimitry Andric // has to have an analyzable terminator for us to move this one. Be paranoid 2298*0b57cec5SDimitry Andric // and make sure we're not trying to move the entry block of the function. 2299*0b57cec5SDimitry Andric if (!B && Cond.empty() && BB != &MF->front() && 2300*0b57cec5SDimitry Andric !TII->analyzeBranch(*OldPrior, TBB, FBB, CondPrior)) { 2301*0b57cec5SDimitry Andric BB->moveAfter(JTBB); 2302*0b57cec5SDimitry Andric OldPrior->updateTerminator(); 2303*0b57cec5SDimitry Andric BB->updateTerminator(); 2304*0b57cec5SDimitry Andric // Update numbering to account for the block being moved. 2305*0b57cec5SDimitry Andric MF->RenumberBlocks(); 2306*0b57cec5SDimitry Andric ++NumJTMoved; 2307*0b57cec5SDimitry Andric return nullptr; 2308*0b57cec5SDimitry Andric } 2309*0b57cec5SDimitry Andric 2310*0b57cec5SDimitry Andric // Create a new MBB for the code after the jump BB. 2311*0b57cec5SDimitry Andric MachineBasicBlock *NewBB = 2312*0b57cec5SDimitry Andric MF->CreateMachineBasicBlock(JTBB->getBasicBlock()); 2313*0b57cec5SDimitry Andric MachineFunction::iterator MBBI = ++JTBB->getIterator(); 2314*0b57cec5SDimitry Andric MF->insert(MBBI, NewBB); 2315*0b57cec5SDimitry Andric 2316*0b57cec5SDimitry Andric // Add an unconditional branch from NewBB to BB. 2317*0b57cec5SDimitry Andric // There doesn't seem to be meaningful DebugInfo available; this doesn't 2318*0b57cec5SDimitry Andric // correspond directly to anything in the source. 2319*0b57cec5SDimitry Andric if (isThumb2) 2320*0b57cec5SDimitry Andric BuildMI(NewBB, DebugLoc(), TII->get(ARM::t2B)) 2321*0b57cec5SDimitry Andric .addMBB(BB) 2322*0b57cec5SDimitry Andric .add(predOps(ARMCC::AL)); 2323*0b57cec5SDimitry Andric else 2324*0b57cec5SDimitry Andric BuildMI(NewBB, DebugLoc(), TII->get(ARM::tB)) 2325*0b57cec5SDimitry Andric .addMBB(BB) 2326*0b57cec5SDimitry Andric .add(predOps(ARMCC::AL)); 2327*0b57cec5SDimitry Andric 2328*0b57cec5SDimitry Andric // Update internal data structures to account for the newly inserted MBB. 2329*0b57cec5SDimitry Andric MF->RenumberBlocks(NewBB); 2330*0b57cec5SDimitry Andric 2331*0b57cec5SDimitry Andric // Update the CFG. 2332*0b57cec5SDimitry Andric NewBB->addSuccessor(BB); 2333*0b57cec5SDimitry Andric JTBB->replaceSuccessor(BB, NewBB); 2334*0b57cec5SDimitry Andric 2335*0b57cec5SDimitry Andric ++NumJTInserted; 2336*0b57cec5SDimitry Andric return NewBB; 2337*0b57cec5SDimitry Andric } 2338*0b57cec5SDimitry Andric 2339*0b57cec5SDimitry Andric /// createARMConstantIslandPass - returns an instance of the constpool 2340*0b57cec5SDimitry Andric /// island pass. 2341*0b57cec5SDimitry Andric FunctionPass *llvm::createARMConstantIslandPass() { 2342*0b57cec5SDimitry Andric return new ARMConstantIslands(); 2343*0b57cec5SDimitry Andric } 2344*0b57cec5SDimitry Andric 2345*0b57cec5SDimitry Andric INITIALIZE_PASS(ARMConstantIslands, "arm-cp-islands", ARM_CP_ISLANDS_OPT_NAME, 2346*0b57cec5SDimitry Andric false, false) 2347