[llvm] r366669 - [IPRA][ARM] Make use of the "returned" parameter attribute

Oliver Stannard via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 22 01:44:39 PDT 2019


Author: ostannard
Date: Mon Jul 22 01:44:36 2019
New Revision: 366669

URL: http://llvm.org/viewvc/llvm-project?rev=366669&view=rev
Log:
[IPRA][ARM] Make use of the "returned" parameter attribute

ARM has code to recognise uses of the "returned" function parameter
attribute which guarantee that the value passed to the function in r0
will be returned in r0 unmodified. IPRA replaces the regmask on call
instructions, so needs to be told about this to avoid reverting the
optimisation.

Differential revision: https://reviews.llvm.org/D64986

Added:
    llvm/trunk/test/CodeGen/ARM/ipra-r0-returned.ll
Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
    llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=366669&r1=366668&r2=366669&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Mon Jul 22 01:44:36 2019
@@ -9615,6 +9615,8 @@ void SelectionDAGISel::LowerArguments(co
       Flags.setOrigAlign(OriginalAlignment);
       if (ArgCopyElisionCandidates.count(&Arg))
         Flags.setCopyElisionCandidate();
+      if (Arg.hasAttribute(Attribute::Returned))
+        Flags.setReturned();
 
       MVT RegisterVT = TLI->getRegisterTypeForCallingConv(
           *CurDAG->getContext(), F.getCallingConv(), VT);

Modified: llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp?rev=366669&r1=366668&r2=366669&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp Mon Jul 22 01:44:36 2019
@@ -2097,6 +2097,12 @@ void ARMFrameLowering::determineCalleeSa
     AFI->setLRIsSpilledForFarJump(true);
   }
   AFI->setLRIsSpilled(SavedRegs.test(ARM::LR));
+
+  // If we have the "returned" parameter attribute which guarantees that we
+  // return the value which was passed in r0 unmodified (e.g. C++ 'structors),
+  // record that fact for IPRA.
+  if (AFI->getPreservesR0())
+    SavedRegs.set(ARM::R0);
 }
 
 MachineBasicBlock::iterator ARMFrameLowering::eliminateCallFramePseudoInstr(

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=366669&r1=366668&r2=366669&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Jul 22 01:44:36 2019
@@ -3898,6 +3898,12 @@ SDValue ARMTargetLowering::LowerFormalAr
         // Transform the arguments in physical registers into virtual ones.
         unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC);
         ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
+
+        // If this value is passed in r0 and has the returned attribute (e.g.
+        // C++ 'structors), record this fact for later use.
+        if (VA.getLocReg() == ARM::R0 && Ins[VA.getValNo()].Flags.isReturned()) {
+          AFI->setPreservesR0();
+        }
       }
 
       // If this is an 8 or 16-bit value, it is really passed promoted

Modified: llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h?rev=366669&r1=366668&r2=366669&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h Mon Jul 22 01:44:36 2019
@@ -130,6 +130,10 @@ class ARMFunctionInfo : public MachineFu
   /// The amount the literal pool has been increasedby due to promoted globals.
   int PromotedGlobalsIncrease = 0;
 
+  /// True if r0 will be preserved by a call to this function (e.g. C++
+  /// con/destructors).
+  bool PreservesR0 = false;
+
 public:
   ARMFunctionInfo() = default;
 
@@ -247,6 +251,9 @@ public:
   }
 
   DenseMap<unsigned, unsigned> EHPrologueRemappedRegs;
+
+  void setPreservesR0() { PreservesR0 = true; }
+  bool getPreservesR0() const { return PreservesR0; }
 };
 
 } // end namespace llvm

Added: llvm/trunk/test/CodeGen/ARM/ipra-r0-returned.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ipra-r0-returned.ll?rev=366669&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/ipra-r0-returned.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/ipra-r0-returned.ll Mon Jul 22 01:44:36 2019
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple armv7a--none-eabi -enable-ipra=false < %s | FileCheck %s
+; RUN: llc -mtriple armv7a--none-eabi -enable-ipra=true  < %s | FileCheck %s
+
+define i32 @returns_r0(i32 returned %a)  {
+entry:
+  call void asm sideeffect "", "~{r0}"()
+  ret i32 %a
+}
+
+define i32 @test(i32 %a) {
+; CHECK-LABEL: test:
+entry:
+; CHECK-NOT: r0
+; CHECK: bl      returns_r0
+; CHECK-NOT: r0
+  %b = call i32 @returns_r0(i32 %a)
+  ret i32 %a
+}




More information about the llvm-commits mailing list