aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCBranchSelector.cpp')
-rw-r--r--llvm/lib/Target/PowerPC/PPCBranchSelector.cpp35
1 files changed, 33 insertions, 2 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCBranchSelector.cpp b/llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
index cdff4d383d23..47b9e97f0d67 100644
--- a/llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
+++ b/llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
@@ -31,6 +31,9 @@ using namespace llvm;
#define DEBUG_TYPE "ppc-branch-select"
STATISTIC(NumExpanded, "Number of branches expanded to long format");
+STATISTIC(NumPrefixed, "Number of prefixed instructions");
+STATISTIC(NumPrefixedAligned,
+ "Number of prefixed instructions that have been aligned");
namespace {
struct PPCBSel : public MachineFunctionPass {
@@ -82,7 +85,7 @@ FunctionPass *llvm::createPPCBranchSelectionPass() {
unsigned PPCBSel::GetAlignmentAdjustment(MachineBasicBlock &MBB,
unsigned Offset) {
const Align Alignment = MBB.getAlignment();
- if (Alignment == Align::None())
+ if (Alignment == Align(1))
return 0;
const Align ParentAlign = MBB.getParent()->getAlignment();
@@ -134,10 +137,38 @@ unsigned PPCBSel::ComputeBlockSizes(MachineFunction &Fn) {
}
unsigned BlockSize = 0;
+ unsigned UnalignedBytesRemaining = 0;
for (MachineInstr &MI : *MBB) {
- BlockSize += TII->getInstSizeInBytes(MI);
+ unsigned MINumBytes = TII->getInstSizeInBytes(MI);
if (MI.isInlineAsm() && (FirstImpreciseBlock < 0))
FirstImpreciseBlock = MBB->getNumber();
+ if (TII->isPrefixed(MI.getOpcode())) {
+ NumPrefixed++;
+
+ // All 8 byte instructions may require alignment. Each 8 byte
+ // instruction may be aligned by another 4 bytes.
+ // This means that an 8 byte instruction may require 12 bytes
+ // (8 for the instruction itself and 4 for the alignment nop).
+ // This will happen if an 8 byte instruction can be aligned to 64 bytes
+ // by only adding a 4 byte nop.
+ // We don't know the alignment at this point in the code so we have to
+ // adopt a more pessimistic approach. If an instruction may need
+ // alignment we assume that it does need alignment and add 4 bytes to
+ // it. As a result we may end up with more long branches than before
+ // but we are in the safe position where if we need a long branch we
+ // have one.
+ // The if statement checks to make sure that two 8 byte instructions
+ // are at least 64 bytes away from each other. It is not possible for
+ // two instructions that both need alignment to be within 64 bytes of
+ // each other.
+ if (!UnalignedBytesRemaining) {
+ BlockSize += 4;
+ UnalignedBytesRemaining = 60;
+ NumPrefixedAligned++;
+ }
+ }
+ UnalignedBytesRemaining -= std::min(UnalignedBytesRemaining, MINumBytes);
+ BlockSize += MINumBytes;
}
BlockSizes[MBB->getNumber()].first = BlockSize;