llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
Derek Schuff d239e9c2e5 [WebAssembly] Switch varags calling convention to use a register
Instead of passing varargs directly on the user stack, allocate a buffer in
the caller's stack frame and pass a pointer to it. This simplifies the C
ABI (e.g. non-C callers of C functions do not need to use C's user stack if
they have their own mechanism) and allows further optimizations in the future
(e.g. fewer functions may need to use the stack).

Differential Revision: http://reviews.llvm.org/D17048

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260421 91177308-0d34-0410-b5e6-96231b3b80d8
2016-02-10 19:51:04 +00:00

114 lines
4.0 KiB
C++

// WebAssemblyMachineFunctionInfo.h-WebAssembly machine function info-*- C++ -*-
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file declares WebAssembly-specific per-machine-function
/// information.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
namespace llvm {
/// This class is derived from MachineFunctionInfo and contains private
/// WebAssembly-specific information for each MachineFunction.
class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
MachineFunction &MF;
std::vector<MVT> Params;
/// A mapping from CodeGen vreg index to WebAssembly register number.
std::vector<unsigned> WARegs;
/// A mapping from CodeGen vreg index to a boolean value indicating whether
/// the given register is considered to be "stackified", meaning it has been
/// determined or made to meet the stack requirements:
/// - single use (per path)
/// - single def (per path)
/// - defined and used in LIFO order with other stack registers
BitVector VRegStackified;
// One entry for each possible target reg. we expect it to be small.
std::vector<unsigned> PhysRegs;
// A virtual register holding the pointer to the vararg buffer for vararg
// functions. It is created and set in TLI::LowerFormalArguments and read by
// TLI::LowerVASTART
unsigned VarargVreg = -1U;
public:
explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF) {
PhysRegs.resize(WebAssembly::NUM_TARGET_REGS, -1U);
}
~WebAssemblyFunctionInfo() override;
void addParam(MVT VT) { Params.push_back(VT); }
const std::vector<MVT> &getParams() const { return Params; }
unsigned getVarargBufferVreg() const {
assert(VarargVreg != -1U && "Vararg vreg hasn't been set");
return VarargVreg;
}
void setVarargBufferVreg(unsigned Reg) { VarargVreg = Reg; }
static const unsigned UnusedReg = -1u;
void stackifyVReg(unsigned VReg) {
if (TargetRegisterInfo::virtReg2Index(VReg) >= VRegStackified.size())
VRegStackified.resize(TargetRegisterInfo::virtReg2Index(VReg) + 1);
VRegStackified.set(TargetRegisterInfo::virtReg2Index(VReg));
}
void unstackifyVReg(unsigned VReg) {
if (TargetRegisterInfo::virtReg2Index(VReg) >= VRegStackified.size())
return;
VRegStackified.reset(TargetRegisterInfo::virtReg2Index(VReg));
}
bool isVRegStackified(unsigned VReg) const {
if (TargetRegisterInfo::virtReg2Index(VReg) >= VRegStackified.size())
return false;
return VRegStackified.test(TargetRegisterInfo::virtReg2Index(VReg));
}
void initWARegs();
void setWAReg(unsigned VReg, unsigned WAReg) {
assert(WAReg != UnusedReg);
assert(TargetRegisterInfo::virtReg2Index(VReg) < WARegs.size());
WARegs[TargetRegisterInfo::virtReg2Index(VReg)] = WAReg;
}
unsigned getWAReg(unsigned Reg) const {
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
assert(TargetRegisterInfo::virtReg2Index(Reg) < WARegs.size());
return WARegs[TargetRegisterInfo::virtReg2Index(Reg)];
}
return PhysRegs[Reg];
}
// If new virtual registers are created after initWARegs has been called,
// this function can be used to add WebAssembly register mappings for them.
void addWAReg(unsigned VReg, unsigned WAReg) {
assert(VReg = WARegs.size());
WARegs.push_back(WAReg);
}
void addPReg(unsigned PReg, unsigned WAReg) {
assert(PReg < WebAssembly::NUM_TARGET_REGS);
assert(WAReg < -1U);
PhysRegs[PReg] = WAReg;
}
const std::vector<unsigned> &getPhysRegs() const { return PhysRegs; }
};
} // end namespace llvm
#endif