From 719510a178a910feb1db707140011c32a30992c4 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 12 Aug 2010 20:30:05 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMConstantIslandPass.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index 224842d0700..9f4de8c7615 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -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); } }