From 03bb65ceece39a9c44d33577ca5cc66b91c973d9 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Wed, 2 Oct 2019 21:13:07 +0000 Subject: [PATCH] [gicombiner] Add the boring boilerplate for the declarative combiner Summary: This is the first of a series of patches extracted from a much bigger WIP patch. It merely establishes the tblgen pass and the way empty combiner helpers are declared and integrated into a combiner info. The tablegen pass takes a -combiners option to select the combiner helper that will be generated. This can be given multiple values to generate multiple combiner helpers at once. Doing so helps to minimize parsing overhead. The reason for creating a GlobalISel subdirectory in utils/TableGen is that there will be quite a lot of non-pass files (~15) by the time the patch series is done. Reviewers: volkan Subscribers: mgorny, hiraditya, simoncook, Petar.Avramovic, s.egerton, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D68286 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@373527 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/GlobalISel/Combine.td | 17 ++++ lib/Target/AArch64/AArch64.td | 1 + lib/Target/AArch64/AArch64Combine.td | 15 +++ .../AArch64/AArch64PreLegalizerCombiner.cpp | 17 ++++ lib/Target/AArch64/CMakeLists.txt | 2 + utils/TableGen/CMakeLists.txt | 1 + utils/TableGen/GICombinerEmitter.cpp | 94 +++++++++++++++++++ utils/TableGen/TableGen.cpp | 6 ++ utils/TableGen/TableGenBackends.h | 1 + 9 files changed, 154 insertions(+) create mode 100644 include/llvm/Target/GlobalISel/Combine.td create mode 100644 lib/Target/AArch64/AArch64Combine.td create mode 100644 utils/TableGen/GICombinerEmitter.cpp diff --git a/include/llvm/Target/GlobalISel/Combine.td b/include/llvm/Target/GlobalISel/Combine.td new file mode 100644 index 00000000000..065e28eca8a --- /dev/null +++ b/include/llvm/Target/GlobalISel/Combine.td @@ -0,0 +1,17 @@ +//===- Combine.td - Combine rule definitions ---------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Declare GlobalISel combine rules and provide mechanisms to opt-out. +// +//===----------------------------------------------------------------------===// + +// Declares a combiner helper class +class GICombinerHelper { + // The class name to use in the generated output. + string Classname = classname; +} diff --git a/lib/Target/AArch64/AArch64.td b/lib/Target/AArch64/AArch64.td index 6689ee48200..51bf35d4a16 100644 --- a/lib/Target/AArch64/AArch64.td +++ b/lib/Target/AArch64/AArch64.td @@ -406,6 +406,7 @@ include "AArch64Schedule.td" include "AArch64InstrInfo.td" include "AArch64SchedPredicates.td" include "AArch64SchedPredExynos.td" +include "AArch64Combine.td" def AArch64InstrInfo : InstrInfo; diff --git a/lib/Target/AArch64/AArch64Combine.td b/lib/Target/AArch64/AArch64Combine.td new file mode 100644 index 00000000000..c4658f73b8d --- /dev/null +++ b/lib/Target/AArch64/AArch64Combine.td @@ -0,0 +1,15 @@ +//=- AArch64.td - Define AArch64 Combine Rules ---------------*- tablegen -*-=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// +//===----------------------------------------------------------------------===// + +include "llvm/Target/GlobalISel/Combine.td" + +def AArch64PreLegalizerCombinerHelper: GICombinerHelper< + "AArch64GenPreLegalizerCombinerHelper">; diff --git a/lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp b/lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp index 6df3f944f8c..bea75b83517 100644 --- a/lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp +++ b/lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp @@ -27,12 +27,22 @@ using namespace llvm; using namespace MIPatternMatch; +#define AARCH64PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS +#include "AArch64GenGICombiner.inc" +#undef AARCH64PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS + namespace { +#define AARCH64PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H +#include "AArch64GenGICombiner.inc" +#undef AARCH64PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H + class AArch64PreLegalizerCombinerInfo : public CombinerInfo { GISelKnownBits *KB; MachineDominatorTree *MDT; public: + AArch64GenPreLegalizerCombinerHelper Generated; + AArch64PreLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, GISelKnownBits *KB, MachineDominatorTree *MDT) : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, @@ -81,9 +91,16 @@ bool AArch64PreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, } } + if (Generated.tryCombineAll(Observer, MI, B)) + return true; + return false; } +#define AARCH64PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP +#include "AArch64GenGICombiner.inc" +#undef AARCH64PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP + // Pass boilerplate // ================ diff --git a/lib/Target/AArch64/CMakeLists.txt b/lib/Target/AArch64/CMakeLists.txt index 0da057ea997..8473ddfca4c 100644 --- a/lib/Target/AArch64/CMakeLists.txt +++ b/lib/Target/AArch64/CMakeLists.txt @@ -8,6 +8,8 @@ tablegen(LLVM AArch64GenDAGISel.inc -gen-dag-isel) tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler) tablegen(LLVM AArch64GenFastISel.inc -gen-fast-isel) tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel) +tablegen(LLVM AArch64GenGICombiner.inc -gen-global-isel-combiner + -combiners='AArch64PreLegalizerCombinerHelper') tablegen(LLVM AArch64GenInstrInfo.inc -gen-instr-info) tablegen(LLVM AArch64GenMCCodeEmitter.inc -gen-emitter) tablegen(LLVM AArch64GenMCPseudoLowering.inc -gen-pseudo-lowering) diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt index c88365a2b8c..d97f9359f54 100644 --- a/utils/TableGen/CMakeLists.txt +++ b/utils/TableGen/CMakeLists.txt @@ -24,6 +24,7 @@ add_tablegen(llvm-tblgen LLVM ExegesisEmitter.cpp FastISelEmitter.cpp FixedLenDecoderEmitter.cpp + GICombinerEmitter.cpp GlobalISelEmitter.cpp InfoByHwMode.cpp InstrInfoEmitter.cpp diff --git a/utils/TableGen/GICombinerEmitter.cpp b/utils/TableGen/GICombinerEmitter.cpp new file mode 100644 index 00000000000..7a9c87b6b93 --- /dev/null +++ b/utils/TableGen/GICombinerEmitter.cpp @@ -0,0 +1,94 @@ +//===- GlobalCombinerEmitter.cpp - Generate a combiner --------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \file Generate a combiner implementation for GlobalISel from a declarative +/// syntax +/// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Timer.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/TableGenBackend.h" +#include "CodeGenTarget.h" + +using namespace llvm; + +#define DEBUG_TYPE "gicombiner-emitter" + +cl::OptionCategory + GICombinerEmitterCat("Options for -gen-global-isel-combiner"); +static cl::list + SelectedCombiners("combiners", cl::desc("Emit the specified combiners"), + cl::cat(GICombinerEmitterCat), cl::CommaSeparated); +namespace { +class GICombinerEmitter { + StringRef Name; + Record *Combiner; +public: + explicit GICombinerEmitter(RecordKeeper &RK, StringRef Name); + ~GICombinerEmitter() {} + + StringRef getClassName() const { + return Combiner->getValueAsString("Classname"); + } + void run(raw_ostream &OS); + +}; + +GICombinerEmitter::GICombinerEmitter(RecordKeeper &RK, StringRef Name) + : Name(Name), Combiner(RK.getDef(Name)) {} + +void GICombinerEmitter::run(raw_ostream &OS) { + NamedRegionTimer T("Emit", "Time spent emitting the combiner", + "Code Generation", "Time spent generating code", + TimeRegions); + OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_DEPS\n" + << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_DEPS\n\n"; + + OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_H\n" + << "class " << getClassName() << " {\n" + << "public:\n" + << " bool tryCombineAll(\n" + << " GISelChangeObserver &Observer,\n" + << " MachineInstr &MI,\n" + << " MachineIRBuilder &B) const;\n" + << "};\n"; + OS << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_H\n\n"; + + OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_CPP\n" + << "\n" + << "bool " << getClassName() << "::tryCombineAll(\n" + << " GISelChangeObserver &Observer,\n" + << " MachineInstr &MI,\n" + << " MachineIRBuilder &B) const {\n" + << " MachineBasicBlock *MBB = MI.getParent();\n" + << " MachineFunction *MF = MBB->getParent();\n" + << " MachineRegisterInfo &MRI = MF->getRegInfo();\n" + << " (void)MBB; (void)MF; (void)MRI;\n\n"; + OS << "\n return false;\n" + << "}\n" + << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_CPP\n"; +} + +} // end anonymous namespace + +//===----------------------------------------------------------------------===// + +namespace llvm { +void EmitGICombiner(RecordKeeper &RK, raw_ostream &OS) { + CodeGenTarget Target(RK); + emitSourceFileHeader("Global Combiner", OS); + + if (SelectedCombiners.empty()) + PrintFatalError("No combiners selected with -combiners"); + for (const auto &Combiner : SelectedCombiners) + GICombinerEmitter(RK, Combiner).run(OS); +} + +} // namespace llvm diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp index d8dc27e7f72..817663b06e2 100644 --- a/utils/TableGen/TableGen.cpp +++ b/utils/TableGen/TableGen.cpp @@ -49,6 +49,7 @@ enum ActionType { GenAttributes, GenSearchableTables, GenGlobalISel, + GenGICombiner, GenX86EVEX2VEXTables, GenX86FoldTables, GenRegisterBank, @@ -114,6 +115,8 @@ cl::opt Action( "Generate generic binary-searchable table"), clEnumValN(GenGlobalISel, "gen-global-isel", "Generate GlobalISel selector"), + clEnumValN(GenGICombiner, "gen-global-isel-combiner", + "Generate GlobalISel combiner"), clEnumValN(GenX86EVEX2VEXTables, "gen-x86-EVEX2VEX-tables", "Generate X86 EVEX to VEX compress tables"), clEnumValN(GenX86FoldTables, "gen-x86-fold-tables", @@ -231,6 +234,9 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenGlobalISel: EmitGlobalISel(Records, OS); break; + case GenGICombiner: + EmitGICombiner(Records, OS); + break; case GenRegisterBank: EmitRegisterBank(Records, OS); break; diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h index 135ec65c0f9..9c21ef35440 100644 --- a/utils/TableGen/TableGenBackends.h +++ b/utils/TableGen/TableGenBackends.h @@ -85,6 +85,7 @@ void EmitCTags(RecordKeeper &RK, raw_ostream &OS); void EmitAttributes(RecordKeeper &RK, raw_ostream &OS); void EmitSearchableTables(RecordKeeper &RK, raw_ostream &OS); void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS); +void EmitGICombiner(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); -- 2.40.0