[llvm] r279987 - GlobalISel: rework CallLowering so that it can be used for libcalls too.

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 29 12:07:09 PDT 2016


Author: tnorthover
Date: Mon Aug 29 14:07:08 2016
New Revision: 279987

URL: http://llvm.org/viewvc/llvm-project?rev=279987&view=rev
Log:
GlobalISel: rework CallLowering so that it can be used for libcalls too.

There should be no functional change here, I'm just making the implementation
of "frem" (to libcall) legalization easier for a followup.

Added:
    llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp
Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h
    llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt
    llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
    llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
    llvm/trunk/lib/Target/AArch64/AArch64CallLowering.h

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h?rev=279987&r1=279986&r2=279987&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h Mon Aug 29 14:07:08 2016
@@ -16,11 +16,13 @@
 #define LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H
 
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/IR/Function.h"
 
 namespace llvm {
 // Forward declarations.
 class MachineIRBuilder;
+class MachineOperand;
 class TargetLowering;
 class Value;
 
@@ -70,22 +72,47 @@ class CallLowering {
   /// This hook must be implemented to lower the given call instruction,
   /// including argument and return value marshalling.
   ///
-  /// \p CalleeReg is a virtual-register containing the destination if
-  /// `CI.getCalledFunction()` returns null (i.e. if the call is indirect);
-  /// otherwise it is 0.
+  /// \p Callee is the destination of the call. It should be either a register,
+  /// globaladdress, or externalsymbol.
   ///
-  /// \p ResReg is a register where the call's return value should be stored (or
-  /// 0 if there is no return value).
+  /// \p ResTys is a list of the individual result types this function call will
+  /// produce. The types are used to assign physical registers to each slot.
+  ///
+  /// \p ResRegs is a list of the virtual registers that we expect to be defined
+  /// by this call, one per entry in \p ResTys.
+  ///
+  /// \p ArgTys is a list of the types each member of \p ArgRegs has; used by
+  /// the target to decide which register/stack slot should be allocated.
   ///
   /// \p ArgRegs is a list of virtual registers containing each argument that
   /// needs to be passed.
   ///
   /// \return true if the lowering succeeded, false otherwise.
-  virtual bool lowerCall(MachineIRBuilder &MIRBuilder, const CallInst &CI,
-                         unsigned CalleeReg, unsigned ResReg,
+  virtual bool lowerCall(MachineIRBuilder &MIRBuilder, MachineOperand &Callee,
+                         ArrayRef<MVT> ResTys, ArrayRef<unsigned> ResRegs,
+                         ArrayRef<MVT> ArgTys,
                          ArrayRef<unsigned> ArgRegs) const {
     return false;
   }
+
+  /// This hook must be implemented to lower the given call instruction,
+  /// including argument and return value marshalling.
+  ///
+  /// \p ResReg is a register where the call's return value should be stored (or
+  /// 0 if there is no return value).
+  ///
+  /// \p ArgRegs is a list of virtual registers containing each argument that
+  /// needs to be passed.
+  ///
+  /// \p GetCalleeReg is a callback to materialize a register for the callee if
+  /// the target determines it cannot jump to the destination based purely on \p
+  /// CI. This might be because \p CI is indirect, or because of the limited
+  /// range of an immediate jump.
+  ///
+  /// \return true if the lowering succeeded, false otherwise.
+  virtual bool lowerCall(MachineIRBuilder &MIRBuilder, const CallInst &CI,
+                         unsigned ResReg, ArrayRef<unsigned> ArgRegs,
+                         std::function<unsigned()> GetCalleeReg) const;
 };
 } // End namespace llvm.
 

Modified: llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt?rev=279987&r1=279986&r2=279987&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt Mon Aug 29 14:07:08 2016
@@ -1,5 +1,6 @@
 # List of all GlobalISel files.
 set(GLOBAL_ISEL_FILES
+      CallLowering.cpp
       IRTranslator.cpp
       InstructionSelect.cpp
       InstructionSelector.cpp

Added: llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp?rev=279987&view=auto
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp (added)
+++ llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp Mon Aug 29 14:07:08 2016
@@ -0,0 +1,40 @@
+//===-- lib/CodeGen/GlobalISel/CallLowering.cpp - Call lowering -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements some simple delegations needed for call lowering.
+///
+//===----------------------------------------------------------------------===//
+
+
+#include "llvm/CodeGen/GlobalISel/CallLowering.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/IR/Instructions.h"
+
+using namespace llvm;
+
+bool CallLowering::lowerCall(
+    MachineIRBuilder &MIRBuilder, const CallInst &CI, unsigned ResReg,
+    ArrayRef<unsigned> ArgRegs, std::function<unsigned()> GetCalleeReg) const {
+  // First step is to marshall all the function's parameters into the correct
+  // physregs and memory locations. Gather the sequence of argument types that
+  // we'll pass to the assigner function.
+  SmallVector<MVT, 8> ArgTys;
+  for (auto &Arg : CI.arg_operands())
+    ArgTys.push_back(MVT::getVT(Arg->getType()));
+
+  MachineOperand Callee = MachineOperand::CreateImm(0);
+  if (Function *F = CI.getCalledFunction())
+    Callee = MachineOperand::CreateGA(F, 0);
+  else
+    Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
+
+  return lowerCall(MIRBuilder, Callee, MVT::getVT(CI.getType()),
+                   ResReg ? ResReg : ArrayRef<unsigned>(), ArgTys, ArgRegs);
+}

Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=279987&r1=279986&r2=279987&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Mon Aug 29 14:07:08 2016
@@ -347,9 +347,9 @@ bool IRTranslator::translateCall(const U
     for (auto &Arg: CI.arg_operands())
       Args.push_back(getOrCreateVReg(*Arg));
 
-    return CLI->lowerCall(MIRBuilder, CI,
-                          F ? 0 : getOrCreateVReg(*CI.getCalledValue()), Res,
-                          Args);
+    return CLI->lowerCall(MIRBuilder, CI, Res, Args, [&]() {
+      return getOrCreateVReg(*CI.getCalledValue());
+    });
   }
 
   Intrinsic::ID ID = F->getIntrinsicID();

Modified: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp?rev=279987&r1=279986&r2=279987&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp Mon Aug 29 14:07:08 2016
@@ -131,19 +131,14 @@ bool AArch64CallLowering::lowerFormalArg
 }
 
 bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
-                                    const CallInst &CI, unsigned CalleeReg,
-                                    unsigned ResReg,
+                                    MachineOperand &Callee,
+                                    ArrayRef<MVT> ResTys,
+                                    ArrayRef<unsigned> ResRegs,
+                                    ArrayRef<MVT> ArgTys,
                                     ArrayRef<unsigned> ArgRegs) const {
   MachineFunction &MF = MIRBuilder.getMF();
   const Function &F = *MF.getFunction();
 
-  // First step is to marshall all the function's parameters into the correct
-  // physregs and memory locations. Gather the sequence of argument types that
-  // we'll pass to the assigner function.
-  SmallVector<MVT, 8> ArgTys;
-  for (auto &Arg : CI.arg_operands())
-    ArgTys.push_back(MVT::getVT(Arg->getType()));
-
   // Find out which ABI gets to decide where things go.
   const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
   CCAssignFn *CallAssignFn =
@@ -160,12 +155,8 @@ bool AArch64CallLowering::lowerCall(Mach
       });
 
   // Now we can build the actual call instruction.
