The delayed stack protector feature which is currently used for SDAG (and thus allows for more commonly generating tail calls) depends on being able to extract the tail call into a separate return block. To do this it also has to extract the vreg->physreg copies that set up the call's arguments, since if it doesn't then the call inst ends up using undefined physregs in it's new spliced block. SelectionDAG implementations can do this because they delay emitting register copies until *after* the stack arguments are set up. GISel however just processes and emits the arguments in IR order, so stack arguments always end up last, and thus this breaks the code that looks for any register arg copies that precede the call instruction. This patch adds a thunk argument to the assignValueToReg() and custom assignment hooks. For outgoing arguments, register assignments use this return param to return a thunk that does the actual generating of the copies. We collect these until all the outgoing stack assignments have been done and then execute them, so that the copies (and perhaps some artifacts like G_SEXTs) are placed after any stores. Differential Revision: https://reviews.llvm.org/D110610
73 lines
2.4 KiB
C++
73 lines
2.4 KiB
C++
//===-- PPCCallLowering.h - Call lowering for GlobalISel -------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// This file describes how to lower LLVM calls to machine code calls.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_POWERPC_GISEL_PPCCALLLOWERING_H
|
|
#define LLVM_LIB_TARGET_POWERPC_GISEL_PPCCALLLOWERING_H
|
|
|
|
#include "PPCISelLowering.h"
|
|
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
|
|
#include "llvm/IR/CallingConv.h"
|
|
|
|
namespace llvm {
|
|
|
|
class PPCTargetLowering;
|
|
|
|
class PPCCallLowering : public CallLowering {
|
|
public:
|
|
PPCCallLowering(const PPCTargetLowering &TLI);
|
|
|
|
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
|
|
ArrayRef<Register> VRegs, FunctionLoweringInfo &FLI,
|
|
Register SwiftErrorVReg) const override;
|
|
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
|
|
ArrayRef<ArrayRef<Register>> VRegs,
|
|
FunctionLoweringInfo &FLI) const override;
|
|
bool lowerCall(MachineIRBuilder &MIRBuilder,
|
|
CallLoweringInfo &Info) const override;
|
|
};
|
|
|
|
class PPCIncomingValueHandler : public CallLowering::IncomingValueHandler {
|
|
public:
|
|
PPCIncomingValueHandler(MachineIRBuilder &MIRBuilder,
|
|
MachineRegisterInfo &MRI)
|
|
: CallLowering::IncomingValueHandler(MIRBuilder, MRI) {}
|
|
|
|
uint64_t StackUsed;
|
|
|
|
private:
|
|
void assignValueToReg(Register ValVReg, Register PhysReg,
|
|
CCValAssign VA) override;
|
|
|
|
void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
|
|
MachinePointerInfo &MPO, CCValAssign &VA) override;
|
|
|
|
Register getStackAddress(uint64_t Size, int64_t Offset,
|
|
MachinePointerInfo &MPO,
|
|
ISD::ArgFlagsTy Flags) override;
|
|
|
|
virtual void markPhysRegUsed(unsigned PhysReg) = 0;
|
|
};
|
|
|
|
class FormalArgHandler : public PPCIncomingValueHandler {
|
|
|
|
void markPhysRegUsed(unsigned PhysReg) override;
|
|
|
|
public:
|
|
FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
|
|
: PPCIncomingValueHandler(MIRBuilder, MRI) {}
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif
|