diff options
Diffstat (limited to 'lib/Target/ARM/ARMConstantIslandPass.cpp')
-rw-r--r-- | lib/Target/ARM/ARMConstantIslandPass.cpp | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index ce264eeef9..29405eb65d 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -275,6 +275,7 @@ namespace { private: void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs); + bool BBHasFallthrough(MachineBasicBlock *MBB); CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI); unsigned getCPELogAlign(const MachineInstr *CPEMI); void scanFunctionJumpTables(); @@ -382,7 +383,9 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) { << MCP->getConstants().size() << " CP entries, aligned to " << MCP->getConstantPoolAlignment() << " bytes *****\n"); - TII = (const ARMBaseInstrInfo*)MF->getTarget().getInstrInfo(); + TII = (const ARMBaseInstrInfo *)MF->getTarget() + .getSubtargetImpl() + ->getInstrInfo(); AFI = MF->getInfo<ARMFunctionInfo>(); STI = &MF->getTarget().getSubtarget<ARMSubtarget>(); @@ -529,7 +532,7 @@ ARMConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) { // identity mapping of CPI's to CPE's. const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants(); - const DataLayout &TD = *MF->getTarget().getDataLayout(); + const DataLayout &TD = *MF->getSubtarget().getDataLayout(); for (unsigned i = 0, e = CPs.size(); i != e; ++i) { unsigned Size = TD.getTypeAllocSize(CPs[i].getType()); assert(Size >= 4 && "Too small constant pool entry"); @@ -554,9 +557,7 @@ ARMConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) { InsPoint[a] = CPEMI; // Add a new CPEntry, but no corresponding CPUser yet. - std::vector<CPEntry> CPEs; - CPEs.push_back(CPEntry(CPEMI, i)); - CPEntries.push_back(CPEs); + CPEntries.emplace_back(1, CPEntry(CPEMI, i)); ++NumCPEs; DEBUG(dbgs() << "Moved CPI#" << i << " to end of function, size = " << Size << ", align = " << Align <<'\n'); @@ -566,7 +567,7 @@ ARMConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) { /// BBHasFallthrough - Return true if the specified basic block can fallthrough /// into the block immediately after it. -static bool BBHasFallthrough(MachineBasicBlock *MBB) { +bool ARMConstantIslands::BBHasFallthrough(MachineBasicBlock *MBB) { // Get the next machine basic block in the function. MachineFunction::iterator MBBI = MBB; // Can't fall off end of function. @@ -574,12 +575,15 @@ static bool BBHasFallthrough(MachineBasicBlock *MBB) { return false; MachineBasicBlock *NextBB = std::next(MBBI); - for (MachineBasicBlock::succ_iterator I = MBB->succ_begin(), - E = MBB->succ_end(); I != E; ++I) - if (*I == NextBB) - return true; + if (std::find(MBB->succ_begin(), MBB->succ_end(), NextBB) == MBB->succ_end()) + return false; - return false; + // Try to analyze the end of the block. A potential fallthrough may already + // have an unconditional branch for whatever reason. + MachineBasicBlock *TBB, *FBB; + SmallVector<MachineOperand, 4> Cond; + bool TooDifficult = TII->AnalyzeBranch(*MBB, TBB, FBB, Cond); + return TooDifficult || FBB == nullptr; } /// findConstPoolEntry - Given the constpool index and CONSTPOOL_ENTRY MI, @@ -1203,7 +1207,8 @@ bool ARMConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset, unsigned Growth; if (isWaterInRange(UserOffset, WaterBB, U, Growth) && (WaterBB->getNumber() < U.HighWaterMark->getNumber() || - NewWaterList.count(WaterBB)) && Growth < BestGrowth) { + NewWaterList.count(WaterBB) || WaterBB == U.MI->getParent()) && + Growth < BestGrowth) { // This is the least amount of required padding seen so far. BestGrowth = Growth; WaterIter = IP; @@ -1309,7 +1314,12 @@ void ARMConstantIslands::createNewWater(unsigned CPUserIndex, // Back past any possible branches (allow for a conditional and a maximally // long unconditional). if (BaseInsertOffset + 8 >= UserBBI.postOffset()) { - BaseInsertOffset = UserBBI.postOffset() - UPad - 8; + // Ensure BaseInsertOffset is larger than the offset of the instruction + // following UserMI so that the loop which searches for the split point + // iterates at least once. + BaseInsertOffset = + std::max(UserBBI.postOffset() - UPad - 8, + UserOffset + TII->GetInstSizeInBytes(UserMI) + 1); DEBUG(dbgs() << format("Move inside block: %#x\n", BaseInsertOffset)); } unsigned EndInsertOffset = BaseInsertOffset + 4 + UPad + @@ -1352,6 +1362,11 @@ void ARMConstantIslands::createNewWater(unsigned CPUserIndex, if (CC != ARMCC::AL) MI = LastIT; } + + // We really must not split an IT block. + DEBUG(unsigned PredReg; + assert(!isThumb || getITInstrPredicate(MI, PredReg) == ARMCC::AL)); + NewMBB = splitBlockBeforeInstr(MI); } |