[llvm] r295971 - [ARM] GlobalISel: Lower call parameters in regs

Diana Picus via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 23 05:25:43 PST 2017


Author: rovka
Date: Thu Feb 23 07:25:43 2017
New Revision: 295971

URL: http://llvm.org/viewvc/llvm-project?rev=295971&view=rev
Log:
[ARM] GlobalISel: Lower call parameters in regs

Add support for lowering calls with parameters than can fit into regs.  Use the
same ValueHandler that we used for function returns, but rename it to match its
new, extended purpose.

Modified:
    llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp
    llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll

Modified: llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp?rev=295971&r1=295970&r2=295971&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp Thu Feb 23 07:25:43 2017
@@ -48,10 +48,12 @@ static bool isSupportedType(const DataLa
 }
 
 namespace {
-struct FuncReturnHandler : public CallLowering::ValueHandler {
-  FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
-                    MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
-    : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
+/// Helper class for values going out through an ABI boundary (used for handling
+/// function return values and call parameters).
+struct OutgoingValueHandler : public CallLowering::ValueHandler {
+  OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
+                       MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
+      : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
 
   unsigned getStackAddress(uint64_t Size, int64_t Offset,
                            MachinePointerInfo &MPO) override {
@@ -155,7 +157,7 @@ bool ARMCallLowering::lowerReturnVal(Mac
   CCAssignFn *AssignFn =
       TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
 
-  FuncReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret, AssignFn);
+  OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret, AssignFn);
   return handleAssignments(MIRBuilder, SplitVTs, RetHandler);
 }
 
@@ -227,7 +229,7 @@ struct FormalArgHandler : public CallLow
     MIRBuilder.buildCopy(ValVReg, PhysReg);
   }
 
-  unsigned assignCustomValue(const llvm::ARMCallLowering::ArgInfo &Arg,
+  unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg,
                              ArrayRef<CCValAssign> VAs) override {
     CCValAssign VA = VAs[0];
     assert(VA.needsCustom() && "Value doesn't need custom handling");
@@ -309,16 +311,15 @@ bool ARMCallLowering::lowerCall(MachineI
                                 const MachineOperand &Callee,
                                 const ArgInfo &OrigRet,
                                 ArrayRef<ArgInfo> OrigArgs) const {
-  const MachineFunction &MF = MIRBuilder.getMF();
+  MachineFunction &MF = MIRBuilder.getMF();
+  const auto &TLI = *getTLI<ARMTargetLowering>();
+  const auto &DL = MF.getDataLayout();
   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
+  MachineRegisterInfo &MRI = MF.getRegInfo();
 
   if (MF.getSubtarget<ARMSubtarget>().genLongCalls())
     return false;
 
-  // FIXME: Support calling functions with arguments.
-  if (OrigArgs.size() > 0)
-    return false;
-
   // FIXME: Support calling functions with return types.
   if (!OrigRet.Ty->isVoidTy())
     return false;
@@ -327,10 +328,33 @@ bool ARMCallLowering::lowerCall(MachineI
       .addImm(0)
       .add(predOps(ARMCC::AL));
 
-  MIRBuilder.buildInstr(ARM::BLX)
-      .add(Callee)
-      // FIXME: Don't hardcode the calling conv here...
-      .addRegMask(TRI->getCallPreservedMask(MF, CallingConv::ARM_AAPCS));
+  // FIXME: This is the calling convention of the caller - we should use the
+  // calling convention of the callee instead.
+  auto CallConv = MF.getFunction()->getCallingConv();
+
+  // Create the call instruction so we can add the implicit uses of arg
+  // registers, but don't insert it yet.
+  auto MIB = MIRBuilder.buildInstrNoInsert(ARM::BLX).add(Callee).addRegMask(
+      TRI->getCallPreservedMask(MF, CallConv));
+
+  SmallVector<ArgInfo, 8> ArgInfos;
+  for (auto Arg : OrigArgs) {
+    if (!isSupportedType(DL, TLI, Arg.Ty))
+      return false;
+
+    if (!Arg.IsFixed)
+      return false;
+
+    splitToValueTypes(Arg, ArgInfos, DL, MRI);
+  }
+
+  auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv, /*IsVarArg=*/false);
+  OutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn);
+  if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
+    return false;
+
+  // Now we can add the actual call instruction to the correct basic block.
+  MIRBuilder.insertInstr(MIB);
 
   MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
       .addImm(0)

Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll?rev=295971&r1=295970&r2=295971&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll Thu Feb 23 07:25:43 2017
@@ -358,3 +358,80 @@ entry:
   notail call arm_aapcscc void @call_target()
   ret void
 }
+
+declare arm_aapcscc void @simple_params_target(i32, i32*)
+
+define arm_aapcscc void @test_call_simple_params(i32 *%a, i32 %b) {
+; CHECK-LABEL: name: test_call_simple_params
+; CHECK-DAG: [[AVREG:%[0-9]+]](p0) = COPY %r0
+; CHECK-DAG: [[BVREG:%[0-9]+]](s32) = COPY %r1
+; CHECK: ADJCALLSTACKDOWN 0, 14, _, implicit-def %sp, implicit %sp
+; CHECK-DAG: %r0 = COPY [[BVREG]]
+; CHECK-DAG: %r1 = COPY [[AVREG]]
+; CHECK: BLX @simple_params_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r1
+; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp
+entry:
+  notail call arm_aapcscc void @simple_params_target(i32 %b, i32 *%a)
+  ret void
+}
+
+declare arm_aapcscc void @ext_target(i8 signext, i8 zeroext, i16 signext, i16 zeroext)
+
+define arm_aapcscc void @test_call_ext_params(i8 %a, i16 %b) {
+; CHECK-LABEL: name: test_call_ext_params
+; CHECK-DAG: [[AVREG:%[0-9]+]](s8) = COPY %r0
+; CHECK-DAG: [[BVREG:%[0-9]+]](s16) = COPY %r1
+; CHECK: ADJCALLSTACKDOWN 0, 14, _, implicit-def %sp, implicit %sp
+; CHECK-DAG: [[SEXTA:%[0-9]+]](s32) = G_SEXT [[AVREG]](s8)
+; CHECK-DAG: %r0 = COPY [[SEXTA]]
+; CHECK-DAG: [[ZEXTA:%[0-9]+]](s32) = G_ZEXT [[AVREG]](s8)
+; CHECK-DAG: %r1 = COPY [[ZEXTA]]
+; CHECK-DAG: [[SEXTB:%[0-9]+]](s32) = G_SEXT [[BVREG]](s16)
+; CHECK-DAG: %r2 = COPY [[SEXTB]]
+; CHECK-DAG: [[ZEXTB:%[0-9]+]](s32) = G_ZEXT [[BVREG]](s16)
+; CHECK-DAG: %r3 = COPY [[ZEXTB]]
+; CHECK: BLX @ext_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r1, implicit %r2, implicit %r3
+; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp
+entry:
+  notail call arm_aapcscc void @ext_target(i8 signext %a, i8 zeroext %a, i16 signext %b, i16 zeroext %b)
+  ret void
+}
+
+declare arm_aapcs_vfpcc void @vfpcc_fp_target(float, double)
+
+define arm_aapcs_vfpcc void @test_call_vfpcc_fp_params(double %a, float %b) {
+; CHECK-LABEL: name: test_call_vfpcc_fp_params
+; CHECK-DAG: [[AVREG:%[0-9]+]](s64) = COPY %d0
+; CHECK-DAG: [[BVREG:%[0-9]+]](s32) = COPY %s2
+; CHECK: ADJCALLSTACKDOWN 0, 14, _, implicit-def %sp, implicit %sp
+; CHECK-DAG: %s0 = COPY [[BVREG]]
+; CHECK-DAG: %d1 = COPY [[AVREG]]
+; CHECK: BLX @vfpcc_fp_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %s0, implicit %d1
+; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp
+entry:
+  notail call arm_aapcs_vfpcc void @vfpcc_fp_target(float %b, double %a)
+  ret void
+}
+
+declare arm_aapcscc void @aapcscc_fp_target(float, double)
+
+define arm_aapcscc void @test_call_aapcs_fp_params(double %a, float %b) {
+; CHECK-LABEL: name: test_call_aapcs_fp_params
+; CHECK-DAG: [[A1:%[0-9]+]](s32) = COPY %r0
+; CHECK-DAG: [[A2:%[0-9]+]](s32) = COPY %r1
+; LITTLE-DAG: [[AVREG:%[0-9]+]](s64) = G_SEQUENCE [[A1]](s32), 0, [[A2]](s32), 32
+; BIG-DAG: [[AVREG:%[0-9]+]](s64) = G_SEQUENCE [[A2]](s32), 0, [[A1]](s32), 32
+; CHECK-DAG: [[BVREG:%[0-9]+]](s32) = COPY %r2
+; CHECK: ADJCALLSTACKDOWN 0, 14, _, implicit-def %sp, implicit %sp
+; CHECK-DAG: %r0 = COPY [[BVREG]]
+; CHECK-DAG: [[A1:%[0-9]+]](s32), [[A2:%[0-9]+]](s32) = G_EXTRACT [[AVREG]](s64), 0, 32
+; LITTLE-DAG: %r2 = COPY [[A1]]
+; LITTLE-DAG: %r3 = COPY [[A2]]
+; BIG-DAG: %r2 = COPY [[A2]]
+; BIG-DAG: %r3 = COPY [[A1]]
+; CHECK: BLX @aapcscc_fp_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r2, implicit %r3
+; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp
+entry:
+  notail call arm_aapcscc void @aapcscc_fp_target(float %b, double %a)
+  ret void
+}




More information about the llvm-commits mailing list