//===----- X86WinAllocaExpander.cpp - Expand WinAlloca pseudo instruction -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a pass that expands WinAlloca pseudo-instructions.
//
// It performs a conservative analysis to determine whether each allocation
// falls within a region of the stack that is safe to use, or whether stack
// probes must be emitted.
//
//===----------------------------------------------------------------------===//

#include "X86.h"
#include "X86InstrBuilder.h"
#include "X86InstrInfo.h"
#include "X86MachineFunctionInfo.h"
#include "X86Subtarget.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"

using namespace llvm;

namespace {

class X86WinAllocaExpander : public MachineFunctionPass {
public:
  X86WinAllocaExpander() : MachineFunctionPass(ID) {}

  bool runOnMachineFunction(MachineFunction &MF) override;

private:
  /// Strategies for lowering a WinAlloca.
  enum Lowering { TouchAndSub, Sub, Probe };

  /// Deterministic-order map from WinAlloca instruction to desired lowering.
  typedef MapVector<MachineInstr*, Lowering> LoweringMap;

  /// Compute which lowering to use for each WinAlloca instruction.
  void computeLowerings(MachineFunction &MF, LoweringMap& Lowerings);

  /// Get the appropriate lowering based on current offset and amount.
  Lowering getLowering(int64_t CurrentOffset, int64_t AllocaAmount);

  /// Lower a WinAlloca instruction.
  void lower(MachineInstr* MI, Lowering L);

  MachineRegisterInfo *MRI;
  const X86Subtarget *STI;
  const TargetInstrInfo *TII;
  const X86RegisterInfo *TRI;
  unsigned StackPtr;
  unsigned SlotSize;
  int64_t StackProbeSize;

  StringRef getPassName() const override { return "X86 WinAlloca Expander"; }
  static char ID;
};

char X86WinAllocaExpander::ID = 0;

} // end anonymous namespace

FunctionPass *llvm::createX86WinAllocaExpander() {
  return new X86WinAllocaExpander();
}

/// Return the allocation amount for a WinAlloca instruction, or -1 if unknown.
static int64_t getWinAllocaAmount(MachineInstr *MI, MachineRegisterInfo *MRI) {
  assert(MI->getOpcode() == X86::WIN_ALLOCA_32 ||
         MI->getOpcode() == X86::WIN_ALLOCA_64);
  assert(MI->getOperand(0).isReg());

  unsigned AmountReg = MI->getOperand(0).getReg();
  MachineInstr *Def = MRI->getUniqueVRegDef(AmountReg);

  // Look through copies.
  while (Def && Def->isCopy() && Def->getOperand(1).isReg())
    Def = MRI->getUniqueVRegDef(Def->getOperand(1).getReg());

  if (!Def ||
      (Def->getOpcode() != X86::MOV32ri && Def->getOpcode() != X86::MOV64ri) ||
      !Def->getOperand(1).isImm())
    return -1;

  return Def->getOperand(1).getImm();
}

X86WinAllocaExpander::Lowering
X86WinAllocaExpander::getLowering(int64_t CurrentOffset,
                                  int64_t AllocaAmount) {
  // For a non-constant amount or a large amount, we have to probe.
  if (AllocaAmount < 0 || AllocaAmount > StackProbeSize)
    return Probe;

  // If it fits within the safe region of the stack, just subtract.
  if (CurrentOffset + AllocaAmount <= StackProbeSize)
    return Sub;

  // Otherwise, touch the current tip of the stack, then subtract.
  return TouchAndSub;
}

static bool isPushPop(const MachineInstr &MI) {
  switch (MI.getOpcode()) {
  case X86::PUSH32i8:
  case X86::PUSH32r:
  case X86::PUSH32rmm:
  case X86::PUSH32rmr:
  case X86::PUSHi32:
  case X86::PUSH64i8:
  case X86::PUSH64r:
  case X86::PUSH64rmm:
  case X86::PUSH64rmr:
  case X86::PUSH64i32:
  case X86::POP32r:
  case X86::POP64r:
    return true;
  default:
    return false;
  }
}

