Make sure ARM constant island pass does not break up an IT block. If the split point is in the middle of an IT block, it should move it up to just above the IT instruction. rdar://8302637

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110947 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-08-12 20:30:05 +00:00
parent 642eb02045
commit 719510a178

View File

@ -18,6 +18,7 @@
#include "ARMAddressingModes.h"
#include "ARMMachineFunctionInfo.h"
#include "ARMInstrInfo.h"
#include "Thumb2InstrInfo.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@ -1181,11 +1182,13 @@ void ARMConstantIslands::CreateNewWater(unsigned CPUserIndex,
MachineBasicBlock::iterator MI = UserMI;
++MI;
unsigned CPUIndex = CPUserIndex+1;
unsigned NumCPUsers = CPUsers.size();
MachineInstr *LastIT = 0;
for (unsigned Offset = UserOffset+TII->GetInstSizeInBytes(UserMI);
Offset < BaseInsertOffset;
Offset += TII->GetInstSizeInBytes(MI),
MI = llvm::next(MI)) {
if (CPUIndex < CPUsers.size() && CPUsers[CPUIndex].MI == MI) {
MI = llvm::next(MI)) {
if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {
CPUser &U = CPUsers[CPUIndex];
if (!OffsetIsInRange(Offset, EndInsertOffset,
U.MaxDisp, U.NegOk, U.IsSoImm)) {
@ -1197,9 +1200,23 @@ void ARMConstantIslands::CreateNewWater(unsigned CPUserIndex,
EndInsertOffset += CPUsers[CPUIndex].CPEMI->getOperand(2).getImm();
CPUIndex++;
}
// Remember the last IT instruction.
if (MI->getOpcode() == ARM::t2IT)
LastIT = MI;
}
DEBUG(errs() << "Split in middle of big block\n");
NewMBB = SplitBlockBeforeInstr(prior(MI));
--MI;
// Avoid splitting an IT block.
if (LastIT) {
unsigned PredReg = 0;
ARMCC::CondCodes CC = llvm::getITInstrPredicate(MI, PredReg);
if (CC != ARMCC::AL)
MI = LastIT;
}
NewMBB = SplitBlockBeforeInstr(MI);
}
}