[llvm] r280545 - [PowerPC] For larger offsets, when possible, fold offset into addis toc at ha

Hal Finkel via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 2 14:37:07 PDT 2016


Author: hfinkel
Date: Fri Sep  2 16:37:07 2016
New Revision: 280545

URL: http://llvm.org/viewvc/llvm-project?rev=280545&view=rev
Log:
[PowerPC] For larger offsets, when possible, fold offset into addis toc at ha

When we have an offset into a global, etc. that is accessed relative to the TOC
base pointer, and the offset is larger than the minimum alignment of the global
itself and the TOC base pointer (which is 8-byte aligned), we can still fold
the @toc at ha into the memory access, but we must update the addis instruction's
symbol reference with the offset as the symbol addend. When there is only one
use of the addi to be folded and only one use of the addis that would need its
symbol's offset adjusted, then we can make the adjustment and fold the @toc at l
into the memory access.

Modified:
    llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
    llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
    llvm/trunk/test/CodeGen/PowerPC/peephole-align.ll

Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=280545&r1=280544&r2=280545&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Fri Sep  2 16:37:07 2016
@@ -673,6 +673,13 @@ void PPCAsmPrinter::EmitInstruction(cons
     const MCExpr *Exp =
       MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA,
                               OutContext);
+
+    if (!MO.isJTI() && MO.getOffset())
+      Exp = MCBinaryExpr::createAdd(Exp,
+                                    MCConstantExpr::create(MO.getOffset(),
+                                                           OutContext),
+                                    OutContext);
+
     TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
     EmitToStreamer(*OutStreamer, TmpInst);
     return;

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=280545&r1=280544&r2=280545&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Fri Sep  2 16:37:07 2016
@@ -4381,9 +4381,30 @@ void PPCDAGToDAGISel::PeepholePPC64() {
       MaxDisplacement = std::min((int) GV->getAlignment() - 1, MaxDisplacement);
     }
 
+    bool UpdateHBase = false;
+    SDValue HBase = Base.getOperand(0);
+
     int Offset = N->getConstantOperandVal(FirstOp);
-    if (Offset < 0 || Offset > MaxDisplacement)
-      continue;
+    if (Offset < 0 || Offset > MaxDisplacement) {
+      // If we have a addi(toc at l)/addis(toc at ha) pair, and the addis has only
+      // one use, then we can do this for any offset, we just need to also
+      // update the offset (i.e. the symbol addend) on the addis also.
+      if (Base.getMachineOpcode() != PPC::ADDItocL)
+        continue;
+
+      if (!HBase.isMachineOpcode() ||
+          HBase.getMachineOpcode() != PPC::ADDIStocHA)
+        continue;
+
+      if (!Base.hasOneUse() || !HBase.hasOneUse())
+        continue;
+
+      SDValue HImmOpnd = HBase.getOperand(1);
+      if (HImmOpnd != ImmOpnd)
+        continue;
+
+      UpdateHBase = true;
+    }
 
     // We found an opportunity.  Reverse the operands from the add
     // immediate and substitute them into the load or store.  If
@@ -4426,6 +4447,10 @@ void PPCDAGToDAGISel::PeepholePPC64() {
       (void)CurDAG->UpdateNodeOperands(N, ImmOpnd, Base.getOperand(0),
                                        N->getOperand(2));
 
+    if (UpdateHBase)
+      (void)CurDAG->UpdateNodeOperands(HBase.getNode(), HBase.getOperand(0),
+                                       ImmOpnd);
+
     // The add-immediate may now be dead, in which case remove it.
     if (Base.getNode()->use_empty())
       CurDAG->RemoveDeadNode(Base.getNode());

Modified: llvm/trunk/test/CodeGen/PowerPC/peephole-align.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/peephole-align.ll?rev=280545&r1=280544&r2=280545&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/peephole-align.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/peephole-align.ll Fri Sep  2 16:37:07 2016
@@ -227,11 +227,9 @@ entry:
   ret void
 }
 
-; register 3 is the return value, so it should be chosen
 ; CHECK-LABEL: test_singleuse:
-; CHECK: addis 3, 2, d2v at toc@ha
-; CHECK: addi 3, 3, d2v at toc@l
-; CHECK: ld 3, 8(3)
+; CHECK: addis [[REG:[0-9]+]], 2, d2v at toc@ha+8
+; CHECK: ld 3, d2v at toc@l+8([[REG]])
 define i64 @test_singleuse() nounwind {
 entry:
   %0 = load i64, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 1), align 8




More information about the llvm-commits mailing list