From fac93e28f066b6a25b480c0d4334f94473ea1571 Mon Sep 17 00:00:00 2001 From: Petar Jovanovic Date: Fri, 23 Feb 2018 11:06:40 +0000 Subject: [PATCH] [MIPS GlobalISel] Adding GlobalISel Add GlobalISel infrastructure up to the point where we can select a ret void. Patch by Petar Avramovic. Differential Revision: https://reviews.llvm.org/D43583 llvm-svn: 325888 --- llvm/lib/Target/Mips/CMakeLists.txt | 4 ++ llvm/lib/Target/Mips/LLVMBuild.txt | 1 + llvm/lib/Target/Mips/Mips.h | 8 +++ llvm/lib/Target/Mips/MipsCallLowering.cpp | 47 +++++++++++++++ llvm/lib/Target/Mips/MipsCallLowering.h | 40 +++++++++++++ llvm/lib/Target/Mips/MipsInstructionSelector.cpp | 66 ++++++++++++++++++++++ llvm/lib/Target/Mips/MipsLegalizerInfo.cpp | 24 ++++++++ llvm/lib/Target/Mips/MipsLegalizerInfo.h | 29 ++++++++++ llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp | 26 +++++++++ llvm/lib/Target/Mips/MipsRegisterBankInfo.h | 35 ++++++++++++ llvm/lib/Target/Mips/MipsSubtarget.cpp | 27 +++++++++ llvm/lib/Target/Mips/MipsSubtarget.h | 17 ++++++ llvm/lib/Target/Mips/MipsTargetMachine.cpp | 31 ++++++++++ .../CodeGen/Mips/GlobalISel/irtranslator/ret.ll | 11 ++++ llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/ret.ll | 12 ++++ 15 files changed, 378 insertions(+) create mode 100644 llvm/lib/Target/Mips/MipsCallLowering.cpp create mode 100644 llvm/lib/Target/Mips/MipsCallLowering.h create mode 100644 llvm/lib/Target/Mips/MipsInstructionSelector.cpp create mode 100644 llvm/lib/Target/Mips/MipsLegalizerInfo.cpp create mode 100644 llvm/lib/Target/Mips/MipsLegalizerInfo.h create mode 100644 llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp create mode 100644 llvm/lib/Target/Mips/MipsRegisterBankInfo.h create mode 100644 llvm/test/CodeGen/Mips/GlobalISel/irtranslator/ret.ll create mode 100644 llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/ret.ll diff --git a/llvm/lib/Target/Mips/CMakeLists.txt b/llvm/lib/Target/Mips/CMakeLists.txt index 40e337e..f58bb8d 100644 --- a/llvm/lib/Target/Mips/CMakeLists.txt +++ b/llvm/lib/Target/Mips/CMakeLists.txt @@ -23,21 +23,25 @@ add_llvm_target(MipsCodeGen 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 diff --git a/llvm/lib/Target/Mips/LLVMBuild.txt b/llvm/lib/Target/Mips/LLVMBuild.txt index 06af8a1..4b6851f 100644 --- a/llvm/lib/Target/Mips/LLVMBuild.txt +++ b/llvm/lib/Target/Mips/LLVMBuild.txt @@ -43,4 +43,5 @@ required_libraries = SelectionDAG Support Target + GlobalISel add_to_library_groups = Mips diff --git a/llvm/lib/Target/Mips/Mips.h b/llvm/lib/Target/Mips/Mips.h index 008b950..f722388 100644 --- a/llvm/lib/Target/Mips/Mips.h +++ b/llvm/lib/Target/Mips/Mips.h @@ -22,6 +22,10 @@ namespace llvm { class MipsTargetMachine; class ModulePass; class FunctionPass; + class MipsRegisterBankInfo; + class MipsSubtarget; + class MipsTargetMachine; + class InstructionSelector; ModulePass *createMipsOs16Pass(); ModulePass *createMips16HardFloatPass(); @@ -33,6 +37,10 @@ namespace llvm { FunctionPass *createMipsLongBranchPass(); FunctionPass *createMipsConstantIslandPass(); FunctionPass *createMicroMipsSizeReductionPass(); + + InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &, + MipsSubtarget &, + MipsRegisterBankInfo &); } // end namespace llvm; #endif diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp new file mode 100644 index 0000000..55608f4 --- /dev/null +++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp @@ -0,0 +1,47 @@ +//===- MipsCallLowering.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 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; + + // Function had args, but we didn't lower them. + return false; +} diff --git a/llvm/lib/Target/Mips/MipsCallLowering.h b/llvm/lib/Target/Mips/MipsCallLowering.h new file mode 100644 index 0000000..4839b39 --- /dev/null +++ b/llvm/lib/Target/Mips/MipsCallLowering.h @@ -0,0 +1,40 @@ +//===- MipsCallLowering.h ---------------------------------------*- 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 diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp new file mode 100644 index 0000000..c94ccba --- /dev/null +++ b/llvm/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 diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp new file mode 100644 index 0000000..869ac4d --- /dev/null +++ b/llvm/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(); +} diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.h b/llvm/lib/Target/Mips/MipsLegalizerInfo.h new file mode 100644 index 0000000..36dd39c8 --- /dev/null +++ b/llvm/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 diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp new file mode 100644 index 0000000..d148c50 --- /dev/null +++ b/llvm/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() {} diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.h b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h new file mode 100644 index 0000000..b2b07a3 --- /dev/null +++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h @@ -0,0 +1,35 @@ +//===- MipsRegisterBankInfo.h -----------------------------------*- 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 diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp index 2dc70e2..c79a6a4 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.cpp +++ b/llvm/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 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, 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_N64() const { return getABI().IsN64(); } 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(); +} diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h index cab824f..e9f5dee 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.h +++ b/llvm/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 @@ public: 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 diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp index fb79a4b..a66aae6 100644 --- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp +++ b/llvm/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 @@ extern "C" void LLVMInitializeMipsTarget() { 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 @@ public: 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 @@ void MipsPassConfig::addPreEmitPass() { 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; +} diff --git a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/ret.ll b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/ret.ll new file mode 100644 index 0000000..a8e710c --- /dev/null +++ b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/ret.ll @@ -0,0 +1,11 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32 + + +define void @void() { + ; MIPS32-LABEL: name: void + ; MIPS32: bb.1.entry: + ; MIPS32: RetRA +entry: + ret void +} diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/ret.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/ret.ll new file mode 100644 index 0000000..0c89e15 --- /dev/null +++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/ret.ll @@ -0,0 +1,12 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=MIPS32 + +define void @void() { +; MIPS32-LABEL: void: +; MIPS32: # %bb.0: # %entry +; MIPS32-NEXT: jr $ra +; MIPS32-NEXT: nop +entry: + ret void +} + -- 2.7.4