17d370a36SPetar Avramovic //=== lib/CodeGen/GlobalISel/MipsPreLegalizerCombiner.cpp --------------===//
27d370a36SPetar Avramovic //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67d370a36SPetar Avramovic //
77d370a36SPetar Avramovic //===----------------------------------------------------------------------===//
87d370a36SPetar Avramovic //
97d370a36SPetar Avramovic // This pass does combining of machine instructions at the generic MI level,
107d370a36SPetar Avramovic // before the legalizer.
117d370a36SPetar Avramovic //
127d370a36SPetar Avramovic //===----------------------------------------------------------------------===//
137d370a36SPetar Avramovic
147d370a36SPetar Avramovic #include "MipsTargetMachine.h"
157d370a36SPetar Avramovic #include "llvm/CodeGen/GlobalISel/Combiner.h"
16b5a939d2SPetar Avramovic #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
177d370a36SPetar Avramovic #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
187d370a36SPetar Avramovic #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
19ed98c1b3Sserge-sans-paille #include "llvm/CodeGen/MachineFunctionPass.h"
207d370a36SPetar Avramovic #include "llvm/CodeGen/TargetPassConfig.h"
2105da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
227d370a36SPetar Avramovic
237d370a36SPetar Avramovic #define DEBUG_TYPE "mips-prelegalizer-combiner"
247d370a36SPetar Avramovic
257d370a36SPetar Avramovic using namespace llvm;
267d370a36SPetar Avramovic
277d370a36SPetar Avramovic namespace {
287d370a36SPetar Avramovic class MipsPreLegalizerCombinerInfo : public CombinerInfo {
297d370a36SPetar Avramovic public:
MipsPreLegalizerCombinerInfo()307d370a36SPetar Avramovic MipsPreLegalizerCombinerInfo()
317d370a36SPetar Avramovic : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
3213af1ed8SAmara Emerson /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
3313af1ed8SAmara Emerson /*EnableOptSize*/ false, /*EnableMinSize*/ false) {}
34*3f3930a4SKazu Hirata bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
357d370a36SPetar Avramovic MachineIRBuilder &B) const override;
367d370a36SPetar Avramovic };
377d370a36SPetar Avramovic
combine(GISelChangeObserver & Observer,MachineInstr & MI,MachineIRBuilder & B) const387d370a36SPetar Avramovic bool MipsPreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
397d370a36SPetar Avramovic MachineInstr &MI,
407d370a36SPetar Avramovic MachineIRBuilder &B) const {
41b5a939d2SPetar Avramovic CombinerHelper Helper(Observer, B);
42b5a939d2SPetar Avramovic
43b5a939d2SPetar Avramovic switch (MI.getOpcode()) {
44b5a939d2SPetar Avramovic default:
45b5a939d2SPetar Avramovic return false;
46a6428724SJon Roelofs case TargetOpcode::G_MEMCPY_INLINE:
47a6428724SJon Roelofs return Helper.tryEmitMemcpyInline(MI);
48b5a939d2SPetar Avramovic case TargetOpcode::G_LOAD:
49b5a939d2SPetar Avramovic case TargetOpcode::G_SEXTLOAD:
505e32e798SPetar Avramovic case TargetOpcode::G_ZEXTLOAD: {
515e32e798SPetar Avramovic // Don't attempt to combine non power of 2 loads or unaligned loads when
525e32e798SPetar Avramovic // subtarget doesn't support them.
535e32e798SPetar Avramovic auto MMO = *MI.memoperands_begin();
54ad73ce31SZongwei Lan const MipsSubtarget &STI = MI.getMF()->getSubtarget<MipsSubtarget>();
555e32e798SPetar Avramovic if (!isPowerOf2_64(MMO->getSize()))
565e32e798SPetar Avramovic return false;
5774eac903SGuillaume Chatelet bool isUnaligned = MMO->getAlign() < MMO->getSize();
585e32e798SPetar Avramovic if (!STI.systemSupportsUnalignedAccess() && isUnaligned)
595e32e798SPetar Avramovic return false;
605e32e798SPetar Avramovic
61b5a939d2SPetar Avramovic return Helper.tryCombineExtendingLoads(MI);
62b5a939d2SPetar Avramovic }
635e32e798SPetar Avramovic }
645e32e798SPetar Avramovic
657d370a36SPetar Avramovic return false;
667d370a36SPetar Avramovic }
677d370a36SPetar Avramovic
687d370a36SPetar Avramovic // Pass boilerplate
697d370a36SPetar Avramovic // ================
707d370a36SPetar Avramovic
717d370a36SPetar Avramovic class MipsPreLegalizerCombiner : public MachineFunctionPass {
727d370a36SPetar Avramovic public:
737d370a36SPetar Avramovic static char ID;
747d370a36SPetar Avramovic
757d370a36SPetar Avramovic MipsPreLegalizerCombiner();
767d370a36SPetar Avramovic
getPassName() const777d370a36SPetar Avramovic StringRef getPassName() const override { return "MipsPreLegalizerCombiner"; }
787d370a36SPetar Avramovic
797d370a36SPetar Avramovic bool runOnMachineFunction(MachineFunction &MF) override;
807d370a36SPetar Avramovic
817d370a36SPetar Avramovic void getAnalysisUsage(AnalysisUsage &AU) const override;
827d370a36SPetar Avramovic };
837d370a36SPetar Avramovic } // end anonymous namespace
847d370a36SPetar Avramovic
getAnalysisUsage(AnalysisUsage & AU) const857d370a36SPetar Avramovic void MipsPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
867d370a36SPetar Avramovic AU.addRequired<TargetPassConfig>();
877d370a36SPetar Avramovic AU.setPreservesCFG();
887d370a36SPetar Avramovic getSelectionDAGFallbackAnalysisUsage(AU);
897d370a36SPetar Avramovic MachineFunctionPass::getAnalysisUsage(AU);
907d370a36SPetar Avramovic }
917d370a36SPetar Avramovic
MipsPreLegalizerCombiner()927d370a36SPetar Avramovic MipsPreLegalizerCombiner::MipsPreLegalizerCombiner() : MachineFunctionPass(ID) {
937d370a36SPetar Avramovic initializeMipsPreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
947d370a36SPetar Avramovic }
957d370a36SPetar Avramovic
runOnMachineFunction(MachineFunction & MF)967d370a36SPetar Avramovic bool MipsPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
977d370a36SPetar Avramovic if (MF.getProperties().hasProperty(
987d370a36SPetar Avramovic MachineFunctionProperties::Property::FailedISel))
997d370a36SPetar Avramovic return false;
1007d370a36SPetar Avramovic auto *TPC = &getAnalysis<TargetPassConfig>();
1017d370a36SPetar Avramovic MipsPreLegalizerCombinerInfo PCInfo;
1027d370a36SPetar Avramovic Combiner C(PCInfo, TPC);
103500e3eadSAditya Nandakumar return C.combineMachineInstrs(MF, nullptr);
1047d370a36SPetar Avramovic }
1057d370a36SPetar Avramovic
1067d370a36SPetar Avramovic char MipsPreLegalizerCombiner::ID = 0;
1077d370a36SPetar Avramovic INITIALIZE_PASS_BEGIN(MipsPreLegalizerCombiner, DEBUG_TYPE,
1087d370a36SPetar Avramovic "Combine Mips machine instrs before legalization", false,
1097d370a36SPetar Avramovic false)
1107d370a36SPetar Avramovic INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
1117d370a36SPetar Avramovic INITIALIZE_PASS_END(MipsPreLegalizerCombiner, DEBUG_TYPE,
1127d370a36SPetar Avramovic "Combine Mips machine instrs before legalization", false,
1137d370a36SPetar Avramovic false)
1147d370a36SPetar Avramovic
1157d370a36SPetar Avramovic namespace llvm {
createMipsPreLegalizeCombiner()1167d370a36SPetar Avramovic FunctionPass *createMipsPreLegalizeCombiner() {
1177d370a36SPetar Avramovic return new MipsPreLegalizerCombiner();
1187d370a36SPetar Avramovic }
1197d370a36SPetar Avramovic } // end namespace llvm
120