diff options
author | Tim Northover <tnorthover@apple.com> | 2017-02-08 17:57:27 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2017-02-08 17:57:27 +0000 |
commit | e9600d861cf898b51c33218ea55a924292ba7955 (patch) | |
tree | 8ebd34a320d10d350ff8175abcf7d2b0e4edfd6f /llvm/lib | |
parent | f19d467ff6c7c14af97b0bdc52f1980488fca0e3 (diff) | |
download | llvm-e9600d861cf898b51c33218ea55a924292ba7955.zip llvm-e9600d861cf898b51c33218ea55a924292ba7955.tar.gz llvm-e9600d861cf898b51c33218ea55a924292ba7955.tar.bz2 |
GlobalISel: select G_VASTART on iOS AArch64.
The AAPCS ABI is substantially more complicated so that's coming in a separate
patch. For now we can generate correct code for iOS though.
llvm-svn: 294493
Diffstat (limited to 'llvm/lib')
4 files changed, 67 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp index c8a3ce5..6148359 100644 --- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp @@ -15,6 +15,8 @@ #include "AArch64CallLowering.h" #include "AArch64ISelLowering.h" +#include "AArch64MachineFunctionInfo.h" +#include "AArch64Subtarget.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/Analysis.h" @@ -55,7 +57,7 @@ AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI) struct IncomingArgHandler : public CallLowering::ValueHandler { IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, CCAssignFn *AssignFn) - : ValueHandler(MIRBuilder, MRI, AssignFn) {} + : ValueHandler(MIRBuilder, MRI, AssignFn), StackUsed(0) {} unsigned getStackAddress(uint64_t Size, int64_t Offset, MachinePointerInfo &MPO) override { @@ -64,6 +66,7 @@ struct IncomingArgHandler : public CallLowering::ValueHandler { MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); unsigned AddrReg = MRI.createGenericVirtualRegister(LLT::pointer(0, 64)); MIRBuilder.buildFrameIndex(AddrReg, FI); + StackUsed = std::max(StackUsed, Size + Offset); return AddrReg; } @@ -86,6 +89,8 @@ struct IncomingArgHandler : public CallLowering::ValueHandler { /// parameters (it's a basic-block live-in), and a call instruction /// (it's an implicit-def of the BL). virtual void markPhysRegUsed(unsigned PhysReg) = 0; + + uint64_t StackUsed; }; struct FormalArgHandler : public IncomingArgHandler { @@ -265,6 +270,21 @@ bool AArch64CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) return false; + if (F.isVarArg()) { + if (!MF.getSubtarget<AArch64Subtarget>().isTargetDarwin()) { + // FIXME: we need to reimplement saveVarArgsRegisters from + // AArch64ISelLowering. + return false; + } + + // We currently pass all varargs at 8-byte alignment. + uint64_t StackOffset = alignTo(Handler.StackUsed, 8); + + auto &MFI = MIRBuilder.getMF().getFrameInfo(); + AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>(); + FuncInfo->setVarArgsStackIndex(MFI.CreateFixedObject(4, StackOffset, true)); + } + // Move back to the end of the basic block. MIRBuilder.setMBB(MBB); diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index 21d80ca..69811945 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -14,6 +14,7 @@ #include "AArch64InstructionSelector.h" #include "AArch64InstrInfo.h" +#include "AArch64MachineFunctionInfo.h" #include "AArch64RegisterBankInfo.h" #include "AArch64RegisterInfo.h" #include "AArch64Subtarget.h" @@ -440,6 +441,38 @@ static void changeFCMPPredToAArch64CC(CmpInst::Predicate P, } } +bool AArch64InstructionSelector::selectVaStartAAPCS( + MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const { + return false; +} + +bool AArch64InstructionSelector::selectVaStartDarwin( + MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const { + AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>(); + unsigned ListReg = I.getOperand(0).getReg(); + + unsigned ArgsAddrReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass); + + auto MIB = + BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::ADDXri)) + .addDef(ArgsAddrReg) + .addFrameIndex(FuncInfo->getVarArgsStackIndex()) + .addImm(0) + .addImm(0); + + constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); + + MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::STRXui)) + .addUse(ArgsAddrReg) + .addUse(ListReg) + .addImm(0) + .addMemOperand(*I.memoperands_begin()); + + constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); + I.eraseFromParent(); + return true; +} + bool AArch64InstructionSelector::select(MachineInstr &I) const { assert(I.getParent() && "Instruction should be in a basic block!"); assert(I.getParent()->getParent() && "Instruction should be in a function!"); @@ -1125,6 +1158,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { I.eraseFromParent(); return true; } + case TargetOpcode::G_VASTART: + return STI.isTargetDarwin() ? selectVaStartDarwin(I, MF, MRI) + : selectVaStartAAPCS(I, MF, MRI); } return false; diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.h b/llvm/lib/Target/AArch64/AArch64InstructionSelector.h index 2c6e5a9..3f38c9f 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.h +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.h @@ -24,6 +24,9 @@ class AArch64RegisterInfo; class AArch64Subtarget; class AArch64TargetMachine; +class MachineFunction; +class MachineRegisterInfo; + class AArch64InstructionSelector : public InstructionSelector { public: AArch64InstructionSelector(const AArch64TargetMachine &TM, @@ -33,6 +36,11 @@ public: bool select(MachineInstr &I) const override; private: + bool selectVaStartAAPCS(MachineInstr &I, MachineFunction &MF, + MachineRegisterInfo &MRI) const; + bool selectVaStartDarwin(MachineInstr &I, MachineFunction &MF, + MachineRegisterInfo &MRI) const; + /// tblgen-erated 'select' implementation, used as the initial selector for /// the patterns that don't require complex C++. bool selectImpl(MachineInstr &I) const; diff --git a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp index 3a97406..ad0482a 100644 --- a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -225,5 +225,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo() { setAction({G_BITCAST, 1, LLT::vector(32/EltSize, EltSize)}, Legal); } + setAction({G_VASTART, p0}, Legal); + computeTables(); } |