diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 21:25:48 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 21:25:48 +0000 |
commit | d88c1a5a572cdb661c111098831fa526e933756f (patch) | |
tree | 97b32c3372106ac47ded3d1a99f9c023a8530073 /contrib/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp | |
parent | 715652a404ee99f10c09c0a5edbb5883961b8c25 (diff) | |
parent | b915e9e0fc85ba6f398b3fab0db6a81a8913af94 (diff) |
Update llvm to trunk r290819 and resolve conflicts.
Notes
Notes:
svn path=/projects/clang400-import/; revision=311142
Diffstat (limited to 'contrib/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp | 104 |
1 files changed, 73 insertions, 31 deletions
diff --git a/contrib/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp b/contrib/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp index 0a5782e5c287..a6a2c0bf06ae 100644 --- a/contrib/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp +++ b/contrib/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp @@ -37,15 +37,34 @@ using namespace llvm; // TODO: wasm64 // TODO: Emit TargetOpcode::CFI_INSTRUCTION instructions +/// We need a base pointer in the case of having items on the stack that +/// require stricter alignment than the stack pointer itself. Because we need +/// to shift the stack pointer by some unknown amount to force the alignment, +/// we need to record the value of the stack pointer on entry to the function. +bool WebAssemblyFrameLowering::hasBP( + const MachineFunction &MF) const { + const auto *RegInfo = + MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo(); + return RegInfo->needsStackRealignment(MF); +} + /// Return true if the specified function should have a dedicated frame pointer /// register. bool WebAssemblyFrameLowering::hasFP(const MachineFunction &MF) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - const auto *RegInfo = - MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo(); - return MFI->isFrameAddressTaken() || MFI->hasVarSizedObjects() || - MFI->hasStackMap() || MFI->hasPatchPoint() || - RegInfo->needsStackRealignment(MF); + const MachineFrameInfo &MFI = MF.getFrameInfo(); + + // When we have var-sized objects, we move the stack pointer by an unknown + // amount, and need to emit a frame pointer to restore the stack to where we + // were on function entry. + // If we already need a base pointer, we use that to fix up the stack pointer. + // If there are no fixed-size objects, we would have no use of a frame + // pointer, and thus should not emit one. + bool HasFixedSizedObjects = MFI.getStackSize() > 0; + bool NeedsFixedReference = !hasBP(MF) || HasFixedSizedObjects; + + return MFI.isFrameAddressTaken() || + (MFI.hasVarSizedObjects() && NeedsFixedReference) || + MFI.hasStackMap() || MFI.hasPatchPoint(); } /// Under normal circumstances, when a frame pointer is not required, we reserve @@ -55,7 +74,7 @@ bool WebAssemblyFrameLowering::hasFP(const MachineFunction &MF) const { /// frame. bool WebAssemblyFrameLowering::hasReservedCallFrame( const MachineFunction &MF) const { - return !MF.getFrameInfo()->hasVarSizedObjects(); + return !MF.getFrameInfo().hasVarSizedObjects(); } @@ -88,18 +107,17 @@ static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF, const TargetRegisterClass *PtrRC = MRI.getTargetRegisterInfo()->getPointerRegClass(MF); unsigned Zero = MRI.createVirtualRegister(PtrRC); - unsigned Drop = MRI.createVirtualRegister(PtrRC); const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); BuildMI(MBB, InsertAddr, DL, TII->get(WebAssembly::CONST_I32), Zero) .addImm(0); - auto *MMO = new MachineMemOperand(MachinePointerInfo(MF.getPSVManager() - .getExternalSymbolCallEntry(ES)), - MachineMemOperand::MOStore, 4, 4); - BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32), Drop) + MachineMemOperand *MMO = MF.getMachineMemOperand( + MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)), + MachineMemOperand::MOStore, 4, 4); + BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32)) + .addImm(2) // p2align .addExternalSymbol(SPSymbol) .addReg(Zero) - .addImm(2) // p2align .addReg(SrcReg) .addMemOperand(MMO); } @@ -108,11 +126,11 @@ MachineBasicBlock::iterator WebAssemblyFrameLowering::eliminateCallFramePseudoInstr( MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { - assert(!I->getOperand(0).getImm() && hasFP(MF) && + assert(!I->getOperand(0).getImm() && (hasFP(MF) || hasBP(MF)) && "Call frame pseudos should only be used for dynamic stack adjustment"); const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); if (I->getOpcode() == TII->getCallFrameDestroyOpcode() && - needsSPWriteback(MF, *MF.getFrameInfo())) { + needsSPWriteback(MF, MF.getFrameInfo())) { DebugLoc DL = I->getDebugLoc(); writeSPToMemory(WebAssembly::SP32, MF, MBB, I, I, DL); } @@ -122,12 +140,12 @@ WebAssemblyFrameLowering::eliminateCallFramePseudoInstr( void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { // TODO: Do ".setMIFlag(MachineInstr::FrameSetup)" on emitted instructions - auto *MFI = MF.getFrameInfo(); - assert(MFI->getCalleeSavedInfo().empty() && + auto &MFI = MF.getFrameInfo(); + assert(MFI.getCalleeSavedInfo().empty() && "WebAssembly should not have callee-saved registers"); - if (!needsSP(MF, *MFI)) return; - uint64_t StackSize = MFI->getStackSize(); + if (!needsSP(MF, MFI)) return; + uint64_t StackSize = MFI.getStackSize(); const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); auto &MRI = MF.getRegInfo(); @@ -138,22 +156,31 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF, const TargetRegisterClass *PtrRC = MRI.getTargetRegisterInfo()->getPointerRegClass(MF); unsigned Zero = MRI.createVirtualRegister(PtrRC); - unsigned SPReg = MRI.createVirtualRegister(PtrRC); + unsigned SPReg = WebAssembly::SP32; + if (StackSize) + SPReg = MRI.createVirtualRegister(PtrRC); const char *ES = "__stack_pointer"; auto *SPSymbol = MF.createExternalSymbolName(ES); BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), Zero) .addImm(0); - auto *LoadMMO = new MachineMemOperand(MachinePointerInfo(MF.getPSVManager() - .getExternalSymbolCallEntry(ES)), - MachineMemOperand::MOLoad, 4, 4); + MachineMemOperand *LoadMMO = MF.getMachineMemOperand( + MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)), + MachineMemOperand::MOLoad, 4, 4); // Load the SP value. - BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::LOAD_I32), - StackSize ? SPReg : (unsigned)WebAssembly::SP32) + BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::LOAD_I32), SPReg) + .addImm(2) // p2align .addExternalSymbol(SPSymbol) .addReg(Zero) // addr - .addImm(2) // p2align .addMemOperand(LoadMMO); + bool HasBP = hasBP(MF); + if (HasBP) { + auto FI = MF.getInfo<WebAssemblyFunctionInfo>(); + unsigned BasePtr = MRI.createVirtualRegister(PtrRC); + FI->setBasePointerVreg(BasePtr); + BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY), BasePtr) + .addReg(SPReg); + } if (StackSize) { // Subtract the frame size unsigned OffsetReg = MRI.createVirtualRegister(PtrRC); @@ -164,6 +191,18 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF, .addReg(SPReg) .addReg(OffsetReg); } + if (HasBP) { + unsigned BitmaskReg = MRI.createVirtualRegister(PtrRC); + unsigned Alignment = MFI.getMaxAlignment(); + assert((1u << countTrailingZeros(Alignment)) == Alignment && + "Alignment must be a power of 2"); + BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), BitmaskReg) + .addImm((int)~(Alignment - 1)); + BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::AND_I32), + WebAssembly::SP32) + .addReg(WebAssembly::SP32) + .addReg(BitmaskReg); + } if (hasFP(MF)) { // Unlike most conventional targets (where FP points to the saved FP), // FP points to the bottom of the fixed-size locals, so we can use positive @@ -172,16 +211,16 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF, WebAssembly::FP32) .addReg(WebAssembly::SP32); } - if (StackSize && needsSPWriteback(MF, *MFI)) { + if (StackSize && needsSPWriteback(MF, MFI)) { writeSPToMemory(WebAssembly::SP32, MF, MBB, InsertPt, InsertPt, DL); } } void WebAssemblyFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { - auto *MFI = MF.getFrameInfo(); - uint64_t StackSize = MFI->getStackSize(); - if (!needsSP(MF, *MFI) || !needsSPWriteback(MF, *MFI)) return; + auto &MFI = MF.getFrameInfo(); + uint64_t StackSize = MFI.getStackSize(); + if (!needsSP(MF, MFI) || !needsSPWriteback(MF, MFI)) return; const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); auto &MRI = MF.getRegInfo(); auto InsertPt = MBB.getFirstTerminator(); @@ -194,7 +233,10 @@ void WebAssemblyFrameLowering::emitEpilogue(MachineFunction &MF, // subtracted in the prolog. unsigned SPReg = 0; MachineBasicBlock::iterator InsertAddr = InsertPt; - if (StackSize) { + if (hasBP(MF)) { + auto FI = MF.getInfo<WebAssemblyFunctionInfo>(); + SPReg = FI->getBasePointerVreg(); + } else if (StackSize) { const TargetRegisterClass *PtrRC = MRI.getTargetRegisterInfo()->getPointerRegClass(MF); unsigned OffsetReg = MRI.createVirtualRegister(PtrRC); |