[llvm] 85b4d28 - [ARM] Register pressure with -mthumb forces register reload before each call

David Green via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 31 12:00:54 PDT 2020


Author: Prathamesh Kulkarni
Date: 2020-08-31T20:00:30+01:00
New Revision: 85b4d286d7b19f78135277fe068b1d90f595f8bf

URL: https://github.com/llvm/llvm-project/commit/85b4d286d7b19f78135277fe068b1d90f595f8bf
DIFF: https://github.com/llvm/llvm-project/commit/85b4d286d7b19f78135277fe068b1d90f595f8bf.diff

LOG: [ARM] Register pressure with -mthumb forces register reload before each call

This patch implements the foldMemoryOperand hook in Thumb1InstrInfo,
allowing tBLXr and a spilled function address to be combined back into a
tBL. This can help with codesize at Oz, especailly in the tinycrypt
library.

Differential Revision: https://reviews.llvm.org/D79785

Added: 
    llvm/test/CodeGen/ARM/minsize-call-cse-2.ll
    llvm/test/CodeGen/ARM/minsize-call-cse-3.ll

Modified: 
    llvm/lib/Target/ARM/Thumb1InstrInfo.cpp
    llvm/lib/Target/ARM/Thumb1InstrInfo.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp b/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp
index 79afa378cb62..7eec05df88ca 100644
--- a/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp
+++ b/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp
@@ -152,3 +152,37 @@ bool Thumb1InstrInfo::canCopyGluedNodeDuringSchedule(SDNode *N) const {
 
   return false;
 }
+
+MachineInstr *Thumb1InstrInfo::foldMemoryOperandImpl(
+    MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops,
+    MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI,
+    LiveIntervals *LIS) const {
+  // Replace:
+  // ldr Rd, func address
+  // blx Rd
+  // with:
+  // bl func
+
+  if (MI.getOpcode() == ARM::tBLXr && LoadMI.getOpcode() == ARM::tLDRpci &&
+      MI.getParent() == LoadMI.getParent()) {
+    unsigned CPI = LoadMI.getOperand(1).getIndex();
+    const MachineConstantPool *MCP = MF.getConstantPool();
+    if (CPI >= MCP->getConstants().size())
+      return nullptr;
+    const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];
+    assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry");
+    const Function *Callee = dyn_cast<Function>(CPE.Val.ConstVal);
+    if (!Callee)
+      return nullptr;
+    const char *FuncName = MF.createExternalSymbolName(Callee->getName());
+    MachineInstrBuilder MIB =
+        BuildMI(*MI.getParent(), InsertPt, MI.getDebugLoc(), get(ARM::tBL))
+            .add(predOps(ARMCC::AL))
+            .addExternalSymbol(FuncName);
+    for (auto &MO : MI.implicit_operands())
+      MIB.add(MO);
+    return MIB.getInstr();
+  }
+
+  return nullptr;
+}

diff  --git a/llvm/lib/Target/ARM/Thumb1InstrInfo.h b/llvm/lib/Target/ARM/Thumb1InstrInfo.h
index 017b7222337c..bc4da451ca5d 100644
--- a/llvm/lib/Target/ARM/Thumb1InstrInfo.h
+++ b/llvm/lib/Target/ARM/Thumb1InstrInfo.h
@@ -53,6 +53,13 @@ class Thumb1InstrInfo : public ARMBaseInstrInfo {
                             const TargetRegisterInfo *TRI) const override;
 
   bool canCopyGluedNodeDuringSchedule(SDNode *N) const override;
+
+protected:
+  virtual MachineInstr *foldMemoryOperandImpl(
+      MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops,
+      MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI,
+      LiveIntervals *LIS = nullptr) const override;
+
 private:
   void expandLoadStackGuard(MachineBasicBlock::iterator MI) const override;
 };

diff  --git a/llvm/test/CodeGen/ARM/minsize-call-cse-2.ll b/llvm/test/CodeGen/ARM/minsize-call-cse-2.ll
new file mode 100644
index 000000000000..4f9e508c1c97
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/minsize-call-cse-2.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "thumbv6m-arm-none-eabi"
+
+; CHECK-LABEL: f:
+; CHECK: bl g
+; CHECK: blx r
+; CHECK: bl g
+; CHECK: bl g
+define void @f(i32* %p, i32 %x, i32 %y, i32 %z) minsize optsize {
+entry:
+  call void @g(i32* %p, i32 %x, i32 %y, i32 %z)
+  call void @g(i32* %p, i32 %x, i32 %y, i32 %z)
+  call void @g(i32* %p, i32 %x, i32 %y, i32 %z)
+  call void @g(i32* %p, i32 %x, i32 %y, i32 %z)
+  ret void
+}
+
+declare void @g(i32*,i32,i32,i32)

diff  --git a/llvm/test/CodeGen/ARM/minsize-call-cse-3.ll b/llvm/test/CodeGen/ARM/minsize-call-cse-3.ll
new file mode 100644
index 000000000000..abe1f0347e5d
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/minsize-call-cse-3.ll
@@ -0,0 +1,16 @@
+; RUN: llc < %s
+; Verify that we don't crash on indirect function calls
+; in Thumb1InstrInfo::foldMemoryOperand.
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "thumbv6m-arm-none-eabi"
+
+; Function Attrs: minsize nounwind optsize
+define void @test(i32* %p, i32 %x, i32 %y, i32 %z) {
+entry:
+  tail call void inttoptr (i32 19088743 to void (i32*, i32, i32, i32)*)(i32* %p, i32 %x, i32 %y, i32 %z)
+  tail call void inttoptr (i32 19088743 to void (i32*, i32, i32, i32)*)(i32* %p, i32 %x, i32 %y, i32 %z)
+  tail call void inttoptr (i32 19088743 to void (i32*, i32, i32, i32)*)(i32* %p, i32 %x, i32 %y, i32 %z)
+  tail call void inttoptr (i32 19088743 to void (i32*, i32, i32, i32)*)(i32* %p, i32 %x, i32 %y, i32 %z)
+  ret void
+}


        


More information about the llvm-commits mailing list