From c63b5fcb2a272bb98d4ff0d106e78faf9cf32644 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 22 Oct 2018 21:55:26 +0000 Subject: [PATCH] [WebAssembly][NFC] Remove WebAssemblyStackifier TableGen backend Summary: Replace its functionality with a TableGen InstrInfo relational instruction mapping. Although arguably more complex than the TableGen backend, the relational mapping is a smaller maintenance burden than a TableGen backend. Reviewers: aardappel, aheejin, dschuff Subscribers: mgorny, sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D53307 llvm-svn: 344962 --- llvm/lib/Target/WebAssembly/CMakeLists.txt | 1 - .../Target/WebAssembly/WebAssemblyInstrControl.td | 10 +++-- .../Target/WebAssembly/WebAssemblyInstrFormats.td | 17 +++++---- .../lib/Target/WebAssembly/WebAssemblyInstrInfo.td | 13 +++++++ .../Target/WebAssembly/WebAssemblyMCInstLower.cpp | 27 ++++--------- llvm/utils/TableGen/CMakeLists.txt | 1 - llvm/utils/TableGen/TableGen.cpp | 8 +--- llvm/utils/TableGen/TableGenBackends.h | 1 - .../TableGen/WebAssemblyDisassemblerEmitter.cpp | 13 ++++--- .../TableGen/WebAssemblyStackifierEmitter.cpp | 44 ---------------------- 10 files changed, 44 insertions(+), 91 deletions(-) delete mode 100644 llvm/utils/TableGen/WebAssemblyStackifierEmitter.cpp diff --git a/llvm/lib/Target/WebAssembly/CMakeLists.txt b/llvm/lib/Target/WebAssembly/CMakeLists.txt index 2af5b9c..549229a 100644 --- a/llvm/lib/Target/WebAssembly/CMakeLists.txt +++ b/llvm/lib/Target/WebAssembly/CMakeLists.txt @@ -9,7 +9,6 @@ tablegen(LLVM WebAssemblyGenInstrInfo.inc -gen-instr-info) tablegen(LLVM WebAssemblyGenMCCodeEmitter.inc -gen-emitter) tablegen(LLVM WebAssemblyGenRegisterInfo.inc -gen-register-info) tablegen(LLVM WebAssemblyGenSubtargetInfo.inc -gen-subtarget) -tablegen(LLVM WebAssemblyGenStackifier.inc -gen-wasm-stackifier) add_public_tablegen_target(WebAssemblyCommonTableGen) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td index ed9879a..be9cdc5 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td @@ -43,26 +43,28 @@ def : Pat<(brcond (i32 (seteq I32:$cond, 0)), bb:$dst), let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in { let isCodeGenOnly = 1 in def BR_TABLE_I32 : NI<(outs), (ins I32:$index, variable_ops), - [(WebAssemblybr_table I32:$index)], 0, + [(WebAssemblybr_table I32:$index)], "false", "br_table \t$index", 0x0e> { let TSFlags{0} = 1; let TSFlags{1} = 1; } +let BaseName = "BR_TABLE_I32" in def BR_TABLE_I32_S : NI<(outs), (ins variable_ops), - [], 1, + [], "true", "br_table", 0x0e> { let TSFlags{0} = 1; let TSFlags{1} = 1; } let isCodeGenOnly = 1 in def BR_TABLE_I64 : NI<(outs), (ins I64:$index, variable_ops), - [(WebAssemblybr_table I64:$index)], 0, + [(WebAssemblybr_table I64:$index)], "false", "br_table \t$index"> { let TSFlags{0} = 1; let TSFlags{1} = 1; } +let BaseName = "BR_TABLE_I64" in def BR_TABLE_I64_S : NI<(outs), (ins variable_ops), - [], 1, + [], "true", "br_table"> { let TSFlags{0} = 1; let TSFlags{1} = 1; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td index 2d23acf..97583ea 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td @@ -15,17 +15,19 @@ // WebAssembly Instruction Format. // We instantiate 2 of these for every actual instruction (register based // and stack based), see below. -class WebAssemblyInst inst, string asmstr, bit stack> : Instruction { - field bits<32> Inst = inst; // Instruction encoding. - field bit StackBased = stack; +class WebAssemblyInst inst, string asmstr, string stack> : StackRel, + Instruction { + bits<32> Inst = inst; // Instruction encoding. + string StackBased = stack; + string BaseName = NAME; let Namespace = "WebAssembly"; let Pattern = []; let AsmString = asmstr; } // Normal instructions. Default instantiation of a WebAssemblyInst. -class NI pattern, bit stack, string asmstr = "", - bits<32> inst = -1> +class NI pattern, string stack, + string asmstr = "", bits<32> inst = -1> : WebAssemblyInst { dag OutOperandList = oops; dag InOperandList = iops; @@ -50,8 +52,9 @@ multiclass I pattern_r, string asmstr_r = "", string asmstr_s = "", bits<32> inst = -1> { let isCodeGenOnly = 1 in - def "" : NI; - def _S : NI; + def "" : NI; + let BaseName = NAME in + def _S : NI; } // For instructions that have no register ops, so both sets are the same. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td index 8d98510..c5b419832 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td @@ -154,6 +154,19 @@ def TypeIndex : Operand; } // OperandNamespace = "WebAssembly" //===----------------------------------------------------------------------===// +// WebAssembly Register to Stack instruction mapping +//===----------------------------------------------------------------------===// + +class StackRel; +def getStackOpcode : InstrMapping { + let FilterClass = "StackRel"; + let RowFields = ["BaseName"]; + let ColFields = ["StackBased"]; + let KeyCol = ["false"]; + let ValueCols = [["true"]]; +} + +//===----------------------------------------------------------------------===// // WebAssembly Instruction Format Definitions. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp index e9a0cf5..ebd3747 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -30,6 +30,11 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; +// Defines llvm::WebAssembly::getStackOpcode to convert register instructions to +// stack instructions +#define GET_INSTRMAP_INFO 1 +#include "WebAssemblyGenInstrInfo.inc" + // This disables the removal of registers when lowering into MC, as required // by some current tests. static cl::opt @@ -38,7 +43,6 @@ static cl::opt " instruction output for test purposes only."), cl::init(false)); -static unsigned regInstructionToStackInstruction(unsigned OpCode); static void removeRegisterOperands(const MachineInstr *MI, MCInst &OutMI); MCSymbol * @@ -254,7 +258,8 @@ static void removeRegisterOperands(const MachineInstr *MI, MCInst &OutMI) { // Transform to _S instruction. auto RegOpcode = OutMI.getOpcode(); - auto StackOpcode = regInstructionToStackInstruction(RegOpcode); + auto StackOpcode = WebAssembly::getStackOpcode(RegOpcode); + assert(StackOpcode != -1 && "Failed to stackify instruction"); OutMI.setOpcode(StackOpcode); // Remove register operands. @@ -265,21 +270,3 @@ static void removeRegisterOperands(const MachineInstr *MI, MCInst &OutMI) { } } } - -static unsigned regInstructionToStackInstruction(unsigned OpCode) { - // For most opcodes, this function could have been implemented as "return - // OpCode + 1", but since table-gen alphabetically sorts them, this cannot be - // guaranteed (see e.g. BR and BR_IF). Instead we use a giant switch statement - // generated by a custom TableGen backend (WebAssemblyStackifierEmitter.cpp) - // that emits switch cases of the form - // - // case WebAssembly::RegisterInstr: return WebAssembly::StackInstr; - // - // for every pair of equivalent register and stack instructions. - switch (OpCode) { - default: - llvm_unreachable( - "unknown WebAssembly instruction in WebAssemblyMCInstLower pass"); -#include "WebAssemblyGenStackifier.inc" - } -} diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt index 5ac3eca..0428249 100644 --- a/llvm/utils/TableGen/CMakeLists.txt +++ b/llvm/utils/TableGen/CMakeLists.txt @@ -46,7 +46,6 @@ add_tablegen(llvm-tblgen LLVM X86ModRMFilters.cpp X86RecognizableInstr.cpp WebAssemblyDisassemblerEmitter.cpp - WebAssemblyStackifierEmitter.cpp CTagsEmitter.cpp ) set_target_properties(llvm-tblgen PROPERTIES FOLDER "Tablegenning") diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp index 9e526b6..b782606 100644 --- a/llvm/utils/TableGen/TableGen.cpp +++ b/llvm/utils/TableGen/TableGen.cpp @@ -53,7 +53,6 @@ enum ActionType { GenX86EVEX2VEXTables, GenX86FoldTables, GenRegisterBank, - GenWebAssemblyStackifier, }; namespace { @@ -118,9 +117,7 @@ namespace { clEnumValN(GenX86FoldTables, "gen-x86-fold-tables", "Generate X86 fold tables"), clEnumValN(GenRegisterBank, "gen-register-bank", - "Generate registers bank descriptions"), - clEnumValN(GenWebAssemblyStackifier, "gen-wasm-stackifier", - "Generate WebAssembly stackification cases"))); + "Generate registers bank descriptions"))); cl::OptionCategory PrintEnumsCat("Options for -print-enums"); cl::opt @@ -234,9 +231,6 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenX86FoldTables: EmitX86FoldTables(Records, OS); break; - case GenWebAssemblyStackifier: - EmitWebAssemblyStackifier(Records, OS); - break; } return false; diff --git a/llvm/utils/TableGen/TableGenBackends.h b/llvm/utils/TableGen/TableGenBackends.h index f7ed5cc..1329a6d 100644 --- a/llvm/utils/TableGen/TableGenBackends.h +++ b/llvm/utils/TableGen/TableGenBackends.h @@ -89,7 +89,6 @@ void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS); void EmitX86EVEX2VEXTables(RecordKeeper &RK, raw_ostream &OS); void EmitX86FoldTables(RecordKeeper &RK, raw_ostream &OS); void EmitRegisterBank(RecordKeeper &RK, raw_ostream &OS); -void EmitWebAssemblyStackifier(RecordKeeper &RK, raw_ostream &OS); } // End llvm namespace diff --git a/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp b/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp index f9c3cb1..a8edfdc 100644 --- a/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp +++ b/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp @@ -42,12 +42,13 @@ void emitWebAssemblyDisassemblerTables( auto Prefix = Opc >> 8; Opc = Opc & 0xFF; auto &CGIP = OpcodeTable[Prefix][Opc]; - // All wasm instructions have a StackBased fieldof type bit, we only want - // the instructions for which this is 1. - auto Bit = Def.getValue("StackBased")->getValue()-> - getCastTo(BitRecTy::get()); - auto IsStackBased = Bit && reinterpret_cast(Bit) - ->getValue(); + // All wasm instructions have a StackBased field of type string, we only + // want the instructions for which this is "true". + auto StackString = + Def.getValue("StackBased")->getValue()->getCastTo(StringRecTy::get()); + auto IsStackBased = + StackString && + reinterpret_cast(StackString)->getValue() == "true"; if (IsStackBased && !CGIP.second) { // this picks the first of many typed variants, which is // currently the except_ref one, though this shouldn't matter for diff --git a/llvm/utils/TableGen/WebAssemblyStackifierEmitter.cpp b/llvm/utils/TableGen/WebAssemblyStackifierEmitter.cpp deleted file mode 100644 index 0b9741d..0000000 --- a/llvm/utils/TableGen/WebAssemblyStackifierEmitter.cpp +++ /dev/null @@ -1,44 +0,0 @@ -//===- WebAssemblyStackifierEmitter.cpp - Stackifier cases ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file emits the switch statement cases to translate WebAssembly -// instructions to their stack forms. -// -//===----------------------------------------------------------------------===// - -#include "WebAssemblyDisassemblerEmitter.h" -#include "llvm/TableGen/Record.h" - -namespace llvm { - -// Find all register WebAssembly instructions and their corresponding stack -// instructions. For each pair, emit a switch case of the form -// -// case WebAssembly::RegisterInstr: return WebAssembly::StackInstr; -// -// For example, -// -// case WebAssembly::ADD_I32: return WebAssembly::ADD_I32_S; -// -// This is useful for converting instructions from their register form to their -// equivalent stack form. -void EmitWebAssemblyStackifier(RecordKeeper &RK, raw_ostream &OS) { - Record *InstrClass = RK.getClass("WebAssemblyInst"); - for (auto &RecordPair : RK.getDefs()) { - if (!RecordPair.second->isSubClassOf(InstrClass)) - continue; - bool IsStackBased = RecordPair.second->getValueAsBit("StackBased"); - if (IsStackBased) - continue; - OS << " case WebAssembly::" << RecordPair.first << ": return " - << "WebAssembly::" << RecordPair.first << "_S;\n"; - } -} - -} // namespace llvm -- 2.7.4