PPCCallLowering.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. //===-- PPCCallLowering.h - Call lowering for GlobalISel -------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// \file
  10. /// This file implements the lowering of LLVM calls to machine code calls for
  11. /// GlobalISel.
  12. ///
  13. //===----------------------------------------------------------------------===//
  14. #include "PPCCallLowering.h"
  15. #include "PPCCallingConv.h"
  16. #include "PPCISelLowering.h"
  17. #include "PPCSubtarget.h"
  18. #include "PPCTargetMachine.h"
  19. #include "llvm/CodeGen/CallingConvLower.h"
  20. #include "llvm/CodeGen/GlobalISel/CallLowering.h"
  21. #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
  22. #include "llvm/CodeGen/MachineFrameInfo.h"
  23. #include "llvm/CodeGen/TargetCallingConv.h"
  24. #include "llvm/Support/Debug.h"
  25. #define DEBUG_TYPE "ppc-call-lowering"
  26. using namespace llvm;
  27. namespace {
  28. struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler {
  29. OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
  30. MachineInstrBuilder MIB)
  31. : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
  32. void assignValueToReg(Register ValVReg, Register PhysReg,
  33. CCValAssign VA) override;
  34. void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
  35. MachinePointerInfo &MPO, CCValAssign &VA) override;
  36. Register getStackAddress(uint64_t Size, int64_t Offset,
  37. MachinePointerInfo &MPO,
  38. ISD::ArgFlagsTy Flags) override;
  39. MachineInstrBuilder MIB;
  40. };
  41. } // namespace
  42. void OutgoingArgHandler::assignValueToReg(Register ValVReg, Register PhysReg,
  43. CCValAssign VA) {
  44. MIB.addUse(PhysReg, RegState::Implicit);
  45. Register ExtReg = extendRegister(ValVReg, VA);
  46. MIRBuilder.buildCopy(PhysReg, ExtReg);
  47. }
  48. void OutgoingArgHandler::assignValueToAddress(Register ValVReg, Register Addr,
  49. LLT MemTy,
  50. MachinePointerInfo &MPO,
  51. CCValAssign &VA) {
  52. llvm_unreachable("unimplemented");
  53. }
  54. Register OutgoingArgHandler::getStackAddress(uint64_t Size, int64_t Offset,
  55. MachinePointerInfo &MPO,
  56. ISD::ArgFlagsTy Flags) {
  57. llvm_unreachable("unimplemented");
  58. }
  59. PPCCallLowering::PPCCallLowering(const PPCTargetLowering &TLI)
  60. : CallLowering(&TLI) {}
  61. bool PPCCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
  62. const Value *Val, ArrayRef<Register> VRegs,
  63. FunctionLoweringInfo &FLI,
  64. Register SwiftErrorVReg) const {
  65. auto MIB = MIRBuilder.buildInstrNoInsert(PPC::BLR8);
  66. bool Success = true;
  67. MachineFunction &MF = MIRBuilder.getMF();
  68. const Function &F = MF.getFunction();
  69. MachineRegisterInfo &MRI = MF.getRegInfo();
  70. auto &DL = F.getParent()->getDataLayout();
  71. if (!VRegs.empty()) {
  72. // Setup the information about the return value.
  73. ArgInfo OrigArg{VRegs, Val->getType(), 0};
  74. setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
  75. // Split the return value into consecutive registers if needed.
  76. SmallVector<ArgInfo, 8> SplitArgs;
  77. splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
  78. // Use the calling convention callback to determine type and location of
  79. // return value.
  80. OutgoingValueAssigner ArgAssigner(RetCC_PPC);
  81. // Handler to move the return value into the correct location.
  82. OutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB);
  83. // Iterate over all return values, and move them to the assigned location.
  84. Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
  85. MIRBuilder, F.getCallingConv(),
  86. F.isVarArg());
  87. }
  88. MIRBuilder.insertInstr(MIB);
  89. return Success;
  90. }
  91. bool PPCCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
  92. CallLoweringInfo &Info) const {
  93. return false;
  94. }
  95. bool PPCCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
  96. const Function &F,
  97. ArrayRef<ArrayRef<Register>> VRegs,
  98. FunctionLoweringInfo &FLI) const {
  99. MachineFunction &MF = MIRBuilder.getMF();
  100. MachineRegisterInfo &MRI = MF.getRegInfo();
  101. const auto &DL = F.getParent()->getDataLayout();
  102. auto &TLI = *getTLI<PPCTargetLowering>();
  103. // Loop over each arg, set flags and split to single value types
  104. SmallVector<ArgInfo, 8> SplitArgs;
  105. unsigned I = 0;
  106. for (const auto &Arg : F.args()) {
  107. if (DL.getTypeStoreSize(Arg.getType()).isZero())
  108. continue;
  109. ArgInfo OrigArg{VRegs[I], Arg, I};
  110. setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F);
  111. splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
  112. ++I;
  113. }
  114. CCAssignFn *AssignFn =
  115. TLI.ccAssignFnForCall(F.getCallingConv(), false, F.isVarArg());
  116. IncomingValueAssigner ArgAssigner(AssignFn);
  117. FormalArgHandler ArgHandler(MIRBuilder, MRI);
  118. return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
  119. MIRBuilder, F.getCallingConv(),
  120. F.isVarArg());
  121. }
  122. void PPCIncomingValueHandler::assignValueToReg(Register ValVReg,
  123. Register PhysReg,
  124. CCValAssign VA) {
  125. markPhysRegUsed(PhysReg);
  126. IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
  127. }
  128. void PPCIncomingValueHandler::assignValueToAddress(Register ValVReg,
  129. Register Addr, LLT MemTy,
  130. MachinePointerInfo &MPO,
  131. CCValAssign &VA) {
  132. // define a lambda expression to load value
  133. auto BuildLoad = [](MachineIRBuilder &MIRBuilder, MachinePointerInfo &MPO,
  134. LLT MemTy, const DstOp &Res, Register Addr) {
  135. MachineFunction &MF = MIRBuilder.getMF();
  136. auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
  137. inferAlignFromPtrInfo(MF, MPO));
  138. return MIRBuilder.buildLoad(Res, Addr, *MMO);
  139. };
  140. BuildLoad(MIRBuilder, MPO, MemTy, ValVReg, Addr);
  141. }
  142. Register PPCIncomingValueHandler::getStackAddress(uint64_t Size, int64_t Offset,
  143. MachinePointerInfo &MPO,
  144. ISD::ArgFlagsTy Flags) {
  145. auto &MFI = MIRBuilder.getMF().getFrameInfo();
  146. const bool IsImmutable = !Flags.isByVal();
  147. int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
  148. MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
  149. // Build Frame Index based on whether the machine is 32-bit or 64-bit
  150. llvm::LLT FramePtr = LLT::pointer(
  151. 0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits());
  152. MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI);
  153. StackUsed = std::max(StackUsed, Size + Offset);
  154. return AddrReg.getReg(0);
  155. }
  156. void FormalArgHandler::markPhysRegUsed(unsigned PhysReg) {
  157. MIRBuilder.getMRI()->addLiveIn(PhysReg);
  158. MIRBuilder.getMBB().addLiveIn(PhysReg);
  159. }