void X86WinAllocaExpander::computeLowerings(MachineFunction &MF,
                                            LoweringMap &Lowerings) {
  // Do a one-pass reverse post-order walk of the CFG to conservatively estimate
  // the offset between the stack pointer and the lowest touched part of the
  // stack, and use that to decide how to lower each WinAlloca instruction.

  // Initialize OutOffset[B], the stack offset at exit from B, to something big.
  DenseMap<MachineBasicBlock *, int64_t> OutOffset;
  for (MachineBasicBlock &MBB : MF)
    OutOffset[&MBB] = INT32_MAX;

  // Note: we don't know the offset at the start of the entry block since the
  // prologue hasn't been inserted yet, and how much that will adjust the stack
  // pointer depends on register spills, which have not been computed yet.

  // Compute the reverse post-order.
  ReversePostOrderTraversal<MachineFunction*> RPO(&MF);

  for (MachineBasicBlock *MBB : RPO) {
    int64_t Offset = -1;
    for (MachineBasicBlock *Pred : MBB->predecessors())
      Offset = std::max(Offset, OutOffset[Pred]);
    if (Offset == -1) Offset = INT32_MAX;

    for (MachineInstr &MI : *MBB) {
      if (MI.getOpcode() == X86::WIN_ALLOCA_32 ||
          MI.getOpcode() == X86::WIN_ALLOCA_64) {
        // A WinAlloca moves StackPtr, and potentially touches it.
        int64_t Amount = getWinAllocaAmount(&MI, MRI);
        Lowering L = getLowering(Offset, Amount);
        Lowerings[&MI] = L;
        switch (L) {
        case Sub:
          Offset += Amount;
          break;
        case TouchAndSub:
          Offset = Amount;
          break;
        case Probe:
          Offset = 0;
          break;
        }
      } else if (MI.isCall() || isPushPop(MI)) {
        // Calls, pushes and pops touch the tip of the stack.
        Offset = 0;
      } else if (MI.getOpcode() == X86::ADJCALLSTACKUP32 ||
                 MI.getOpcode() == X86::ADJCALLSTACKUP64) {
        Offset -= MI.getOperand(0).getImm();
      } else if (MI.getOpcode() == X86::ADJCALLSTACKDOWN32 ||
                 MI.getOpcode() == X86::ADJCALLSTACKDOWN64) {
        Offset += MI.getOperand(0).getImm();
      } else if (MI.modifiesRegister(StackPtr, TRI)) {
        // Any other modification of SP means we've lost track of it.
        Offset = INT32_MAX;
      }
    }

    OutOffset[MBB] = Offset;
  }
}

static unsigned getSubOpcode(bool Is64Bit, int64_t Amount) {
  if (Is64Bit)
    return isInt<8>(Amount) ? X86::SUB64ri8 : X86::SUB64ri32;
  return isInt<8>(Amount) ? X86::SUB32ri8 : X86::SUB32ri;
}

void X86WinAllocaExpander::lower(MachineInstr* MI, Lowering L) {
  DebugLoc DL = MI->getDebugLoc();
  MachineBasicBlock *MBB = MI->getParent();
  MachineBasicBlock::iterator I = *MI;

  int64_t Amount = getWinAllocaAmount(MI, MRI);
  if (Amount == 0) {
    MI->eraseFromParent();
    return;
  }

  bool Is64Bit = STI->is64Bit();
  assert(SlotSize == 4 || SlotSize == 8);
  unsigned RegA = (SlotSize == 8) ? X86::RAX : X86::EAX;

  switch (L) {
  case TouchAndSub:
    assert(Amount >= SlotSize);

    // Use a push to touch the top of the stack.
    BuildMI(*MBB, I, DL, TII->get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
        .addReg(RegA, RegState::Undef);
    Amount -= SlotSize;
    if (!Amount)
      break;

    // Fall through to make any remaining adjustment.
    LLVM_FALLTHROUGH;
  case Sub:
    assert(Amount > 0);
    if (Amount == SlotSize) {
      // Use push to save size.
      BuildMI(*MBB, I, DL, TII->get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
          .addReg(RegA, RegState::Undef);
    } else {
      // Sub.
      BuildMI(*MBB, I, DL, TII->get(getSubOpcode(Is64Bit, Amount)), StackPtr)
          .addReg(StackPtr)
          .addImm(Amount);
    }
    break;
  case Probe:
    // The probe lowering expects the amount in RAX/EAX.
    BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::COPY), RegA)
        .addReg(MI->getOperand(0).getReg());

    // Do the probe.
    STI->getFrameLowering()->emitStackProbe(*MBB->getParent(), *MBB, MI, DL,
                                            /*InPrologue=*/false);
    break;
  }

  unsigned AmountReg = MI->getOperand(0).getReg();
  MI->eraseFromParent();

  // Delete the definition of AmountReg, possibly walking a chain of copies.
  for (;;) {
    if (!MRI->use_empty(AmountReg))
      break;
    MachineInstr *AmountDef = MRI->getUniqueVRegDef(AmountReg);
    if (!AmountDef)
      break;
    if (AmountDef->isCopy() && AmountDef->getOperand(1).isReg())
      AmountReg = AmountDef->getOperand(1).isReg();
    AmountDef->eraseFromParent();
    break;
  }
}

bool X86WinAllocaExpander::runOnMachineFunction(MachineFunction &MF) {
  if (!MF.getInfo<X86MachineFunctionInfo>()->hasWinAlloca())
    return false;

  MRI = &MF.getRegInfo();
  STI = &MF.getSubtarget<X86Subtarget>();
  TII = STI->getInstrInfo();
  TRI = STI->getRegisterInfo();
  StackPtr = TRI->getStackRegister();
  SlotSize = TRI->getSlotSize();

  StackProbeSize = 4096;
  if (MF.getFunction()->hasFnAttribute("stack-probe-size")) {
    MF.getFunction()
        ->getFnAttribute("stack-probe-size")
        .getValueAsString()
        .getAsInteger(0, StackProbeSize);
  }

  LoweringMap Lowerings;
  computeLowerings(MF, Lowerings);
  for (auto &P : Lowerings)
    lower(P.first, P.second);

  return true;
}
