[llvm] 9de1241 - [PowerPC][Future] Branch Distance Estimation For Prefixed Instructions
Stefan Pintilie via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 30 06:58:18 PST 2020
Author: Stefan Pintilie
Date: 2020-01-30T08:54:33-06:00
New Revision: 9de1241bb2dd1b0e39bb695c701f2d299776ff6b
URL: https://github.com/llvm/llvm-project/commit/9de1241bb2dd1b0e39bb695c701f2d299776ff6b
DIFF: https://github.com/llvm/llvm-project/commit/9de1241bb2dd1b0e39bb695c701f2d299776ff6b.diff
LOG: [PowerPC][Future] Branch Distance Estimation For Prefixed Instructions
By adding the prefixed instructions the branch distances are no longer
computed correctly. Since prefixed instructions cannot cross a 64 byte
boundary we have to assume that a prefixed instruction may have a nop
prepended to it. This patch tries to take that nop into consideration
when computing the size of basic blocks.
Differential Revision: https://reviews.llvm.org/D72572
Added:
llvm/test/CodeGen/PowerPC/alignlongjumptest.mir
Modified:
llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/PowerPC/PPCBranchSelector.cpp b/llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
index 31187c7cee55..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 {
@@ -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;
diff --git a/llvm/test/CodeGen/PowerPC/alignlongjumptest.mir b/llvm/test/CodeGen/PowerPC/alignlongjumptest.mir
new file mode 100644
index 000000000000..041f0f9747fe
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/alignlongjumptest.mir
@@ -0,0 +1,84 @@
+# RUN: llc -mcpu=future -mtriple=powerpc64le-unknown-unknown %s \
+# RUN: -start-before=ppc-branch-select -verify-machineinstrs \
+# RUN: -filetype=obj -o - | llvm-objdump -mcpu=future -d -r - | \
+# RUN: FileCheck --check-prefix=CHECK-LE %s
+# RUN: llc -mcpu=future -mtriple=powerpc64-unknown-unknown %s \
+# RUN: -start-before=ppc-branch-select -verify-machineinstrs \
+# RUN: -filetype=obj -o - | llvm-objdump -mcpu=future -d -r - | \
+# RUN: FileCheck --check-prefix=CHECK-BE %s
+
+# The purpose of this test is to check that long branches are selected correctly
+# when we have prefixed instructions that may require alignment. Prefixed
+# instructions may require alignment and so an additional 4 bytes may be added.
+# If those 4 bytes put the target of the branch past the range of a short branch
+# then we should use a long branch like in this test.
+
+---
+name: longbranchtest
+alignment: 16
+exposesReturnsTwice: false
+legalized: false
+regBankSelected: false
+selected: false
+failedISel: false
+tracksRegLiveness: true
+hasWinCFI: false
+registers: []
+liveins:
+ - { reg: '$x3', virtual-reg: '' }
+frameInfo:
+ isFrameAddressTaken: false
+ isReturnAddressTaken: false
+ hasStackMap: false
+ hasPatchPoint: false
+ stackSize: 0
+ offsetAdjustment: 0
+ maxAlignment: 1
+ adjustsStack: false
+ hasCalls: false
+ stackProtector: ''
+ maxCallFrameSize: 0
+ cvBytesOfCalleeSavedRegisters: 0
+ hasOpaqueSPAdjustment: false
+ hasVAStart: false
+ hasMustTailInVarArgFunc: false
+ localFrameSize: 0
+ savePoint: ''
+ restorePoint: ''
+fixedStack: []
+stack: []
+callSites: []
+constants: []
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ successors: %bb.1(0x30000000), %bb.2(0x50000000)
+ liveins: $x3
+ renamable $cr0 = CMPLWI killed renamable $r3, 0, implicit $x3
+ BCC 76, killed renamable $cr0, %bb.1
+ bb.2:
+ renamable $x3 = LI8 2
+ INLINEASM &".space 32744", 1
+ renamable $x3 = PADDI8 $x3, 13
+ BLR8 implicit $lr8, implicit $rm, implicit killed $x3
+ bb.1:
+ renamable $x3 = LI8 1
+ INLINEASM &".space 32744", 1
+ renamable $x3 = PADDI8 $x3, 21
+ BLR8 implicit $lr8, implicit $rm, implicit killed $x3
+
+...
+
+# Check for the long branch.
+# CHECK-LE: 08 00 82 4{{[01]}} b{{[tf]}} 2, .+8
+# CHECK-LE-NEXT: fc 7f 00 48 b .+32764
+# CHECK-LE-DAG: paddi 3, 3, 13, 0
+# CHECK-LE-DAG: paddi 3, 3, 21, 0
+# CHECK-LE: blr
+# CHECK-BE: 4{{[01]}} 82 00 08 b{{[tf]}} 2, .+8
+# CHECK-BE-NEXT: 48 00 7f fc b .+32764
+# CHECK-BE-DAG: paddi 3, 3, 13, 0
+# CHECK-BE-DAG: paddi 3, 3, 21, 0
+# CHECK-BE: blr
+
+
More information about the llvm-commits
mailing list