[MIPS GlobalISel] Add pre legalizer combiner pass

Introduce GlobalISel pre legalizer pass for MIPS.
It will be used to cope with instructions that require
combining before legalization.

Differential Revision: https://reviews.llvm.org/D56269

llvm-svn: 351046
This commit is contained in:
Petar Avramovic 2019-01-14 10:27:05 +00:00
parent 1f73310e1e
commit 7d370a36bb
5 changed files with 138 additions and 0 deletions

View File

@ -44,6 +44,7 @@ add_llvm_target(MipsCodeGen
MipsModuleISelDAGToDAG.cpp
MipsOptimizePICCall.cpp
MipsOs16.cpp
MipsPreLegalizerCombiner.cpp
MipsRegisterBankInfo.cpp
MipsRegisterInfo.cpp
MipsSEFrameLowering.cpp

View File

@ -38,6 +38,7 @@ namespace llvm {
FunctionPass *createMipsConstantIslandPass();
FunctionPass *createMicroMipsSizeReducePass();
FunctionPass *createMipsExpandPseudoPass();
FunctionPass *createMipsPreLegalizeCombiner();
InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &,
MipsSubtarget &,
@ -46,6 +47,7 @@ namespace llvm {
void initializeMipsDelaySlotFillerPass(PassRegistry &);
void initializeMipsBranchExpansionPass(PassRegistry &);
void initializeMicroMipsSizeReducePass(PassRegistry &);
void initializeMipsPreLegalizerCombinerPass(PassRegistry&);
} // end namespace llvm;
#endif

View File

@ -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<TargetPassConfig>();
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<TargetPassConfig>();
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

View File

@ -56,6 +56,7 @@ extern "C" void LLVMInitializeMipsTarget() {
initializeMipsDelaySlotFillerPass(*PR);
initializeMipsBranchExpansionPass(*PR);
initializeMicroMipsSizeReducePass(*PR);
initializeMipsPreLegalizerCombinerPass(*PR);
}
static std::string computeDataLayout(const Triple &TT, StringRef CPU,
@ -235,6 +236,7 @@ public:
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 @@ bool MipsPassConfig::addIRTranslator() {
return false;
}
void MipsPassConfig::addPreLegalizeMachineIR() {
addPass(createMipsPreLegalizeCombiner());
}
bool MipsPassConfig::addLegalizeMachineIR() {
addPass(new Legalizer());
return false;

View File

@ -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
...