Index: lib/Target/Mips/CMakeLists.txt =================================================================== --- lib/Target/Mips/CMakeLists.txt +++ lib/Target/Mips/CMakeLists.txt @@ -44,6 +44,7 @@ MipsModuleISelDAGToDAG.cpp MipsOptimizePICCall.cpp MipsOs16.cpp + MipsPreLegalizerCombiner.cpp MipsRegisterBankInfo.cpp MipsRegisterInfo.cpp MipsSEFrameLowering.cpp Index: lib/Target/Mips/Mips.h =================================================================== --- lib/Target/Mips/Mips.h +++ lib/Target/Mips/Mips.h @@ -38,6 +38,7 @@ FunctionPass *createMipsConstantIslandPass(); FunctionPass *createMicroMipsSizeReducePass(); FunctionPass *createMipsExpandPseudoPass(); + FunctionPass *createMipsPreLegalizeCombiner(); InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &, MipsSubtarget &, @@ -46,6 +47,7 @@ void initializeMipsDelaySlotFillerPass(PassRegistry &); void initializeMipsBranchExpansionPass(PassRegistry &); void initializeMicroMipsSizeReducePass(PassRegistry &); + void initializeMipsPreLegalizerCombinerPass(PassRegistry&); } // end namespace llvm; #endif Index: lib/Target/Mips/MipsPreLegalizerCombiner.cpp =================================================================== --- /dev/null +++ lib/Target/Mips/MipsPreLegalizerCombiner.cpp @@ -0,0 +1,92 @@ +//=== lib/CodeGen/GlobalISel/MipsPreLegalizerCombiner.cpp --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass does combining of machine instructions at the generic MI level, +// before the legalizer. +// +//===----------------------------------------------------------------------===// + +#include "MipsTargetMachine.h" +#include "llvm/CodeGen/GlobalISel/Combiner.h" +#include "llvm/CodeGen/GlobalISel/CombinerInfo.h" +#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" +#include "llvm/CodeGen/TargetPassConfig.h" + +#define DEBUG_TYPE "mips-prelegalizer-combiner" + +using namespace llvm; + +namespace { +class MipsPreLegalizerCombinerInfo : public CombinerInfo { +public: + MipsPreLegalizerCombinerInfo() + : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, + /*LegalizerInfo*/ nullptr) {} + virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI, + MachineIRBuilder &B) const override; +}; + +bool MipsPreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, + MachineInstr &MI, + MachineIRBuilder &B) const { + return false; +} + +// Pass boilerplate +// ================ + +class MipsPreLegalizerCombiner : public MachineFunctionPass { +public: + static char ID; + + MipsPreLegalizerCombiner(); + + StringRef getPassName() const override { return "MipsPreLegalizerCombiner"; } + + bool runOnMachineFunction(MachineFunction &MF) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; +} // end anonymous namespace + +void MipsPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesCFG(); + getSelectionDAGFallbackAnalysisUsage(AU); + MachineFunctionPass::getAnalysisUsage(AU); +} + +MipsPreLegalizerCombiner::MipsPreLegalizerCombiner() : MachineFunctionPass(ID) { + initializeMipsPreLegalizerCombinerPass(*PassRegistry::getPassRegistry()); +} + +bool MipsPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { + if (MF.getProperties().hasProperty( + MachineFunctionProperties::Property::FailedISel)) + return false; + auto *TPC = &getAnalysis(); + MipsPreLegalizerCombinerInfo PCInfo; + Combiner C(PCInfo, TPC); + return C.combineMachineInstrs(MF); +} + +char MipsPreLegalizerCombiner::ID = 0; +INITIALIZE_PASS_BEGIN(MipsPreLegalizerCombiner, DEBUG_TYPE, + "Combine Mips machine instrs before legalization", false, + false) +INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) +INITIALIZE_PASS_END(MipsPreLegalizerCombiner, DEBUG_TYPE, + "Combine Mips machine instrs before legalization", false, + false) + +namespace llvm { +FunctionPass *createMipsPreLegalizeCombiner() { + return new MipsPreLegalizerCombiner(); +} +} // end namespace llvm Index: lib/Target/Mips/MipsTargetMachine.cpp =================================================================== --- lib/Target/Mips/MipsTargetMachine.cpp +++ lib/Target/Mips/MipsTargetMachine.cpp @@ -56,6 +56,7 @@ initializeMipsDelaySlotFillerPass(*PR); initializeMipsBranchExpansionPass(*PR); initializeMicroMipsSizeReducePass(*PR); + initializeMipsPreLegalizerCombinerPass(*PR); } static std::string computeDataLayout(const Triple &TT, StringRef CPU, @@ -235,6 +236,7 @@ void addPreEmitPass() override; void addPreRegAlloc() override; bool addIRTranslator() override; + void addPreLegalizeMachineIR() override; bool addLegalizeMachineIR() override; bool addRegBankSelect() override; bool addGlobalInstructionSelect() override; @@ -312,6 +314,10 @@ return false; } +void MipsPassConfig::addPreLegalizeMachineIR() { + addPass(createMipsPreLegalizeCombiner()); +} + bool MipsPassConfig::addLegalizeMachineIR() { addPass(new Legalizer()); return false; Index: test/CodeGen/Mips/GlobalISel/mips-prelegalizer-combiner/tryCombine.mir =================================================================== --- /dev/null +++ test/CodeGen/Mips/GlobalISel/mips-prelegalizer-combiner/tryCombine.mir @@ -0,0 +1,37 @@ +# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=mips-prelegalizer-combiner -verify-machineinstrs -debug %s -o - 2>&1 | FileCheck %s -check-prefixes=MIPS32 +--- | + + define void @f() {entry: ret void} + +... +--- +# Check that we report attempts to combine each instruction from the input +# since none of them gets changed in this test. + +# MIPS32-LABEL: Generic MI Combiner for: f +# MIPS32: Try combining %0:_(s32) = COPY $a0 +# MIPS32: Try combining %1:_(s32) = COPY $a1 +# MIPS32: Try combining %2:_(s32) = G_ADD %1:_, %0:_ +# MIPS32: Try combining $v0 = COPY %2:_(s32) +# MIPS32: Try combining RetRA implicit $v0 +name: f +alignment: 2 +tracksRegLiveness: true +body: | + bb.1.entry: + liveins: $a0, $a1 + + ; MIPS32-LABEL: name: f + ; MIPS32: liveins: $a0, $a1 + ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1 + ; MIPS32: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY1]], [[COPY]] + ; MIPS32: $v0 = COPY [[ADD]](s32) + ; MIPS32: RetRA implicit $v0 + %0:_(s32) = COPY $a0 + %1:_(s32) = COPY $a1 + %2:_(s32) = G_ADD %1, %0 + $v0 = COPY %2(s32) + RetRA implicit $v0 + +...