Consider unknown alignment caused by OptimizeThumb2Instructions().

This function runs after all constant islands have been placed, and may
shrink some instructions to their 2-byte forms.  This can actually cause
some constant pool entries to move out of range because of growing
alignment padding.

Treat instructions that may be shrunk the same as inline asm - they
erode the known alignment bits.

Also reinstate an old assertion in verify(). It is correct now that
basic block offsets include alignments.

Add a single large test case that will hopefully exercise many parts of
the constant island pass.

<rdar://problem/10670199>

llvm-svn: 147885
This commit is contained in:
Jakob Stoklund Olesen 2012-01-10 22:32:14 +00:00
parent 6466bb6919
commit 7f7f8a2e77
2 changed files with 1425 additions and 4 deletions

View File

@ -309,6 +309,7 @@ namespace {
bool FixUpConditionalBr(ImmBranch &Br);
bool FixUpUnconditionalBr(ImmBranch &Br);
bool UndoLRSpillRestore();
bool mayOptimizeThumb2Instruction(const MachineInstr *MI) const;
bool OptimizeThumb2Instructions();
bool OptimizeThumb2Branches();
bool ReorderThumb2JumpTables();
@ -347,10 +348,8 @@ void ARMConstantIslands::verify() {
for (unsigned i = 0, e = CPUsers.size(); i != e; ++i) {
CPUser &U = CPUsers[i];
unsigned UserOffset = GetUserOffset(U);
unsigned CPEOffset = GetOffsetOf(U.CPEMI);
unsigned Disp = UserOffset < CPEOffset ? CPEOffset - UserOffset :
UserOffset - CPEOffset;
assert(Disp <= U.getMaxDisp() || "Constant pool entry out of range!");
assert(CPEIsInRange(U.MI, UserOffset, U.CPEMI, U.getMaxDisp(), U.NegOk) &&
"Constant pool entry out of range!");
}
#endif
}
@ -807,6 +806,9 @@ void ARMConstantIslands::ComputeBlockSize(MachineBasicBlock *MBB) {
// The actual size may be smaller, but still a multiple of the instr size.
if (I->isInlineAsm())
BBI.Unalign = isThumb ? 1 : 2;
// Also consider instructions that may be shrunk later.
else if (isThumb && mayOptimizeThumb2Instruction(I))
BBI.Unalign = 1;
}
// tBR_JTr contains a .align 2 directive.
@ -1676,6 +1678,25 @@ bool ARMConstantIslands::UndoLRSpillRestore() {
return MadeChange;
}
// mayOptimizeThumb2Instruction - Returns true if OptimizeThumb2Instructions
// below may shrink MI.
bool
ARMConstantIslands::mayOptimizeThumb2Instruction(const MachineInstr *MI) const {
switch(MI->getOpcode()) {
// OptimizeThumb2Instructions.
case ARM::t2LEApcrel:
case ARM::t2LDRpci:
// OptimizeThumb2Branches.
case ARM::t2B:
case ARM::t2Bcc:
case ARM::tBcc:
// OptimizeThumb2JumpTables.
case ARM::t2BR_JT:
return true;
}
return false;
}
bool ARMConstantIslands::OptimizeThumb2Instructions() {
bool MadeChange = false;

File diff suppressed because it is too large Load Diff