1de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===----- X86WinAllocaExpander.cpp - Expand WinAlloca pseudo instruction -===// 2de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// 3de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// The LLVM Compiler Infrastructure 4de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// 5de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 6de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// License. See LICENSE.TXT for details. 7de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// 8de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===----------------------------------------------------------------------===// 9de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// 10de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// This file defines a pass that expands WinAlloca pseudo-instructions. 11de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// 12de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// It performs a conservative analysis to determine whether each allocation 13de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// falls within a region of the stack that is safe to use, or whether stack 14de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// probes must be emitted. 15de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// 16de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===----------------------------------------------------------------------===// 17de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 18de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "X86.h" 19de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "X86InstrBuilder.h" 20de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "X86InstrInfo.h" 21de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "X86MachineFunctionInfo.h" 22de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "X86Subtarget.h" 23de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/ADT/PostOrderIterator.h" 24de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/MachineFunctionPass.h" 25de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/MachineInstrBuilder.h" 26de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/MachineRegisterInfo.h" 27de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/Passes.h" 28de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/IR/Function.h" 29de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 30de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Target/TargetInstrInfo.h" 31de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 32de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarusing namespace llvm; 33de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 34de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarnamespace { 35de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 36de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass X86WinAllocaExpander : public MachineFunctionPass { 37de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarpublic: 38de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar X86WinAllocaExpander() : MachineFunctionPass(ID) {} 39de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 40de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool runOnMachineFunction(MachineFunction &MF) override; 41de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 42de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarprivate: 43de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// Strategies for lowering a WinAlloca. 44de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar enum Lowering { TouchAndSub, Sub, Probe }; 45de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 46de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// Deterministic-order map from WinAlloca instruction to desired lowering. 47de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar typedef MapVector<MachineInstr*, Lowering> LoweringMap; 48de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 49de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// Compute which lowering to use for each WinAlloca instruction. 50de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void computeLowerings(MachineFunction &MF, LoweringMap& Lowerings); 51de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 52de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// Get the appropriate lowering based on current offset and amount. 53de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Lowering getLowering(int64_t CurrentOffset, int64_t AllocaAmount); 54de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 55de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// Lower a WinAlloca instruction. 56de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void lower(MachineInstr* MI, Lowering L); 57de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 58de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineRegisterInfo *MRI; 59de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const X86Subtarget *STI; 60de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const TargetInstrInfo *TII; 61de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const X86RegisterInfo *TRI; 62de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned StackPtr; 63de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned SlotSize; 64de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int64_t StackProbeSize; 65de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 66de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const char *getPassName() const override { return "X86 WinAlloca Expander"; } 67de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar static char ID; 68de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}; 69de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 70de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarchar X86WinAllocaExpander::ID = 0; 71de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 72de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} // end anonymous namespace 73de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 74de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarFunctionPass *llvm::createX86WinAllocaExpander() { 75de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return new X86WinAllocaExpander(); 76de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 77de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 78de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// Return the allocation amount for a WinAlloca instruction, or -1 if unknown. 79de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic int64_t getWinAllocaAmount(MachineInstr *MI, MachineRegisterInfo *MRI) { 80de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MI->getOpcode() == X86::WIN_ALLOCA_32 || 81de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MI->getOpcode() == X86::WIN_ALLOCA_64); 82de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MI->getOperand(0).isReg()); 83de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 84de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned AmountReg = MI->getOperand(0).getReg(); 85de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *Def = MRI->getUniqueVRegDef(AmountReg); 86de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 87de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Look through copies. 88de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar while (Def && Def->isCopy() && Def->getOperand(1).isReg()) 89de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Def = MRI->getUniqueVRegDef(Def->getOperand(1).getReg()); 90de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 91de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!Def || 92de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar (Def->getOpcode() != X86::MOV32ri && Def->getOpcode() != X86::MOV64ri) || 93de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar !Def->getOperand(1).isImm()) 94de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return -1; 95de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 96de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Def->getOperand(1).getImm(); 97de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 98de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 99de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarX86WinAllocaExpander::Lowering 100de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarX86WinAllocaExpander::getLowering(int64_t CurrentOffset, 101de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int64_t AllocaAmount) { 102de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // For a non-constant amount or a large amount, we have to probe. 103de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (AllocaAmount < 0 || AllocaAmount > StackProbeSize) 104de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Probe; 105de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 106de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // If it fits within the safe region of the stack, just subtract. 107de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (CurrentOffset + AllocaAmount <= StackProbeSize) 108de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Sub; 109de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 110de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Otherwise, touch the current tip of the stack, then subtract. 111de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return TouchAndSub; 112de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 113de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 114de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic bool isPushPop(const MachineInstr &MI) { 115de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar switch (MI.getOpcode()) { 116de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::PUSH32i8: 117de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::PUSH32r: 118de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::PUSH32rmm: 119de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::PUSH32rmr: 120de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::PUSHi32: 121de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::PUSH64i8: 122de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::PUSH64r: 123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::PUSH64rmm: 124de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::PUSH64rmr: 125de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::PUSH64i32: 126de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::POP32r: 127de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case X86::POP64r: 128de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 129de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar default: 130de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 131de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 132de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 133de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 134de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid X86WinAllocaExpander::computeLowerings(MachineFunction &MF, 135de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LoweringMap &Lowerings) { 136de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Do a one-pass reverse post-order walk of the CFG to conservatively estimate 137de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // the offset between the stack pointer and the lowest touched part of the 138de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // stack, and use that to decide how to lower each WinAlloca instruction. 139de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 140de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Initialize OutOffset[B], the stack offset at exit from B, to something big. 141de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DenseMap<MachineBasicBlock *, int64_t> OutOffset; 142de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (MachineBasicBlock &MBB : MF) 143de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OutOffset[&MBB] = INT32_MAX; 144de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 145de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Note: we don't know the offset at the start of the entry block since the 146de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // prologue hasn't been inserted yet, and how much that will adjust the stack 147de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // pointer depends on register spills, which have not been computed yet. 148de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 149de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Compute the reverse post-order. 150de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ReversePostOrderTraversal<MachineFunction*> RPO(&MF); 151de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 152de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (MachineBasicBlock *MBB : RPO) { 153de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int64_t Offset = -1; 154de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (MachineBasicBlock *Pred : MBB->predecessors()) 155de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Offset = std::max(Offset, OutOffset[Pred]); 156de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Offset == -1) Offset = INT32_MAX; 157de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 158de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (MachineInstr &MI : *MBB) { 159de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (MI.getOpcode() == X86::WIN_ALLOCA_32 || 160de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MI.getOpcode() == X86::WIN_ALLOCA_64) { 161de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // A WinAlloca moves StackPtr, and potentially touches it. 162de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int64_t Amount = getWinAllocaAmount(&MI, MRI); 163de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Lowering L = getLowering(Offset, Amount); 164de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Lowerings[&MI] = L; 165de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar switch (L) { 166de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Sub: 167de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Offset += Amount; 168de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 169de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case TouchAndSub: 170de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Offset = Amount; 171de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 172de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Probe: 173de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Offset = 0; 174de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 175de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 176de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else if (MI.isCall() || isPushPop(MI)) { 177de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Calls, pushes and pops touch the tip of the stack. 178de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Offset = 0; 179de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else if (MI.getOpcode() == X86::ADJCALLSTACKUP32 || 180de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MI.getOpcode() == X86::ADJCALLSTACKUP64) { 181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Offset -= MI.getOperand(0).getImm(); 182de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else if (MI.getOpcode() == X86::ADJCALLSTACKDOWN32 || 183de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MI.getOpcode() == X86::ADJCALLSTACKDOWN64) { 184de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Offset += MI.getOperand(0).getImm(); 185de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else if (MI.modifiesRegister(StackPtr, TRI)) { 186de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Any other modification of SP means we've lost track of it. 187de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Offset = INT32_MAX; 188de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 189de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 190de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 191de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OutOffset[MBB] = Offset; 192de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 193de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 194de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 195de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic unsigned getSubOpcode(bool Is64Bit, int64_t Amount) { 196de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Is64Bit) 197de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return isInt<8>(Amount) ? X86::SUB64ri8 : X86::SUB64ri32; 198de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return isInt<8>(Amount) ? X86::SUB32ri8 : X86::SUB32ri; 199de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 200de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 201de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid X86WinAllocaExpander::lower(MachineInstr* MI, Lowering L) { 202de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DebugLoc DL = MI->getDebugLoc(); 203de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock *MBB = MI->getParent(); 204de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator I = *MI; 205de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 206de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int64_t Amount = getWinAllocaAmount(MI, MRI); 207de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Amount == 0) { 208de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MI->eraseFromParent(); 209de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return; 210de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 211de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 212de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Is64Bit = STI->is64Bit(); 213de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(SlotSize == 4 || SlotSize == 8); 214de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned RegA = (SlotSize == 8) ? X86::RAX : X86::EAX; 215de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 216de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar switch (L) { 217de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case TouchAndSub: 218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(Amount >= SlotSize); 219de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Use a push to touch the top of the stack. 221de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(*MBB, I, DL, TII->get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) 222de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(RegA, RegState::Undef); 223de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Amount -= SlotSize; 224de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!Amount) 225de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 226de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 227de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Fall through to make any remaining adjustment. 228de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Sub: 229de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(Amount > 0); 230de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Amount == SlotSize) { 231de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Use push to save size. 232de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(*MBB, I, DL, TII->get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) 233de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(RegA, RegState::Undef); 234de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else { 235de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Sub. 236de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(*MBB, I, DL, TII->get(getSubOpcode(Is64Bit, Amount)), StackPtr) 237de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(StackPtr) 238de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addImm(Amount); 239de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 240de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 241de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Probe: 242de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // The probe lowering expects the amount in RAX/EAX. 243de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::COPY), RegA) 244de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(MI->getOperand(0).getReg()); 245de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 246de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Do the probe. 247de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar STI->getFrameLowering()->emitStackProbe(*MBB->getParent(), *MBB, MI, DL, 248de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /*InPrologue=*/false); 249de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 250de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 251de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 252de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned AmountReg = MI->getOperand(0).getReg(); 253de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MI->eraseFromParent(); 254de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 255de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Delete the definition of AmountReg, possibly walking a chain of copies. 256de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (;;) { 257de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!MRI->use_empty(AmountReg)) 258de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 259de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *AmountDef = MRI->getUniqueVRegDef(AmountReg); 260de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!AmountDef) 261de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 262de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (AmountDef->isCopy() && AmountDef->getOperand(1).isReg()) 263de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar AmountReg = AmountDef->getOperand(1).isReg(); 264de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar AmountDef->eraseFromParent(); 265de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 266de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 267de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 268de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 269de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool X86WinAllocaExpander::runOnMachineFunction(MachineFunction &MF) { 270de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!MF.getInfo<X86MachineFunctionInfo>()->hasWinAlloca()) 271de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 272de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 273de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MRI = &MF.getRegInfo(); 274de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar STI = &MF.getSubtarget<X86Subtarget>(); 275de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TII = STI->getInstrInfo(); 276de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TRI = STI->getRegisterInfo(); 277de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StackPtr = TRI->getStackRegister(); 278de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SlotSize = TRI->getSlotSize(); 279de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 280de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StackProbeSize = 4096; 281de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (MF.getFunction()->hasFnAttribute("stack-probe-size")) { 282de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MF.getFunction() 283de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ->getFnAttribute("stack-probe-size") 284de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .getValueAsString() 285de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .getAsInteger(0, StackProbeSize); 286de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 287de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 288de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LoweringMap Lowerings; 289de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar computeLowerings(MF, Lowerings); 290de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &P : Lowerings) 291de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar lower(P.first, P.second); 292de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 293de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 294de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 295