Index: lib/Target/ARM/ARMConstantIslandPass.cpp =================================================================== --- lib/Target/ARM/ARMConstantIslandPass.cpp +++ lib/Target/ARM/ARMConstantIslandPass.cpp @@ -292,11 +292,11 @@ bool decrementCPEReferenceCount(unsigned CPI, MachineInstr* CPEMI); unsigned getCombinedIndex(const MachineInstr *CPEMI); int findInRangeCPEntry(CPUser& U, unsigned UserOffset); - bool findAvailableWater(CPUser&U, unsigned UserOffset, - water_iterator &WaterIter); + bool findAvailableWater(CPUser &U, unsigned UserOffset, + water_iterator &WaterIter, bool IgnoreGrowth); void createNewWater(unsigned CPUserIndex, unsigned UserOffset, MachineBasicBlock *&NewMBB); - bool handleConstantPoolUser(unsigned CPUserIndex); + bool handleConstantPoolUser(unsigned CPUserIndex, bool IgnoreGrowth); void removeDeadCPEMI(MachineInstr *CPEMI); bool removeUnusedCPEntries(); bool isCPEntryInRange(MachineInstr *MI, unsigned UserOffset, @@ -456,7 +456,7 @@ DEBUG(dbgs() << "Beginning CP iteration #" << NoCPIters << '\n'); bool CPChange = false; for (unsigned i = 0, e = CPUsers.size(); i != e; ++i) - CPChange |= handleConstantPoolUser(i); + CPChange |= handleConstantPoolUser(i, NoCPIters >= 15 /*Ignore Growth*/); if (CPChange && ++NoCPIters > 30) report_fatal_error("Constant Island pass failed to converge!"); DEBUG(dumpBBs()); @@ -1293,7 +1293,8 @@ /// move to a lower address, so search backward from the end of the list and /// prefer the first water that is in range. bool ARMConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset, - water_iterator &WaterIter) { + water_iterator &WaterIter, + bool IgnoreGrowth) { if (WaterList.empty()) return false; @@ -1309,6 +1310,8 @@ // should be relatively uncommon and when it does happen, we want to be // sure to take advantage of it for all the CPEs near that block, so that // we don't insert more branches than necessary. + // When IgnoreGrowth is true, we try to find the lowerest address after (or + // equal to) user MI's BB no matter of padding growth. unsigned Growth; if (isWaterInRange(UserOffset, WaterBB, U, Growth) && (WaterBB->getNumber() < U.HighWaterMark->getNumber() || @@ -1319,9 +1322,10 @@ WaterIter = IP; DEBUG(dbgs() << "Found water after BB#" << WaterBB->getNumber() << " Growth=" << Growth << '\n'); - + if (IgnoreGrowth && WaterBB == U.MI->getParent()) + return true; // Keep looking unless it is perfect. - if (BestGrowth == 0) + if (!IgnoreGrowth && BestGrowth == 0) return true; } if (IP == B) @@ -1479,7 +1483,8 @@ /// is out-of-range. If so, pick up the constant pool value and move it some /// place in-range. Return true if we changed any addresses (thus must run /// another pass of branch lengthening), false otherwise. -bool ARMConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) { +bool ARMConstantIslands::handleConstantPoolUser(unsigned CPUserIndex, + bool IgnoreGrowth) { CPUser &U = CPUsers[CPUserIndex]; MachineInstr *UserMI = U.MI; MachineInstr *CPEMI = U.CPEMI; @@ -1502,7 +1507,7 @@ MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock(); MachineBasicBlock *NewMBB; water_iterator IP; - if (findAvailableWater(U, UserOffset, IP)) { + if (findAvailableWater(U, UserOffset, IP, IgnoreGrowth)) { DEBUG(dbgs() << "Found water in range\n"); MachineBasicBlock *WaterBB = *IP;