[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