Index: llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -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 @@ : 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 @@ 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 Args, ValueHandler &Callback) const; + public: CallLowering(const TargetLowering *TLI) : TLI(TLI) {} virtual ~CallLowering() {} Index: llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp +++ llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -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 @@ CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const CallInst &FuncInfo) const; + +bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder, + CCAssignFn *AssignFn, + ArrayRef Args, + ValueHandler &Handler) const { + MachineFunction &MF = MIRBuilder.getMF(); + const Function &F = *MF.getFunction(); + + SmallVector 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; +} Index: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.h =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.h +++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.h @@ -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 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 @@ SmallVectorImpl &SplitArgs, const DataLayout &DL, MachineRegisterInfo &MRI, SplitArgTy SplitArg) const; - - bool handleAssignments(MachineIRBuilder &MIRBuilder, CCAssignFn *AssignFn, - ArrayRef Args, - ValueHandler &Callback) const; }; } // End of namespace llvm; #endif Index: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp @@ -32,44 +32,8 @@ : CallLowering(&TLI) { } -bool AArch64CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder, - CCAssignFn *AssignFn, - ArrayRef Args, - ValueHandler &Handler) const { - MachineFunction &MF = MIRBuilder.getMF(); - const Function &F = *MF.getFunction(); - - SmallVector 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 @@ 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 @@ MachineInstrBuilder MIB; }; -struct OutgoingArgHandler : public AArch64CallLowering::ValueHandler { +struct OutgoingArgHandler : public CallLowering::ValueHandler { OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, MachineInstrBuilder MIB) : ValueHandler(MIRBuilder, MRI), MIB(MIB) {}