Index: lib/Target/Mips/CMakeLists.txt =================================================================== --- lib/Target/Mips/CMakeLists.txt +++ lib/Target/Mips/CMakeLists.txt @@ -23,21 +23,25 @@ Mips16RegisterInfo.cpp MipsAnalyzeImmediate.cpp MipsAsmPrinter.cpp + MipsCallLowering.cpp MipsCCState.cpp MipsConstantIslandPass.cpp MipsDelaySlotFiller.cpp MipsFastISel.cpp MipsHazardSchedule.cpp MipsInstrInfo.cpp + MipsInstructionSelector.cpp MipsISelDAGToDAG.cpp MipsISelLowering.cpp MipsFrameLowering.cpp + MipsLegalizerInfo.cpp MipsLongBranch.cpp MipsMCInstLower.cpp MipsMachineFunction.cpp MipsModuleISelDAGToDAG.cpp MipsOptimizePICCall.cpp MipsOs16.cpp + MipsRegisterBankInfo.cpp MipsRegisterInfo.cpp MipsSEFrameLowering.cpp MipsSEInstrInfo.cpp Index: lib/Target/Mips/LLVMBuild.txt =================================================================== --- lib/Target/Mips/LLVMBuild.txt +++ lib/Target/Mips/LLVMBuild.txt @@ -43,4 +43,5 @@ SelectionDAG Support Target + GlobalISel add_to_library_groups = Mips Index: lib/Target/Mips/Mips.h =================================================================== --- lib/Target/Mips/Mips.h +++ lib/Target/Mips/Mips.h @@ -22,6 +22,10 @@ class MipsTargetMachine; class ModulePass; class FunctionPass; + class MipsRegisterBankInfo; + class MipsSubtarget; + class MipsTargetMachine; + class InstructionSelector; ModulePass *createMipsOs16Pass(); ModulePass *createMips16HardFloatPass(); @@ -33,6 +37,10 @@ FunctionPass *createMipsLongBranchPass(); FunctionPass *createMipsConstantIslandPass(); FunctionPass *createMicroMipsSizeReductionPass(); + + InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &, + MipsSubtarget &, + MipsRegisterBankInfo &); } // end namespace llvm; #endif Index: lib/Target/Mips/MipsCallLowering.h =================================================================== --- /dev/null +++ lib/Target/Mips/MipsCallLowering.h @@ -0,0 +1,40 @@ +//==- llvm/lib/Target/MIPS/MipsCallLowering.h - Call lowering ----*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// \file +/// This file describes how to lower LLVM calls to machine code calls. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_MIPS_MIPSCALLLOWERING_H +#define LLVM_LIB_TARGET_MIPS_MIPSCALLLOWERING_H + +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/GlobalISel/CallLowering.h" +#include "llvm/CodeGen/ValueTypes.h" + +namespace llvm { + +class MipsTargetLowering; + +class MipsCallLowering : public CallLowering { + +public: + MipsCallLowering(const MipsTargetLowering &TLI); + + bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, + unsigned VReg) const override; + + bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, + ArrayRef VRegs) const override; +}; + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_MIPS_MIPSCALLLOWERING_H Index: lib/Target/Mips/MipsCallLowering.cpp =================================================================== --- /dev/null +++ lib/Target/Mips/MipsCallLowering.cpp @@ -0,0 +1,47 @@ +//===- llvm/lib/Target/MIPS/MIPSCallLowering.cpp - Call lowering-----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// \file +/// This file implements the lowering of LLVM calls to machine code calls for +/// GlobalISel. +// +//===----------------------------------------------------------------------===// + +#include "MipsCallLowering.h" +#include "MipsISelLowering.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" + +using namespace llvm; + +MipsCallLowering::MipsCallLowering(const MipsTargetLowering &TLI) + : CallLowering(&TLI) {} + +bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, + const Value *Val, unsigned VReg) const { + + MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA); + + if (Val != nullptr) { + return false; + } + MIRBuilder.insertInstr(Ret); + return true; +} + +bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, + const Function &F, + ArrayRef VRegs) const { + + // Quick exit if there aren't any args + if (F.arg_empty()) + return true; + + // fail, function had args, but we didn't lower them + return false; +} Index: lib/Target/Mips/MipsInstructionSelector.cpp =================================================================== --- /dev/null +++ lib/Target/Mips/MipsInstructionSelector.cpp @@ -0,0 +1,66 @@ +//===---- MipsInstructionSelector.cpp ----------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file implements the targeting of the InstructionSelector class for +/// Mips. +/// \todo This should be generated by TableGen. +//===----------------------------------------------------------------------===// + +#include "MipsRegisterBankInfo.h" +#include "MipsSubtarget.h" +#include "MipsTargetMachine.h" +#include "llvm/Support/Debug.h" + +using namespace llvm; + +namespace { + +class MipsInstructionSelector : public InstructionSelector { +public: + MipsInstructionSelector(const MipsTargetMachine &TM, const MipsSubtarget &STI, + const MipsRegisterBankInfo &RBI); + + bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override; + +private: + const MipsTargetMachine &TM; + const MipsSubtarget &STI; + const MipsInstrInfo &TII; + const MipsRegisterInfo &TRI; + const MipsRegisterBankInfo &RBI; +}; + +} // end anonymous namespace + +MipsInstructionSelector::MipsInstructionSelector( + const MipsTargetMachine &TM, const MipsSubtarget &STI, + const MipsRegisterBankInfo &RBI) + : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()), + TRI(*STI.getRegisterInfo()), RBI(RBI) {} + +bool MipsInstructionSelector::select(MachineInstr &I, + CodeGenCoverage &CoverageInfo) const { + + if (!isPreISelGenericOpcode(I.getOpcode())) { + // not global isel generic opcode + // TODO: select copy + return true; + } + + // we didn't select anything + return false; +} + +namespace llvm { +InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &TM, + MipsSubtarget &Subtarget, + MipsRegisterBankInfo &RBI) { + return new MipsInstructionSelector(TM, Subtarget, RBI); +} +} // end namespace llvm Index: lib/Target/Mips/MipsLegalizerInfo.h =================================================================== --- /dev/null +++ lib/Target/Mips/MipsLegalizerInfo.h @@ -0,0 +1,29 @@ +//==- MipsLegalizerInfo ------------------------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares the targeting of the Machinelegalizer class for Mips. +/// \todo This should be generated by TableGen. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_MIPS_MIPSMACHINELEGALIZER_H +#define LLVM_LIB_TARGET_MIPS_MIPSMACHINELEGALIZER_H + +#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" + +namespace llvm { + +class MipsSubtarget; + +/// This class provides legalization strategies. +class MipsLegalizerInfo : public LegalizerInfo { +public: + MipsLegalizerInfo(const MipsSubtarget &ST); +}; +} // end namespace llvm +#endif Index: lib/Target/Mips/MipsLegalizerInfo.cpp =================================================================== --- /dev/null +++ lib/Target/Mips/MipsLegalizerInfo.cpp @@ -0,0 +1,24 @@ +//==- MipsLegalizerInfo.cpp --------------------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file implements the targeting of the Machinelegalizer class for Mips. +/// \todo This should be generated by TableGen. +//===----------------------------------------------------------------------===// + +#include "MipsLegalizerInfo.h" +#include "llvm/CodeGen/TargetOpcodes.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Type.h" + +using namespace llvm; + +MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { + computeTables(); +} Index: lib/Target/Mips/MipsRegisterBankInfo.h =================================================================== --- /dev/null +++ lib/Target/Mips/MipsRegisterBankInfo.h @@ -0,0 +1,35 @@ +//==- mipsRegisterBankInfo ---------------------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares the targeting of the RegisterBankInfo class for Mips. +/// \todo This should be generated by TableGen. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_MIPS_MIPSREGISTERBANKINFO_H +#define LLVM_LIB_TARGET_MIPS_MIPSREGISTERBANKINFO_H + +#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" + +namespace llvm { + +class TargetRegisterInfo; + +class MipsGenRegisterBankInfo : public RegisterBankInfo { +// TODO: This should be auto-generated by TableGen +public: + MipsGenRegisterBankInfo(); +}; + +/// This class provides the information for the target register banks. +class MipsRegisterBankInfo final : public MipsGenRegisterBankInfo { +public: + MipsRegisterBankInfo(const TargetRegisterInfo &TRI); +}; +} // end namespace llvm +#endif Index: lib/Target/Mips/MipsRegisterBankInfo.cpp =================================================================== --- /dev/null +++ lib/Target/Mips/MipsRegisterBankInfo.cpp @@ -0,0 +1,26 @@ +//===- MipsRegisterBankInfo.cpp -----------------------------------*- C++-*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file implements the targeting of the RegisterBankInfo class for Mips. +/// \todo This should be generated by TableGen. +//===----------------------------------------------------------------------===// + +#include "MipsRegisterBankInfo.h" +#include "llvm/CodeGen/GlobalISel/RegisterBank.h" +#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" + +using namespace llvm; + +MipsGenRegisterBankInfo::MipsGenRegisterBankInfo() + : RegisterBankInfo(nullptr, 0) {} + +MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI) + : MipsGenRegisterBankInfo() {} Index: lib/Target/Mips/MipsSubtarget.h =================================================================== --- lib/Target/Mips/MipsSubtarget.h +++ lib/Target/Mips/MipsSubtarget.h @@ -20,6 +20,10 @@ #include "MipsInstrInfo.h" #include "llvm/CodeGen/SelectionDAGTargetInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/CodeGen/GlobalISel/CallLowering.h" +#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" +#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" #include "llvm/IR/DataLayout.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/Support/ErrorHandling.h" @@ -349,6 +353,19 @@ const InstrItineraryData *getInstrItineraryData() const override { return &InstrItins; } + +protected: + // GlobalISel related APIs. + std::unique_ptr CallLoweringInfo; + std::unique_ptr Legalizer; + std::unique_ptr RegBankInfo; + std::unique_ptr InstSelector; + +public: + const CallLowering *getCallLowering() const override; + const LegalizerInfo *getLegalizerInfo() const override; + const RegisterBankInfo *getRegBankInfo() const override; + const InstructionSelector *getInstructionSelector() const override; }; } // End llvm namespace Index: lib/Target/Mips/MipsSubtarget.cpp =================================================================== --- lib/Target/Mips/MipsSubtarget.cpp +++ lib/Target/Mips/MipsSubtarget.cpp @@ -16,6 +16,9 @@ #include "MipsMachineFunction.h" #include "MipsRegisterInfo.h" #include "MipsTargetMachine.h" +#include "MipsCallLowering.h" +#include "MipsLegalizerInfo.h" +#include "MipsRegisterBankInfo.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Function.h" #include "llvm/Support/CommandLine.h" @@ -177,6 +180,14 @@ MSAWarningPrinted = true; } } + + CallLoweringInfo.reset(new MipsCallLowering(*getTargetLowering())); + Legalizer.reset(new MipsLegalizerInfo(*this)); + + auto *RBI = new MipsRegisterBankInfo(*getRegisterInfo()); + RegBankInfo.reset(RBI); + InstSelector.reset(createMipsInstructionSelector( + *static_cast(&TM), *this, *RBI)); } bool MipsSubtarget::isPositionIndependent() const { @@ -234,3 +245,19 @@ bool MipsSubtarget::isABI_N32() const { return getABI().IsN32(); } bool MipsSubtarget::isABI_O32() const { return getABI().IsO32(); } const MipsABIInfo &MipsSubtarget::getABI() const { return TM.getABI(); } + +const CallLowering *MipsSubtarget::getCallLowering() const { + return CallLoweringInfo.get(); +} + +const LegalizerInfo *MipsSubtarget::getLegalizerInfo() const { + return Legalizer.get(); +} + +const RegisterBankInfo *MipsSubtarget::getRegBankInfo() const { + return RegBankInfo.get(); +} + +const InstructionSelector *MipsSubtarget::getInstructionSelector() const { + return InstSelector.get(); +} Index: lib/Target/Mips/MipsTargetMachine.cpp =================================================================== --- lib/Target/Mips/MipsTargetMachine.cpp +++ lib/Target/Mips/MipsTargetMachine.cpp @@ -23,6 +23,10 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/CodeGen/GlobalISel/IRTranslator.h" +#include "llvm/CodeGen/GlobalISel/Legalizer.h" +#include "llvm/CodeGen/GlobalISel/RegBankSelect.h" +#include "llvm/CodeGen/GlobalISel/InstructionSelect.h" #include "llvm/CodeGen/BasicTTIImpl.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/Passes.h" @@ -46,6 +50,9 @@ RegisterTargetMachine Y(getTheMipselTarget()); RegisterTargetMachine A(getTheMips64Target()); RegisterTargetMachine B(getTheMips64elTarget()); + + PassRegistry *PR = PassRegistry::getPassRegistry(); + initializeGlobalISel(*PR); } static std::string computeDataLayout(const Triple &TT, StringRef CPU, @@ -230,6 +237,10 @@ bool addInstSelector() override; void addPreEmitPass() override; void addPreRegAlloc() override; + bool addIRTranslator() override; + bool addLegalizeMachineIR() override; + bool addRegBankSelect() override; + bool addGlobalInstructionSelect() override; }; } // end anonymous namespace @@ -285,3 +296,23 @@ addPass(createMipsHazardSchedule()); addPass(createMipsConstantIslandPass()); } + +bool MipsPassConfig::addIRTranslator() { + addPass(new IRTranslator()); + return false; +} + +bool MipsPassConfig::addLegalizeMachineIR() { + addPass(new Legalizer()); + return false; +} + +bool MipsPassConfig::addRegBankSelect() { + addPass(new RegBankSelect()); + return false; +} + +bool MipsPassConfig::addGlobalInstructionSelect() { + addPass(new InstructionSelect()); + return false; +} Index: test/CodeGen/Mips/GlobalISel/mips-irtranslator.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/GlobalISel/mips-irtranslator.ll @@ -0,0 +1,9 @@ +; RUN: llc -march=mipsel -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s + + +define void @test_void_return() { +; CHECK-LABEL: name: test_void_return +; CHECK: RetRA +entry: + ret void +} Index: test/CodeGen/Mips/GlobalISel/mips-isel.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/GlobalISel/mips-isel.ll @@ -0,0 +1,8 @@ +; RUN: llc -march=mipsel -global-isel -verify-machineinstrs %s -o - | FileCheck %s + +define void @test_void_return() { +; CHECK-LABEL: test_void_return: +; CHECK: jr $ra +entry: + ret void +}