[WebAssembly] Introduce a new pseudo-operand for unused expression results.
authorDan Gohman <dan433584@gmail.com>
Fri, 13 Nov 2015 00:21:05 +0000 (00:21 +0000)
committerDan Gohman <dan433584@gmail.com>
Fri, 13 Nov 2015 00:21:05 +0000 (00:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252975 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp
lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp
test/CodeGen/WebAssembly/unused-argument.ll

index cc77f56..d3c4861 100644 (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())
index 6fc309f..bcee995 100644 (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 {
index 542d984..225c5d3 100644 (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);
+}
index 81273c0..475dcc3 100644 (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 {
index 96b0799..3fcf28e 100644 (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++);
   }
 
index 7b4eef5..b22de38 100644 (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
+}