Index: llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h =================================================================== --- llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -568,6 +568,10 @@ ArrayRef> ArgRegs, Register SwiftErrorVReg, std::function GetCalleeReg) const; + /// For targets which want to use big-endian can enable it with + /// enableBigEndian() hook + virtual bool enableBigEndian() const { return false; } + /// For targets which support the "returned" parameter attribute, returns /// true if the given type is a valid one to use with "returned". virtual bool isTypeIsValidForThisReturn(EVT Ty) const { return false; } Index: llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -3122,7 +3122,9 @@ assert(PendingPHIs.empty() && "stale PHIs"); - if (!DL->isLittleEndian()) { + // Targets which want to use big endian can enable it using + // enableBigEndian() + if (!DL->isLittleEndian() && !CLI->enableBigEndian()) { // Currently we don't properly handle big endian code. OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure", F.getSubprogram(), &F.getEntryBlock()); Index: llvm/lib/Target/M68k/CMakeLists.txt =================================================================== --- llvm/lib/Target/M68k/CMakeLists.txt +++ llvm/lib/Target/M68k/CMakeLists.txt @@ -2,7 +2,9 @@ set(LLVM_TARGET_DEFINITIONS M68k.td) +tablegen(LLVM M68kGenGlobalISel.inc -gen-global-isel) tablegen(LLVM M68kGenRegisterInfo.inc -gen-register-info) +tablegen(LLVM M68kGenRegisterBank.inc -gen-register-bank) tablegen(LLVM M68kGenInstrInfo.inc -gen-instr-info) tablegen(LLVM M68kGenSubtargetInfo.inc -gen-subtarget) tablegen(LLVM M68kGenMCCodeBeads.inc -gen-code-beads) @@ -15,6 +17,10 @@ add_public_tablegen_target(M68kCommonTableGen) add_llvm_target(M68kCodeGen + GlSel/M68kCallLowering.cpp + GlSel/M68kInstructionSelector.cpp + GlSel/M68kLegalizerInfo.cpp + GlSel/M68kRegisterBankInfo.cpp M68kAsmPrinter.cpp M68kCollapseMOVEMPass.cpp M68kExpandPseudo.cpp @@ -34,6 +40,7 @@ AsmPrinter CodeGen Core + GlobalISel MC SelectionDAG Support Index: llvm/lib/Target/M68k/GlSel/M68kCallLowering.h =================================================================== --- /dev/null +++ llvm/lib/Target/M68k/GlSel/M68kCallLowering.h @@ -0,0 +1,49 @@ +//===-- M68kCallLowering.h - Call lowering -------------------*- C++ -*-===// +// +// 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 +/// This file implements the lowering of LLVM calls to machine code calls for +/// GlobalISel. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_M68K_GLSEL_M68KCALLLOWERING_H +#define LLVM_LIB_TARGET_M68K_GLSEL_M68KCALLLOWERING_H + +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/GlobalISel/CallLowering.h" +#include "llvm/CodeGen/ValueTypes.h" + +namespace llvm { + +class M68kTargetLowering; + +class M68kCallLowering : public CallLowering { + // TODO: We are only supporting return instruction with no value at this time + // point + +public: + M68kCallLowering(const M68kTargetLowering &TLI); + + bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, + ArrayRef VRegs, FunctionLoweringInfo &FLI, + Register SwiftErrorVReg) const override; + + bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, + ArrayRef> VRegs, + FunctionLoweringInfo &FLI) const override; + + bool lowerCall(MachineIRBuilder &MIRBuilder, + CallLoweringInfo &Info) const override; + + bool enableBigEndian() const override; +}; + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_M68K_GLSEL_M68KCALLLOWERING_H Index: llvm/lib/Target/M68k/GlSel/M68kCallLowering.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/M68k/GlSel/M68kCallLowering.cpp @@ -0,0 +1,51 @@ +//===-- M68kCallLowering.cpp - Call lowering -------------------*- C++ -*-===// +// +// 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 +/// This file implements the lowering of LLVM calls to machine code calls for +/// GlobalISel. +// +//===----------------------------------------------------------------------===// + +#include "M68kCallLowering.h" +#include "M68kISelLowering.h" +#include "M68kInstrInfo.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" +using namespace llvm; + +M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI) + : CallLowering(&TLI) {} + +bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, + const Value *Val, ArrayRef VRegs, + FunctionLoweringInfo &FLI, + Register SwiftErrorVReg) const { + + if (Val) + return false; + MIRBuilder.buildInstr(M68k::RTS); + return true; +} + +bool M68kCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, + const Function &F, + ArrayRef> VRegs, + FunctionLoweringInfo &FLI) const { + + if (F.arg_empty()) + return true; + + return false; +} + +bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, + CallLoweringInfo &Info) const { + return false; +} + +bool M68kCallLowering::enableBigEndian() const { return true; } Index: llvm/lib/Target/M68k/GlSel/M68kInstructionSelector.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/M68k/GlSel/M68kInstructionSelector.cpp @@ -0,0 +1,90 @@ +//===- M68kInstructionSelector.cpp ------------------------------*- C++ -*-===// +//===----------------------------------------------------------------------===// +/// \file +/// This file implements the targeting of the InstructionSelector class for +/// M68k. +/// \todo This should be generated by TableGen. +//===----------------------------------------------------------------------===// + +#include "M68kRegisterBankInfo.h" +#include "M68kSubtarget.h" +#include "M68kTargetMachine.h" +#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" +#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "m68k-isel" + +using namespace llvm; + +#define GET_GLOBALISEL_PREDICATE_BITSET +#include "M68kGenGlobalISel.inc" +#undef GET_GLOBALISEL_PREDICATE_BITSET + +namespace { + +class M68kInstructionSelector : public InstructionSelector { +public: + M68kInstructionSelector(const M68kTargetMachine &TM, const M68kSubtarget &STI, + const M68kRegisterBankInfo &RBI); + + bool select(MachineInstr &I) override; + static const char *getName() { return DEBUG_TYPE; } + +private: + bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; + + const M68kTargetMachine &TM; + const M68kInstrInfo &TII; + const M68kRegisterInfo &TRI; + const M68kRegisterBankInfo &RBI; + +#define GET_GLOBALISEL_PREDICATES_DECL +#include "M68kGenGlobalISel.inc" +#undef GET_GLOBALISEL_PREDICATES_DECL + +#define GET_GLOBALISEL_TEMPORARIES_DECL +#include "M68kGenGlobalISel.inc" +#undef GET_GLOBALISEL_TEMPORARIES_DECL +}; + +} // end anonymous namespace + +#define GET_GLOBALISEL_IMPL +#include "M68kGenGlobalISel.inc" +#undef GET_GLOBALISEL_IMPL + +M68kInstructionSelector::M68kInstructionSelector( + const M68kTargetMachine &TM, const M68kSubtarget &STI, + const M68kRegisterBankInfo &RBI) + : InstructionSelector(), TM(TM), TII(*STI.getInstrInfo()), + TRI(*STI.getRegisterInfo()), RBI(RBI), + +#define GET_GLOBALISEL_PREDICATES_INIT +#include "M68kGenGlobalISel.inc" +#undef GET_GLOBALISEL_PREDICATES_INIT +#define GET_GLOBALISEL_TEMPORARIES_INIT +#include "M68kGenGlobalISel.inc" +#undef GET_GLOBALISEL_TEMPORARIES_INIT +{ +} + +bool M68kInstructionSelector::select(MachineInstr &I) { + // Certain non-generic instructions also need some special handling. + if (!isPreISelGenericOpcode(I.getOpcode())) + return true; + + if (selectImpl(I, *CoverageInfo)) + return true; + + return false; +} + +namespace llvm { +InstructionSelector * +createM68kInstructionSelector(const M68kTargetMachine &TM, + const M68kSubtarget &Subtarget, + const M68kRegisterBankInfo &RBI) { + return new M68kInstructionSelector(TM, Subtarget, RBI); +} +} // end namespace llvm Index: llvm/lib/Target/M68k/GlSel/M68kLegalizerInfo.h =================================================================== --- /dev/null +++ llvm/lib/Target/M68k/GlSel/M68kLegalizerInfo.h @@ -0,0 +1,29 @@ +//===- M68kLegalizerInfo --------------------------------------*- C++ -*-==// +// +// 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 +/// This file declares the targeting of the MachineLegalizer class for +/// M68k. +/// \todo This should be generated by TableGen. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_M68K_GLSEL_M68KLEGALIZERINFO_H +#define LLVM_LIB_TARGET_M68K_GLSEL_M68KLEGALIZERINFO_H + +#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" + +namespace llvm { + +class M68kSubtarget; + +/// This struct provides the information for the target register banks. +struct M68kLegalizerInfo : public LegalizerInfo { +public: + M68kLegalizerInfo(const M68kSubtarget &ST); +}; +} // end namespace llvm +#endif // LLVM_LIB_TARGET_M68K_GLSEL_M68KLEGALIZERINFO_H Index: llvm/lib/Target/M68k/GlSel/M68kLegalizerInfo.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/M68k/GlSel/M68kLegalizerInfo.cpp @@ -0,0 +1,24 @@ +//===-- M68kLegalizerInfo.cpp ----------------------------------*- C++ -*-===// +// +// 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 +/// This file implements the targeting of the Machinelegalizer class for M68k. +//===----------------------------------------------------------------------===// + +#include "M68kLegalizerInfo.h" +#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" +#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" +#include "llvm/CodeGen/TargetOpcodes.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Type.h" + +using namespace llvm; + +M68kLegalizerInfo::M68kLegalizerInfo(const M68kSubtarget &ST) { + getLegacyLegalizerInfo().computeTables(); +} Index: llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.h =================================================================== --- /dev/null +++ llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.h @@ -0,0 +1,39 @@ +//===-- M68kRegisterBankInfo.h ---------------------------------*- C++ -*-===// +// +// 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 +/// This file declares the targeting of the RegisterBankInfo class for M68k. +/// \todo This should be generated by TableGen. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_M68K_GLSEL_M68KREGISTERBANKINFO_H +#define LLVM_LIB_TARGET_M68K_GLSEL_M68KREGISTERBANKINFO_H + +#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" + +#define GET_REGBANK_DECLARATIONS +#include "M68kGenRegisterBank.inc" +#undef GET_REGBANK_DECLARATIONS + +namespace llvm { + +class TargetRegisterInfo; + +class M68kGenRegisterBankInfo : public RegisterBankInfo { +protected: +#define GET_TARGET_REGBANK_CLASS +#include "M68kGenRegisterBank.inc" +#undef GET_TARGET_REGBANK_CLASS +}; + +/// This class provides the information for the target register banks. +class M68kRegisterBankInfo final : public M68kGenRegisterBankInfo { +public: + M68kRegisterBankInfo(const TargetRegisterInfo &TRI); +}; +} // end namespace llvm +#endif Index: llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.cpp @@ -0,0 +1,27 @@ +//===-- M68kRegisterBankInfo.cpp -------------------------------*- C++ -*-===// +// +// 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 +/// This file implements the targeting of the RegisterBankInfo class for M68k. +/// \todo This should be generated by TableGen. +//===----------------------------------------------------------------------===// + +#include "M68kRegisterBankInfo.h" +#include "MCTargetDesc/M68kMCTargetDesc.h" +#include "llvm/CodeGen/GlobalISel/RegisterBank.h" +#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" + +#define GET_TARGET_REGBANK_IMPL +#include "M68kGenRegisterBank.inc" +#undef GET_TARGET_REGBANK_IMPL + +using namespace llvm; + +M68kRegisterBankInfo::M68kRegisterBankInfo(const TargetRegisterInfo &TRI) + : M68kGenRegisterBankInfo() {} Index: llvm/lib/Target/M68k/GlSel/M68kRegisterBanks.td =================================================================== --- /dev/null +++ llvm/lib/Target/M68k/GlSel/M68kRegisterBanks.td @@ -0,0 +1,15 @@ +//===-- M68kRegisterBanks.td - Describe the M68k Banks -------*- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Define the M68k register banks used for GlobalISel. +/// +//===----------------------------------------------------------------------===// + +/// General Purpose Registers. Here we define a register bank with name AnyGPR +def GPRRegBank : RegisterBank<"AnyGPR", [DR8]>; Index: llvm/lib/Target/M68k/M68k.h =================================================================== --- llvm/lib/Target/M68k/M68k.h +++ llvm/lib/Target/M68k/M68k.h @@ -18,6 +18,9 @@ namespace llvm { class FunctionPass; +class InstructionSelector; +class M68kRegisterBankInfo; +class M68kSubtarget; class M68kTargetMachine; /// This pass converts a legalized DAG into a M68k-specific DAG, ready for @@ -45,6 +48,10 @@ /// so that all possible MOVEs are present. FunctionPass *createM68kConvertMOVToMOVMPass(); +InstructionSelector * +createM68kInstructionSelector(const M68kTargetMachine &, const M68kSubtarget &, + const M68kRegisterBankInfo &); + } // namespace llvm #endif Index: llvm/lib/Target/M68k/M68k.td =================================================================== --- llvm/lib/Target/M68k/M68k.td +++ llvm/lib/Target/M68k/M68k.td @@ -78,6 +78,7 @@ //===----------------------------------------------------------------------===// include "M68kRegisterInfo.td" +include "GlSel/M68kRegisterBanks.td" //===----------------------------------------------------------------------===// // Instruction Descriptions Index: llvm/lib/Target/M68k/M68kSubtarget.h =================================================================== --- llvm/lib/Target/M68k/M68kSubtarget.h +++ llvm/lib/Target/M68k/M68kSubtarget.h @@ -19,6 +19,10 @@ #include "M68kInstrInfo.h" #include "llvm/ADT/BitVector.h" +#include "llvm/CodeGen/GlobalISel/CallLowering.h" +#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" +#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" +#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" #include "llvm/CodeGen/SelectionDAGTargetInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/DataLayout.h" @@ -159,6 +163,19 @@ const InstrItineraryData *getInstrItineraryData() const override { return &InstrItins; } + +protected: + // GlobalISel related APIs. + std::unique_ptr CallLoweringInfo; + std::unique_ptr InstSelector; + std::unique_ptr Legalizer; + std::unique_ptr RegBankInfo; + +public: + const CallLowering *getCallLowering() const override; + InstructionSelector *getInstructionSelector() const override; + const LegalizerInfo *getLegalizerInfo() const override; + const RegisterBankInfo *getRegBankInfo() const override; }; } // namespace llvm Index: llvm/lib/Target/M68k/M68kSubtarget.cpp =================================================================== --- llvm/lib/Target/M68k/M68kSubtarget.cpp +++ llvm/lib/Target/M68k/M68kSubtarget.cpp @@ -12,6 +12,9 @@ //===----------------------------------------------------------------------===// #include "M68kSubtarget.h" +#include "GlSel/M68kCallLowering.h" +#include "GlSel/M68kLegalizerInfo.h" +#include "GlSel/M68kRegisterBankInfo.cpp" #include "M68k.h" #include "M68kMachineFunction.h" @@ -51,7 +54,30 @@ UserReservedRegister(M68k::NUM_TARGET_REGS), TM(TM), TSInfo(), InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)), FrameLowering(*this, this->getStackAlignment()), TLInfo(TM, *this), - TargetTriple(TT) {} + TargetTriple(TT) { + CallLoweringInfo.reset(new M68kCallLowering(*getTargetLowering())); + Legalizer.reset(new M68kLegalizerInfo(*this)); + + auto *RBI = new M68kRegisterBankInfo(*getRegisterInfo()); + RegBankInfo.reset(RBI); + InstSelector.reset(createM68kInstructionSelector(&TM, *this, *RBI); +} + +const CallLowering *M68kSubtarget::getCallLowering() const { + return CallLoweringInfo.get(); +} + +InstructionSelector *M68kSubtarget::getInstructionSelector() const { + return InstSelector.get(); +} + +const LegalizerInfo *M68kSubtarget::getLegalizerInfo() const { + return Legalizer.get(); +} + +const RegisterBankInfo *M68kSubtarget::getRegBankInfo() const { + return RegBankInfo.get(); +} bool M68kSubtarget::isPositionIndependent() const { return TM.isPositionIndependent(); Index: llvm/lib/Target/M68k/M68kTargetMachine.cpp =================================================================== --- llvm/lib/Target/M68k/M68kTargetMachine.cpp +++ llvm/lib/Target/M68k/M68kTargetMachine.cpp @@ -13,14 +13,18 @@ #include "M68kTargetMachine.h" #include "M68k.h" -#include "TargetInfo/M68kTargetInfo.h" - #include "M68kSubtarget.h" #include "M68kTargetObjectFile.h" - +#include "TargetInfo/M68kTargetInfo.h" +#include "llvm/CodeGen/GlobalISel/IRTranslator.h" +#include "llvm/CodeGen/GlobalISel/InstructionSelect.h" +#include "llvm/CodeGen/GlobalISel/Legalizer.h" +#include "llvm/CodeGen/GlobalISel/RegBankSelect.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/LegacyPassManager.h" +#include "llvm/InitializePasses.h" +#include "llvm/PassRegistry.h" #include "llvm/Support/TargetRegistry.h" #include @@ -30,6 +34,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kTarget() { RegisterTargetMachine X(getTheM68kTarget()); + auto *PR = PassRegistry::getPassRegistry(); + initializeGlobalISel(*PR); } namespace { @@ -134,7 +140,10 @@ const M68kSubtarget &getM68kSubtarget() const { return *getM68kTargetMachine().getSubtargetImpl(); } - + bool addIRTranslator() override; + bool addLegalizeMachineIR() override; + bool addRegBankSelect() override; + bool addGlobalInstructionSelect() override; bool addInstSelector() override; void addPreSched2() override; void addPreEmitPass() override; @@ -152,6 +161,26 @@ return false; } +bool M68kPassConfig::addIRTranslator() { + addPass(new IRTranslator()); + return false; +} + +bool M68kPassConfig::addLegalizeMachineIR() { + addPass(new Legalizer()); + return false; +} + +bool M68kPassConfig::addRegBankSelect() { + addPass(new RegBankSelect()); + return false; +} + +bool M68kPassConfig::addGlobalInstructionSelect() { + addPass(new InstructionSelect()); + return false; +} + void M68kPassConfig::addPreSched2() { addPass(createM68kExpandPseudoPass()); } void M68kPassConfig::addPreEmitPass() { Index: llvm/test/CodeGen/M68k/GlobalISel/irtranslator-ret.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/M68k/GlobalISel/irtranslator-ret.ll @@ -0,0 +1,7 @@ +; RUN: llc -mtriple=m68k -global-isel -stop-after=irtranslator < %s | FileCheck %s + +; CHECK: name: noArgRetVoid +; CHECK: RTS +define void @noArgRetVoid() { + ret void +}