forked from OSchip/llvm-project
[GlobalISel] Extract handleAssignments out of AArch64CallLowering
This function seems target-independent so far: all the target-specific behaviour is isolated in the CCAssignFn and the ValueHandler (which we're also extracting into the generic CallLowering). The intention is to use this in the ARM backend. Differential Revision: https://reviews.llvm.org/D27045 llvm-svn: 288658
This commit is contained in:
parent
83102d99ce
commit
f11f042ecb
|
@ -16,6 +16,7 @@
|
|||
#define LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/CallingConvLower.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/Target/TargetCallingConv.h"
|
||||
|
@ -39,6 +40,45 @@ public:
|
|||
: Reg(Reg), Ty(Ty), Flags(Flags) {}
|
||||
};
|
||||
|
||||
/// Argument handling is mostly uniform between the four places that
|
||||
/// make these decisions: function formal arguments, call
|
||||
/// instruction args, call instruction returns and function
|
||||
/// returns. However, once a decision has been made on where an
|
||||
/// arugment should go, exactly what happens can vary slightly. This
|
||||
/// class abstracts the differences.
|
||||
struct ValueHandler {
|
||||
/// Materialize a VReg containing the address of the specified
|
||||
/// stack-based object. This is either based on a FrameIndex or
|
||||
/// direct SP manipulation, depending on the context. \p MPO
|
||||
/// should be initialized to an appropriate description of the
|
||||
/// address created.
|
||||
virtual unsigned getStackAddress(uint64_t Size, int64_t Offset,
|
||||
MachinePointerInfo &MPO) = 0;
|
||||
|
||||
/// The specified value has been assigned to a physical register,
|
||||
/// handle the appropriate COPY (either to or from) and mark any
|
||||
/// relevant uses/defines as needed.
|
||||
virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
|
||||
CCValAssign &VA) = 0;
|
||||
|
||||
/// The specified value has been assigned to a stack
|
||||
/// location. Load or store it there, with appropriate extension
|
||||
/// if necessary.
|
||||
virtual void assignValueToAddress(unsigned ValVReg, unsigned Addr,
|
||||
uint64_t Size, MachinePointerInfo &MPO,
|
||||
CCValAssign &VA) = 0;
|
||||
|
||||
unsigned extendRegister(unsigned ValReg, CCValAssign &VA);
|
||||
|
||||
ValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
|
||||
: MIRBuilder(MIRBuilder), MRI(MRI) {}
|
||||
|
||||
virtual ~ValueHandler() {}
|
||||
|
||||
MachineIRBuilder &MIRBuilder;
|
||||
MachineRegisterInfo &MRI;
|
||||
};
|
||||
|
||||
protected:
|
||||
/// Getter for generic TargetLowering class.
|
||||
const TargetLowering *getTLI() const {
|
||||
|
@ -56,6 +96,13 @@ protected:
|
|||
void setArgFlags(ArgInfo &Arg, unsigned OpNum, const DataLayout &DL,
|
||||
const FuncInfoTy &FuncInfo) const;
|
||||
|
||||
/// Invoke the \p AssignFn on each of the given \p Args and then use
|
||||
/// \p Callback to move them to the assigned locations.
|
||||
///
|
||||
/// \return True if everything has succeeded, false otherwise.
|
||||
bool handleAssignments(MachineIRBuilder &MIRBuilder, CCAssignFn *AssignFn,
|
||||
ArrayRef<ArgInfo> Args, ValueHandler &Callback) const;
|
||||
|
||||
public:
|
||||
CallLowering(const TargetLowering *TLI) : TLI(TLI) {}
|
||||
virtual ~CallLowering() {}
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
|
||||
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
|
||||
|
@ -100,3 +100,39 @@ template void
|
|||
CallLowering::setArgFlags<CallInst>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
|
||||
const DataLayout &DL,
|
||||
const CallInst &FuncInfo) const;
|
||||
|
||||
bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder,
|
||||
CCAssignFn *AssignFn,
|
||||
ArrayRef<ArgInfo> Args,
|
||||
ValueHandler &Handler) const {
|
||||
MachineFunction &MF = MIRBuilder.getMF();
|
||||
const Function &F = *MF.getFunction();
|
||||
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
|
||||
|
||||
unsigned NumArgs = Args.size();
|
||||
for (unsigned i = 0; i != NumArgs; ++i) {
|
||||
MVT CurVT = MVT::getVT(Args[i].Ty);
|
||||
if (AssignFn(i, CurVT, CurVT, CCValAssign::Full, Args[i].Flags, CCInfo))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
|
||||
CCValAssign &VA = ArgLocs[i];
|
||||
|
||||
if (VA.isRegLoc())
|
||||
Handler.assignValueToReg(Args[i].Reg, VA.getLocReg(), VA);
|
||||
else if (VA.isMemLoc()) {
|
||||
unsigned Size = VA.getValVT().getSizeInBits() / 8;
|
||||
unsigned Offset = VA.getLocMemOffset();
|
||||
MachinePointerInfo MPO;
|
||||
unsigned StackAddr = Handler.getStackAddress(Size, Offset, MPO);
|
||||
Handler.assignValueToAddress(Args[i].Reg, StackAddr, Size, MPO, VA);
|
||||
} else {
|
||||
// FIXME: Support byvals and other weirdness
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -32,44 +32,8 @@ AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
|
|||
: CallLowering(&TLI) {
|
||||
}
|
||||
|
||||
bool AArch64CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder,
|
||||
CCAssignFn *AssignFn,
|
||||
ArrayRef<ArgInfo> Args,
|
||||
ValueHandler &Handler) const {
|
||||
MachineFunction &MF = MIRBuilder.getMF();
|
||||
const Function &F = *MF.getFunction();
|
||||
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
|
||||
|
||||
unsigned NumArgs = Args.size();
|
||||
for (unsigned i = 0; i != NumArgs; ++i) {
|
||||
MVT CurVT = MVT::getVT(Args[i].Ty);
|
||||
if (AssignFn(i, CurVT, CurVT, CCValAssign::Full, Args[i].Flags, CCInfo))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
|
||||
CCValAssign &VA = ArgLocs[i];
|
||||
|
||||
if (VA.isRegLoc())
|
||||
Handler.assignValueToReg(Args[i].Reg, VA.getLocReg(), VA);
|
||||
else if (VA.isMemLoc()) {
|
||||
unsigned Size = VA.getValVT().getSizeInBits() / 8;
|
||||
unsigned Offset = VA.getLocMemOffset();
|
||||
MachinePointerInfo MPO;
|
||||
unsigned StackAddr = Handler.getStackAddress(Size, Offset, MPO);
|
||||
Handler.assignValueToAddress(Args[i].Reg, StackAddr, Size, MPO, VA);
|
||||
} else {
|
||||
// FIXME: Support byvals and other weirdness
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned AArch64CallLowering::ValueHandler::extendRegister(unsigned ValReg,
|
||||
CCValAssign &VA) {
|
||||
unsigned CallLowering::ValueHandler::extendRegister(unsigned ValReg,
|
||||
CCValAssign &VA) {
|
||||
LLT LocTy{VA.getLocVT()};
|
||||
switch (VA.getLocInfo()) {
|
||||
default: break;
|
||||
|
@ -96,7 +60,7 @@ unsigned AArch64CallLowering::ValueHandler::extendRegister(unsigned ValReg,
|
|||
llvm_unreachable("unable to extend register");
|
||||
}
|
||||
|
||||
struct IncomingArgHandler : public AArch64CallLowering::ValueHandler {
|
||||
struct IncomingArgHandler : public CallLowering::ValueHandler {
|
||||
IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
|
||||
: ValueHandler(MIRBuilder, MRI) {}
|
||||
|
||||
|
@ -152,7 +116,7 @@ struct CallReturnHandler : public IncomingArgHandler {
|
|||
MachineInstrBuilder MIB;
|
||||
};
|
||||
|
||||
struct OutgoingArgHandler : public AArch64CallLowering::ValueHandler {
|
||||
struct OutgoingArgHandler : public CallLowering::ValueHandler {
|
||||
OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
|
||||
MachineInstrBuilder MIB)
|
||||
: ValueHandler(MIRBuilder, MRI), MIB(MIB) {}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#define LLVM_LIB_TARGET_AARCH64_AARCH64CALLLOWERING
|
||||
|
||||
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
|
||||
#include "llvm/CodeGen/CallingConvLower.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
@ -25,46 +24,6 @@ class AArch64TargetLowering;
|
|||
|
||||
class AArch64CallLowering: public CallLowering {
|
||||
public:
|
||||
|
||||
/// Argument handling is mostly uniform between the four places that
|
||||
/// make these decisions: function formal arguments, call
|
||||
/// instruction args, call instruction returns and function
|
||||
/// returns. However, once a decision has been made on where an
|
||||
/// arugment should go, exactly what happens can vary slightly. This
|
||||
/// class abstracts the differences.
|
||||
struct ValueHandler {
|
||||
/// Materialize a VReg containing the address of the specified
|
||||
/// stack-based object. This is either based on a FrameIndex or
|
||||
/// direct SP manipulation, depending on the context. \p MPO
|
||||
/// should be initialized to an appropriate description of the
|
||||
/// address created.
|
||||
virtual unsigned getStackAddress(uint64_t Size, int64_t Offset,
|
||||
MachinePointerInfo &MPO) = 0;
|
||||
|
||||
/// The specified value has been assigned to a physical register,
|
||||
/// handle the appropriate COPY (either to or from) and mark any
|
||||
/// relevant uses/defines as needed.
|
||||
virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
|
||||
CCValAssign &VA) = 0;
|
||||
|
||||
/// The specified value has been assigned to a stack
|
||||
/// location. Load or store it there, with appropriate extension
|
||||
/// if necessary.
|
||||
virtual void assignValueToAddress(unsigned ValVReg, unsigned Addr,
|
||||
uint64_t Size, MachinePointerInfo &MPO,
|
||||
CCValAssign &VA) = 0;
|
||||
|
||||
unsigned extendRegister(unsigned ValReg, CCValAssign &VA);
|
||||
|
||||
ValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
|
||||
: MIRBuilder(MIRBuilder), MRI(MRI) {}
|
||||
|
||||
virtual ~ValueHandler() {}
|
||||
|
||||
MachineIRBuilder &MIRBuilder;
|
||||
MachineRegisterInfo &MRI;
|
||||
};
|
||||
|
||||
AArch64CallLowering(const AArch64TargetLowering &TLI);
|
||||
|
||||
bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val,
|
||||
|
@ -92,10 +51,6 @@ private:
|
|||
SmallVectorImpl<ArgInfo> &SplitArgs,
|
||||
const DataLayout &DL, MachineRegisterInfo &MRI,
|
||||
SplitArgTy SplitArg) const;
|
||||
|
||||
bool handleAssignments(MachineIRBuilder &MIRBuilder, CCAssignFn *AssignFn,
|
||||
ArrayRef<ArgInfo> Args,
|
||||
ValueHandler &Callback) const;
|
||||
};
|
||||
} // End of namespace llvm;
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue