llvm-project/llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp
Amara Emerson 3daf7ddaef [GlobalISel] Allow prelegalizer combiners to have access to LegalizerInfo.
Before, the isPreLegalize() query in CombinerHelper only checked for the
presence of a LegalizerInfo object. This is problematic when we want to have
a combine actually check for legality in a pre-legalizer combine pass, since
if we pass a LegalizerInfo object to the constructor it causes the combines to
think that we're running *post* legalizer, which isn't true.

This change fixes it to instead check an explicit bool that passes to signal
whether the pass will be run before or after legalization.

Doing so exposed a bug in the extending loads combine, which tried to check for
legality of candidate extending loads if LegalizerInfo was present. Since we
only ran it pre-legalizer and therefore with a null LegalizerInfo, it never
actually ran. Also fixes the legality checks to keep the tests passing.

Differential Revision: https://reviews.llvm.org/D135044
2022-10-03 07:36:18 +01:00

120 lines
4.0 KiB
C++

//=== lib/CodeGen/GlobalISel/MipsPreLegalizerCombiner.cpp --------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// 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/CombinerHelper.h"
#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/InitializePasses.h"
#define DEBUG_TYPE "mips-prelegalizer-combiner"
using namespace llvm;
namespace {
class MipsPreLegalizerCombinerInfo : public CombinerInfo {
public:
MipsPreLegalizerCombinerInfo()
: CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
/*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
/*EnableOptSize*/ false, /*EnableMinSize*/ false) {}
bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
MachineIRBuilder &B) const override;
};
bool MipsPreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
MachineInstr &MI,
MachineIRBuilder &B) const {
CombinerHelper Helper(Observer, B, /*IsPreLegalize*/ true);
switch (MI.getOpcode()) {
default:
return false;
case TargetOpcode::G_MEMCPY_INLINE:
return Helper.tryEmitMemcpyInline(MI);
case TargetOpcode::G_LOAD:
case TargetOpcode::G_SEXTLOAD:
case TargetOpcode::G_ZEXTLOAD: {
// Don't attempt to combine non power of 2 loads or unaligned loads when
// subtarget doesn't support them.
auto MMO = *MI.memoperands_begin();
const MipsSubtarget &STI = MI.getMF()->getSubtarget<MipsSubtarget>();
if (!isPowerOf2_64(MMO->getSize()))
return false;
bool isUnaligned = MMO->getAlign() < MMO->getSize();
if (!STI.systemSupportsUnalignedAccess() && isUnaligned)
return false;
return Helper.tryCombineExtendingLoads(MI);
}
}
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, nullptr);
}
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