From c7f1d5b5dca70722f17f48cd128dfef288760740 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 13 Nov 2015 00:21:05 +0000 Subject: [PATCH] [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 --- .../InstPrinter/WebAssemblyInstPrinter.cpp | 23 ++++++++++++++----- .../WebAssembly/WebAssemblyAsmPrinter.cpp | 4 +++- .../WebAssemblyMachineFunctionInfo.cpp | 6 +++++ .../WebAssemblyMachineFunctionInfo.h | 8 +++---- .../WebAssembly/WebAssemblyRegNumbering.cpp | 2 +- test/CodeGen/WebAssembly/unused-argument.ll | 9 ++++++++ 6 files changed, 40 insertions(+), 12 deletions(-) diff --git a/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp b/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp index cc77f56dce3..d3c4861e1d6 100644 --- a/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp +++ b/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp @@ -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()) diff --git a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 6fc309f0261..bcee99578f5 100644 --- a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -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 { diff --git a/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp b/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp index 542d984b900..225c5d32cb5 100644 --- a/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp +++ b/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp @@ -17,3 +17,9 @@ using namespace llvm; WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() {} + +void WebAssemblyFunctionInfo::initWARegs() { + assert(WARegs.empty()); + unsigned Reg = UnusedReg; + WARegs.resize(MF.getRegInfo().getNumVirtRegs(), Reg); +} diff --git a/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h index 81273c00471..475dcc33d78 100644 --- a/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h +++ b/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h @@ -43,11 +43,11 @@ public: void addResult(MVT VT) { Results.push_back(VT); } const std::vector &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 { diff --git a/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp b/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp index 96b0799d1c3..3fcf28ebdd2 100644 --- a/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp @@ -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++); } diff --git a/test/CodeGen/WebAssembly/unused-argument.ll b/test/CodeGen/WebAssembly/unused-argument.ll index 7b4eef5e4b9..b22de384868 100644 --- a/test/CodeGen/WebAssembly/unused-argument.ll +++ b/test/CodeGen/WebAssembly/unused-argument.ll @@ -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 +} -- 2.34.1