-  MachineInstrBuilder MIB;
-  if (CalleeReg)
-    MIB = MIRBuilder.buildInstr(AArch64::BLR).addUse(CalleeReg);
-  else
-    MIB = MIRBuilder.buildInstr(AArch64::BL)
-              .addGlobalAddress(CI.getCalledFunction());
+  auto MIB = MIRBuilder.buildInstr(Callee.isReg() ? AArch64::BLR : AArch64::BL);
+  MIB.addOperand(Callee);
 
   // Tell the call which registers are clobbered.
   auto TRI = MF.getSubtarget().getRegisterInfo();
@@ -178,9 +169,9 @@ bool AArch64CallLowering::lowerCall(Mach
   // symmetry with the arugments, the physical register must be an
   // implicit-define of the call instruction.
   CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
-  if (!CI.getType()->isVoidTy())
+  if (!ResRegs.empty())
     handleAssignments(
-        MIRBuilder, RetAssignFn, MVT::getVT(CI.getType()), ResReg,
+        MIRBuilder, RetAssignFn, ResTys, ResRegs,
         [&](MachineIRBuilder &MIRBuilder, unsigned ValReg, unsigned PhysReg) {
           MIRBuilder.buildCopy(ValReg, PhysReg);
           MIB.addDef(PhysReg, RegState::Implicit);

Modified: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallLowering.h?rev=279987&r1=279986&r2=279987&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.h Mon Aug 29 14:07:08 2016
@@ -34,8 +34,9 @@ class AArch64CallLowering: public CallLo
                             const Function::ArgumentListType &Args,
                             ArrayRef<unsigned> VRegs) const override;
 
-  bool lowerCall(MachineIRBuilder &MIRBuilder, const CallInst &CI,
-                 unsigned CalleeReg, unsigned ResReg,
+  bool lowerCall(MachineIRBuilder &MIRBuilder, MachineOperand &Callee,
+                 ArrayRef<MVT> ResTys, ArrayRef<unsigned> ResRegs,
+                 ArrayRef<MVT> ArgTys,
                  ArrayRef<unsigned> ArgRegs) const override;
 
 private:




More information about the llvm-commits mailing list