[WebAssembly] Introduce a new pseudo-operand for unused expression results.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252975 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2015-11-13 00:21:05 +00:00
parent c81095daa7
commit c7f1d5b5dc
6 changed files with 40 additions and 12 deletions

View File

@ -14,6 +14,7 @@
#include "InstPrinter/WebAssemblyInstPrinter.h"
#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
@ -36,6 +37,7 @@ WebAssemblyInstPrinter::WebAssemblyInstPrinter(const MCAsmInfo &MAI,
void WebAssemblyInstPrinter::printRegName(raw_ostream &OS,
unsigned RegNo) const {
assert(RegNo != WebAssemblyFunctionInfo::UnusedReg);
// FIXME: Revisit whether we actually print the get_local explicitly.
OS << "(get_local " << RegNo << ")";
}
@ -60,9 +62,14 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
"Instructions with multiple result values not implemented");
// FIXME: Revisit whether we actually print the set_local explicitly.
if (NumDefs != 0)
OS << "\n"
"\t" "set_local " << MI->getOperand(0).getReg() << ", $pop";
if (NumDefs != 0) {
unsigned WAReg = MI->getOperand(0).getReg();
// Only print the set_local if the register is used.
// TODO: Revisit this once the spec explains what should happen here.
if (WAReg != WebAssemblyFunctionInfo::UnusedReg)
OS << "\n"
"\t" "set_local " << WAReg << ", $pop";
}
}
static std::string toString(const APFloat &FP) {
@ -86,10 +93,14 @@ void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
if (OpNo < MII.get(MI->getOpcode()).getNumDefs())
O << "$push";
else
if (OpNo >= MII.get(MI->getOpcode()).getNumDefs())
printRegName(O, Op.getReg());
else {
if (Op.getReg() != WebAssemblyFunctionInfo::UnusedReg)
O << "$push";
else
O << "$discard";
}
} else if (Op.isImm())
O << Op.getImm();
else if (Op.isFPImm())

View File

@ -104,7 +104,9 @@ std::string WebAssemblyAsmPrinter::regToString(const MachineOperand &MO) {
if (TargetRegisterInfo::isPhysicalRegister(RegNo))
return WebAssemblyInstPrinter::getRegisterName(RegNo);
return utostr(MFI->getWAReg(RegNo));
unsigned WAReg = MFI->getWAReg(RegNo);
assert(WAReg != WebAssemblyFunctionInfo::UnusedReg);
return utostr(WAReg);
}
const char *WebAssemblyAsmPrinter::toString(MVT VT) const {

View File

@ -17,3 +17,9 @@
using namespace llvm;
WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() {}
void WebAssemblyFunctionInfo::initWARegs() {
assert(WARegs.empty());
unsigned Reg = UnusedReg;
WARegs.resize(MF.getRegInfo().getNumVirtRegs(), Reg);
}

View File

@ -43,11 +43,11 @@ public:
void addResult(MVT VT) { Results.push_back(VT); }
const std::vector<MVT> &getResults() const { return Results; }
void initWARegs() {
assert(WARegs.empty());
WARegs.resize(MF.getRegInfo().getNumVirtRegs(), -1u);
}
static const unsigned UnusedReg = -1u;
void initWARegs();
void setWAReg(unsigned VReg, unsigned WAReg) {
assert(WAReg != UnusedReg);
WARegs[TargetRegisterInfo::virtReg2Index(VReg)] = WAReg;
}
unsigned getWAReg(unsigned VReg) const {

View File

@ -90,7 +90,7 @@ bool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction &MF) {
// Skip unused registers.
if (MRI.use_empty(VReg))
continue;
if (MFI.getWAReg(VReg) == -1u)
if (MFI.getWAReg(VReg) == WebAssemblyFunctionInfo::UnusedReg)
MFI.setWAReg(VReg, NumArgRegs + CurReg++);
}

View File

@ -24,3 +24,12 @@ define i32 @unused_first(i32 %x, i32 %y) {
define i32 @unused_second(i32 %x, i32 %y) {
ret i32 %x
}
; CHECK-LABEL: call_something:
; CHECK-NEXT: call return_something, $discard{{$}}
; CHECK-NEXT: return{{$}}
declare i32 @return_something()
define void @call_something() {
call i32 @return_something()
ret void
}