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
--- /dev/null
+//===- 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<string classname> {
+ // The class name to use in the generated output.
+ string Classname = classname;
+}
include "AArch64InstrInfo.td"
include "AArch64SchedPredicates.td"
include "AArch64SchedPredExynos.td"
+include "AArch64Combine.td"
def AArch64InstrInfo : InstrInfo;
--- /dev/null
+//=- 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">;
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,
}
}
+ if (Generated.tryCombineAll(Observer, MI, B))
+ return true;
+
return false;
}
+#define AARCH64PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP
+#include "AArch64GenGICombiner.inc"
+#undef AARCH64PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP
+
// Pass boilerplate
// ================
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)
ExegesisEmitter.cpp
FastISelEmitter.cpp
FixedLenDecoderEmitter.cpp
+ GICombinerEmitter.cpp
GlobalISelEmitter.cpp
InfoByHwMode.cpp
InstrInfoEmitter.cpp
--- /dev/null
+//===- 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<std::string>
+ 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
GenAttributes,
GenSearchableTables,
GenGlobalISel,
+ GenGICombiner,
GenX86EVEX2VEXTables,
GenX86FoldTables,
GenRegisterBank,
"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",
case GenGlobalISel:
EmitGlobalISel(Records, OS);
break;
+ case GenGICombiner:
+ EmitGICombiner(Records, OS);
+ break;
case GenRegisterBank:
EmitRegisterBank(Records, OS);
break;
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);