aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp
diff options
context:
space:
mode:
authororivej <orivej@yandex-team.ru>2022-02-10 16:45:01 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:01 +0300
commit2d37894b1b037cf24231090eda8589bbb44fb6fc (patch)
treebe835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp
parent718c552901d703c502ccbefdfc3c9028d608b947 (diff)
downloadydb-2d37894b1b037cf24231090eda8589bbb44fb6fc.tar.gz
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp')
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp786
1 files changed, 393 insertions, 393 deletions
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp
index 490b7b2c0f..5ba9367cac 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp
@@ -1,394 +1,394 @@
-//===-- llvm/CodeGen/GlobalISel/Legalizer.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
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file This file implements the LegalizerHelper class to legalize individual
-/// instructions and the LegalizePass wrapper pass for the primary
-/// legalization.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/GlobalISel/Legalizer.h"
-#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
-#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
-#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
-#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
-#include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h"
-#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
-#include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h"
-#include "llvm/CodeGen/GlobalISel/Utils.h"
-#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/TargetPassConfig.h"
-#include "llvm/CodeGen/TargetSubtargetInfo.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Target/TargetMachine.h"
-
-#include <iterator>
-
-#define DEBUG_TYPE "legalizer"
-
-using namespace llvm;
-
-static cl::opt<bool>
- EnableCSEInLegalizer("enable-cse-in-legalizer",
- cl::desc("Should enable CSE in Legalizer"),
- cl::Optional, cl::init(false));
-
-enum class DebugLocVerifyLevel {
- None,
- Legalizations,
- LegalizationsAndArtifactCombiners,
-};
-#ifndef NDEBUG
-static cl::opt<DebugLocVerifyLevel> VerifyDebugLocs(
- "verify-legalizer-debug-locs",
- cl::desc("Verify that debug locations are handled"),
- cl::values(
- clEnumValN(DebugLocVerifyLevel::None, "none", "No verification"),
- clEnumValN(DebugLocVerifyLevel::Legalizations, "legalizations",
- "Verify legalizations"),
- clEnumValN(DebugLocVerifyLevel::LegalizationsAndArtifactCombiners,
- "legalizations+artifactcombiners",
- "Verify legalizations and artifact combines")),
- cl::init(DebugLocVerifyLevel::Legalizations));
-#else
-// Always disable it for release builds by preventing the observer from being
-// installed.
-static const DebugLocVerifyLevel VerifyDebugLocs = DebugLocVerifyLevel::None;
-#endif
-
-char Legalizer::ID = 0;
-INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,
- "Legalize the Machine IR a function's Machine IR", false,
- false)
-INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
-INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
-INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
- "Legalize the Machine IR a function's Machine IR", false,
- false)
-
-Legalizer::Legalizer() : MachineFunctionPass(ID) { }
-
-void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<TargetPassConfig>();
- AU.addRequired<GISelCSEAnalysisWrapperPass>();
- AU.addPreserved<GISelCSEAnalysisWrapperPass>();
- getSelectionDAGFallbackAnalysisUsage(AU);
- MachineFunctionPass::getAnalysisUsage(AU);
-}
-
-void Legalizer::init(MachineFunction &MF) {
-}
-
-static bool isArtifact(const MachineInstr &MI) {
- switch (MI.getOpcode()) {
- default:
- return false;
- case TargetOpcode::G_TRUNC:
- case TargetOpcode::G_ZEXT:
- case TargetOpcode::G_ANYEXT:
- case TargetOpcode::G_SEXT:
- case TargetOpcode::G_MERGE_VALUES:
- case TargetOpcode::G_UNMERGE_VALUES:
- case TargetOpcode::G_CONCAT_VECTORS:
- case TargetOpcode::G_BUILD_VECTOR:
- case TargetOpcode::G_EXTRACT:
- return true;
- }
-}
-using InstListTy = GISelWorkList<256>;
-using ArtifactListTy = GISelWorkList<128>;
-
-namespace {
-class LegalizerWorkListManager : public GISelChangeObserver {
- InstListTy &InstList;
- ArtifactListTy &ArtifactList;
-#ifndef NDEBUG
- SmallVector<MachineInstr *, 4> NewMIs;
-#endif
-
-public:
- LegalizerWorkListManager(InstListTy &Insts, ArtifactListTy &Arts)
- : InstList(Insts), ArtifactList(Arts) {}
-
- void createdOrChangedInstr(MachineInstr &MI) {
- // Only legalize pre-isel generic instructions.
- // Legalization process could generate Target specific pseudo
- // instructions with generic types. Don't record them
- if (isPreISelGenericOpcode(MI.getOpcode())) {
- if (isArtifact(MI))
- ArtifactList.insert(&MI);
- else
- InstList.insert(&MI);
- }
- }
-
- void createdInstr(MachineInstr &MI) override {
- LLVM_DEBUG(NewMIs.push_back(&MI));
- createdOrChangedInstr(MI);
- }
-
- void printNewInstrs() {
- LLVM_DEBUG({
- for (const auto *MI : NewMIs)
- dbgs() << ".. .. New MI: " << *MI;
- NewMIs.clear();
- });
- }
-
- void erasingInstr(MachineInstr &MI) override {
- LLVM_DEBUG(dbgs() << ".. .. Erasing: " << MI);
- InstList.remove(&MI);
- ArtifactList.remove(&MI);
- }
-
- void changingInstr(MachineInstr &MI) override {
- LLVM_DEBUG(dbgs() << ".. .. Changing MI: " << MI);
- }
-
- void changedInstr(MachineInstr &MI) override {
- // When insts change, we want to revisit them to legalize them again.
- // We'll consider them the same as created.
- LLVM_DEBUG(dbgs() << ".. .. Changed MI: " << MI);
- createdOrChangedInstr(MI);
- }
-};
-} // namespace
-
-Legalizer::MFResult
-Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
- ArrayRef<GISelChangeObserver *> AuxObservers,
- LostDebugLocObserver &LocObserver,
- MachineIRBuilder &MIRBuilder) {
- MIRBuilder.setMF(MF);
- MachineRegisterInfo &MRI = MF.getRegInfo();
-
- // Populate worklists.
- InstListTy InstList;
- ArtifactListTy ArtifactList;
- ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
- // Perform legalization bottom up so we can DCE as we legalize.
- // Traverse BB in RPOT and within each basic block, add insts top down,
- // so when we pop_back_val in the legalization process, we traverse bottom-up.
- for (auto *MBB : RPOT) {
- if (MBB->empty())
- continue;
- for (MachineInstr &MI : *MBB) {
- // Only legalize pre-isel generic instructions: others don't have types
- // and are assumed to be legal.
- if (!isPreISelGenericOpcode(MI.getOpcode()))
- continue;
- if (isArtifact(MI))
- ArtifactList.deferred_insert(&MI);
- else
- InstList.deferred_insert(&MI);
- }
- }
- ArtifactList.finalize();
- InstList.finalize();
-
- // This observer keeps the worklists updated.
- LegalizerWorkListManager WorkListObserver(InstList, ArtifactList);
- // We want both WorkListObserver as well as all the auxiliary observers (e.g.
- // CSEInfo) to observe all changes. Use the wrapper observer.
- GISelObserverWrapper WrapperObserver(&WorkListObserver);
- for (GISelChangeObserver *Observer : AuxObservers)
- WrapperObserver.addObserver(Observer);
-
- // Now install the observer as the delegate to MF.
- // This will keep all the observers notified about new insertions/deletions.
- RAIIMFObsDelInstaller Installer(MF, WrapperObserver);
- LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder);
- LegalizationArtifactCombiner ArtCombiner(MIRBuilder, MRI, LI);
- auto RemoveDeadInstFromLists = [&WrapperObserver](MachineInstr *DeadMI) {
- WrapperObserver.erasingInstr(*DeadMI);
- };
- bool Changed = false;
- SmallVector<MachineInstr *, 128> RetryList;
- do {
- LLVM_DEBUG(dbgs() << "=== New Iteration ===\n");
- assert(RetryList.empty() && "Expected no instructions in RetryList");
- unsigned NumArtifacts = ArtifactList.size();
- while (!InstList.empty()) {
- MachineInstr &MI = *InstList.pop_back_val();
- assert(isPreISelGenericOpcode(MI.getOpcode()) &&
- "Expecting generic opcode");
- if (isTriviallyDead(MI, MRI)) {
- LLVM_DEBUG(dbgs() << MI << "Is dead; erasing.\n");
- MI.eraseFromParentAndMarkDBGValuesForRemoval();
- LocObserver.checkpoint(false);
- continue;
- }
-
- // Do the legalization for this instruction.
- auto Res = Helper.legalizeInstrStep(MI);
- // Error out if we couldn't legalize this instruction. We may want to
- // fall back to DAG ISel instead in the future.
- if (Res == LegalizerHelper::UnableToLegalize) {
- // Move illegal artifacts to RetryList instead of aborting because
- // legalizing InstList may generate artifacts that allow
- // ArtifactCombiner to combine away them.
- if (isArtifact(MI)) {
- LLVM_DEBUG(dbgs() << ".. Not legalized, moving to artifacts retry\n");
- assert(NumArtifacts == 0 &&
- "Artifacts are only expected in instruction list starting the "
- "second iteration, but each iteration starting second must "
- "start with an empty artifacts list");
- (void)NumArtifacts;
- RetryList.push_back(&MI);
- continue;
- }
- Helper.MIRBuilder.stopObservingChanges();
- return {Changed, &MI};
- }
- WorkListObserver.printNewInstrs();
- LocObserver.checkpoint();
- Changed |= Res == LegalizerHelper::Legalized;
- }
- // Try to combine the instructions in RetryList again if there
- // are new artifacts. If not, stop legalizing.
- if (!RetryList.empty()) {
- if (!ArtifactList.empty()) {
- while (!RetryList.empty())
- ArtifactList.insert(RetryList.pop_back_val());
- } else {
- LLVM_DEBUG(dbgs() << "No new artifacts created, not retrying!\n");
- Helper.MIRBuilder.stopObservingChanges();
- return {Changed, RetryList.front()};
- }
- }
- LocObserver.checkpoint();
- while (!ArtifactList.empty()) {
- MachineInstr &MI = *ArtifactList.pop_back_val();
- assert(isPreISelGenericOpcode(MI.getOpcode()) &&
- "Expecting generic opcode");
- if (isTriviallyDead(MI, MRI)) {
- LLVM_DEBUG(dbgs() << MI << "Is dead\n");
- RemoveDeadInstFromLists(&MI);
- MI.eraseFromParentAndMarkDBGValuesForRemoval();
- LocObserver.checkpoint(false);
- continue;
- }
- SmallVector<MachineInstr *, 4> DeadInstructions;
- LLVM_DEBUG(dbgs() << "Trying to combine: " << MI);
- if (ArtCombiner.tryCombineInstruction(MI, DeadInstructions,
- WrapperObserver)) {
- WorkListObserver.printNewInstrs();
- for (auto *DeadMI : DeadInstructions) {
+//===-- llvm/CodeGen/GlobalISel/Legalizer.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
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This file implements the LegalizerHelper class to legalize individual
+/// instructions and the LegalizePass wrapper pass for the primary
+/// legalization.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/GlobalISel/Legalizer.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
+#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
+#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
+#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
+#include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
+#include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h"
+#include "llvm/CodeGen/GlobalISel/Utils.h"
+#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Target/TargetMachine.h"
+
+#include <iterator>
+
+#define DEBUG_TYPE "legalizer"
+
+using namespace llvm;
+
+static cl::opt<bool>
+ EnableCSEInLegalizer("enable-cse-in-legalizer",
+ cl::desc("Should enable CSE in Legalizer"),
+ cl::Optional, cl::init(false));
+
+enum class DebugLocVerifyLevel {
+ None,
+ Legalizations,
+ LegalizationsAndArtifactCombiners,
+};
+#ifndef NDEBUG
+static cl::opt<DebugLocVerifyLevel> VerifyDebugLocs(
+ "verify-legalizer-debug-locs",
+ cl::desc("Verify that debug locations are handled"),
+ cl::values(
+ clEnumValN(DebugLocVerifyLevel::None, "none", "No verification"),
+ clEnumValN(DebugLocVerifyLevel::Legalizations, "legalizations",
+ "Verify legalizations"),
+ clEnumValN(DebugLocVerifyLevel::LegalizationsAndArtifactCombiners,
+ "legalizations+artifactcombiners",
+ "Verify legalizations and artifact combines")),
+ cl::init(DebugLocVerifyLevel::Legalizations));
+#else
+// Always disable it for release builds by preventing the observer from being
+// installed.
+static const DebugLocVerifyLevel VerifyDebugLocs = DebugLocVerifyLevel::None;
+#endif
+
+char Legalizer::ID = 0;
+INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,
+ "Legalize the Machine IR a function's Machine IR", false,
+ false)
+INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
+INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
+INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
+ "Legalize the Machine IR a function's Machine IR", false,
+ false)
+
+Legalizer::Legalizer() : MachineFunctionPass(ID) { }
+
+void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetPassConfig>();
+ AU.addRequired<GISelCSEAnalysisWrapperPass>();
+ AU.addPreserved<GISelCSEAnalysisWrapperPass>();
+ getSelectionDAGFallbackAnalysisUsage(AU);
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+void Legalizer::init(MachineFunction &MF) {
+}
+
+static bool isArtifact(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ default:
+ return false;
+ case TargetOpcode::G_TRUNC:
+ case TargetOpcode::G_ZEXT:
+ case TargetOpcode::G_ANYEXT:
+ case TargetOpcode::G_SEXT:
+ case TargetOpcode::G_MERGE_VALUES:
+ case TargetOpcode::G_UNMERGE_VALUES:
+ case TargetOpcode::G_CONCAT_VECTORS:
+ case TargetOpcode::G_BUILD_VECTOR:
+ case TargetOpcode::G_EXTRACT:
+ return true;
+ }
+}
+using InstListTy = GISelWorkList<256>;
+using ArtifactListTy = GISelWorkList<128>;
+
+namespace {
+class LegalizerWorkListManager : public GISelChangeObserver {
+ InstListTy &InstList;
+ ArtifactListTy &ArtifactList;
+#ifndef NDEBUG
+ SmallVector<MachineInstr *, 4> NewMIs;
+#endif
+
+public:
+ LegalizerWorkListManager(InstListTy &Insts, ArtifactListTy &Arts)
+ : InstList(Insts), ArtifactList(Arts) {}
+
+ void createdOrChangedInstr(MachineInstr &MI) {
+ // Only legalize pre-isel generic instructions.
+ // Legalization process could generate Target specific pseudo
+ // instructions with generic types. Don't record them
+ if (isPreISelGenericOpcode(MI.getOpcode())) {
+ if (isArtifact(MI))
+ ArtifactList.insert(&MI);
+ else
+ InstList.insert(&MI);
+ }
+ }
+
+ void createdInstr(MachineInstr &MI) override {
+ LLVM_DEBUG(NewMIs.push_back(&MI));
+ createdOrChangedInstr(MI);
+ }
+
+ void printNewInstrs() {
+ LLVM_DEBUG({
+ for (const auto *MI : NewMIs)
+ dbgs() << ".. .. New MI: " << *MI;
+ NewMIs.clear();
+ });
+ }
+
+ void erasingInstr(MachineInstr &MI) override {
+ LLVM_DEBUG(dbgs() << ".. .. Erasing: " << MI);
+ InstList.remove(&MI);
+ ArtifactList.remove(&MI);
+ }
+
+ void changingInstr(MachineInstr &MI) override {
+ LLVM_DEBUG(dbgs() << ".. .. Changing MI: " << MI);
+ }
+
+ void changedInstr(MachineInstr &MI) override {
+ // When insts change, we want to revisit them to legalize them again.
+ // We'll consider them the same as created.
+ LLVM_DEBUG(dbgs() << ".. .. Changed MI: " << MI);
+ createdOrChangedInstr(MI);
+ }
+};
+} // namespace
+
+Legalizer::MFResult
+Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
+ ArrayRef<GISelChangeObserver *> AuxObservers,
+ LostDebugLocObserver &LocObserver,
+ MachineIRBuilder &MIRBuilder) {
+ MIRBuilder.setMF(MF);
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+
+ // Populate worklists.
+ InstListTy InstList;
+ ArtifactListTy ArtifactList;
+ ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
+ // Perform legalization bottom up so we can DCE as we legalize.
+ // Traverse BB in RPOT and within each basic block, add insts top down,
+ // so when we pop_back_val in the legalization process, we traverse bottom-up.
+ for (auto *MBB : RPOT) {
+ if (MBB->empty())
+ continue;
+ for (MachineInstr &MI : *MBB) {
+ // Only legalize pre-isel generic instructions: others don't have types
+ // and are assumed to be legal.
+ if (!isPreISelGenericOpcode(MI.getOpcode()))
+ continue;
+ if (isArtifact(MI))
+ ArtifactList.deferred_insert(&MI);
+ else
+ InstList.deferred_insert(&MI);
+ }
+ }
+ ArtifactList.finalize();
+ InstList.finalize();
+
+ // This observer keeps the worklists updated.
+ LegalizerWorkListManager WorkListObserver(InstList, ArtifactList);
+ // We want both WorkListObserver as well as all the auxiliary observers (e.g.
+ // CSEInfo) to observe all changes. Use the wrapper observer.
+ GISelObserverWrapper WrapperObserver(&WorkListObserver);
+ for (GISelChangeObserver *Observer : AuxObservers)
+ WrapperObserver.addObserver(Observer);
+
+ // Now install the observer as the delegate to MF.
+ // This will keep all the observers notified about new insertions/deletions.
+ RAIIMFObsDelInstaller Installer(MF, WrapperObserver);
+ LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder);
+ LegalizationArtifactCombiner ArtCombiner(MIRBuilder, MRI, LI);
+ auto RemoveDeadInstFromLists = [&WrapperObserver](MachineInstr *DeadMI) {
+ WrapperObserver.erasingInstr(*DeadMI);
+ };
+ bool Changed = false;
+ SmallVector<MachineInstr *, 128> RetryList;
+ do {
+ LLVM_DEBUG(dbgs() << "=== New Iteration ===\n");
+ assert(RetryList.empty() && "Expected no instructions in RetryList");
+ unsigned NumArtifacts = ArtifactList.size();
+ while (!InstList.empty()) {
+ MachineInstr &MI = *InstList.pop_back_val();
+ assert(isPreISelGenericOpcode(MI.getOpcode()) &&
+ "Expecting generic opcode");
+ if (isTriviallyDead(MI, MRI)) {
+ LLVM_DEBUG(dbgs() << MI << "Is dead; erasing.\n");
+ MI.eraseFromParentAndMarkDBGValuesForRemoval();
+ LocObserver.checkpoint(false);
+ continue;
+ }
+
+ // Do the legalization for this instruction.
+ auto Res = Helper.legalizeInstrStep(MI);
+ // Error out if we couldn't legalize this instruction. We may want to
+ // fall back to DAG ISel instead in the future.
+ if (Res == LegalizerHelper::UnableToLegalize) {
+ // Move illegal artifacts to RetryList instead of aborting because
+ // legalizing InstList may generate artifacts that allow
+ // ArtifactCombiner to combine away them.
+ if (isArtifact(MI)) {
+ LLVM_DEBUG(dbgs() << ".. Not legalized, moving to artifacts retry\n");
+ assert(NumArtifacts == 0 &&
+ "Artifacts are only expected in instruction list starting the "
+ "second iteration, but each iteration starting second must "
+ "start with an empty artifacts list");
+ (void)NumArtifacts;
+ RetryList.push_back(&MI);
+ continue;
+ }
+ Helper.MIRBuilder.stopObservingChanges();
+ return {Changed, &MI};
+ }
+ WorkListObserver.printNewInstrs();
+ LocObserver.checkpoint();
+ Changed |= Res == LegalizerHelper::Legalized;
+ }
+ // Try to combine the instructions in RetryList again if there
+ // are new artifacts. If not, stop legalizing.
+ if (!RetryList.empty()) {
+ if (!ArtifactList.empty()) {
+ while (!RetryList.empty())
+ ArtifactList.insert(RetryList.pop_back_val());
+ } else {
+ LLVM_DEBUG(dbgs() << "No new artifacts created, not retrying!\n");
+ Helper.MIRBuilder.stopObservingChanges();
+ return {Changed, RetryList.front()};
+ }
+ }
+ LocObserver.checkpoint();
+ while (!ArtifactList.empty()) {
+ MachineInstr &MI = *ArtifactList.pop_back_val();
+ assert(isPreISelGenericOpcode(MI.getOpcode()) &&
+ "Expecting generic opcode");
+ if (isTriviallyDead(MI, MRI)) {
+ LLVM_DEBUG(dbgs() << MI << "Is dead\n");
+ RemoveDeadInstFromLists(&MI);
+ MI.eraseFromParentAndMarkDBGValuesForRemoval();
+ LocObserver.checkpoint(false);
+ continue;
+ }
+ SmallVector<MachineInstr *, 4> DeadInstructions;
+ LLVM_DEBUG(dbgs() << "Trying to combine: " << MI);
+ if (ArtCombiner.tryCombineInstruction(MI, DeadInstructions,
+ WrapperObserver)) {
+ WorkListObserver.printNewInstrs();
+ for (auto *DeadMI : DeadInstructions) {
LLVM_DEBUG(dbgs() << "Is dead: " << *DeadMI);
- RemoveDeadInstFromLists(DeadMI);
- DeadMI->eraseFromParentAndMarkDBGValuesForRemoval();
- }
- LocObserver.checkpoint(
- VerifyDebugLocs ==
- DebugLocVerifyLevel::LegalizationsAndArtifactCombiners);
- Changed = true;
- continue;
- }
- // If this was not an artifact (that could be combined away), this might
- // need special handling. Add it to InstList, so when it's processed
- // there, it has to be legal or specially handled.
- else {
- LLVM_DEBUG(dbgs() << ".. Not combined, moving to instructions list\n");
- InstList.insert(&MI);
- }
- }
- } while (!InstList.empty());
-
- return {Changed, /*FailedOn*/ nullptr};
-}
-
-bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
- // If the ISel pipeline failed, do not bother running that pass.
- if (MF.getProperties().hasProperty(
- MachineFunctionProperties::Property::FailedISel))
- return false;
- LLVM_DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n');
- init(MF);
- const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
- GISelCSEAnalysisWrapper &Wrapper =
- getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
- MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
-
- const size_t NumBlocks = MF.size();
-
- std::unique_ptr<MachineIRBuilder> MIRBuilder;
- GISelCSEInfo *CSEInfo = nullptr;
- bool EnableCSE = EnableCSEInLegalizer.getNumOccurrences()
- ? EnableCSEInLegalizer
- : TPC.isGISelCSEEnabled();
- if (EnableCSE) {
- MIRBuilder = std::make_unique<CSEMIRBuilder>();
- CSEInfo = &Wrapper.get(TPC.getCSEConfig());
- MIRBuilder->setCSEInfo(CSEInfo);
- } else
- MIRBuilder = std::make_unique<MachineIRBuilder>();
-
- SmallVector<GISelChangeObserver *, 1> AuxObservers;
- if (EnableCSE && CSEInfo) {
- // We want CSEInfo in addition to WorkListObserver to observe all changes.
- AuxObservers.push_back(CSEInfo);
- }
- assert(!CSEInfo || !errorToBool(CSEInfo->verify()));
- LostDebugLocObserver LocObserver(DEBUG_TYPE);
- if (VerifyDebugLocs > DebugLocVerifyLevel::None)
- AuxObservers.push_back(&LocObserver);
-
- const LegalizerInfo &LI = *MF.getSubtarget().getLegalizerInfo();
- MFResult Result =
- legalizeMachineFunction(MF, LI, AuxObservers, LocObserver, *MIRBuilder);
-
- if (Result.FailedOn) {
- reportGISelFailure(MF, TPC, MORE, "gisel-legalize",
- "unable to legalize instruction", *Result.FailedOn);
- return false;
- }
- // For now don't support if new blocks are inserted - we would need to fix the
- // outer loop for that.
- if (MF.size() != NumBlocks) {
- MachineOptimizationRemarkMissed R("gisel-legalize", "GISelFailure",
- MF.getFunction().getSubprogram(),
- /*MBB=*/nullptr);
- R << "inserting blocks is not supported yet";
- reportGISelFailure(MF, TPC, MORE, R);
- return false;
- }
-
- if (LocObserver.getNumLostDebugLocs()) {
- MachineOptimizationRemarkMissed R("gisel-legalize", "LostDebugLoc",
- MF.getFunction().getSubprogram(),
- /*MBB=*/&*MF.begin());
- R << "lost "
- << ore::NV("NumLostDebugLocs", LocObserver.getNumLostDebugLocs())
- << " debug locations during pass";
- reportGISelWarning(MF, TPC, MORE, R);
- // Example remark:
- // --- !Missed
- // Pass: gisel-legalize
- // Name: GISelFailure
- // DebugLoc: { File: '.../legalize-urem.mir', Line: 1, Column: 0 }
- // Function: test_urem_s32
- // Args:
- // - String: 'lost '
- // - NumLostDebugLocs: '1'
- // - String: ' debug locations during pass'
- // ...
- }
-
- // If for some reason CSE was not enabled, make sure that we invalidate the
- // CSEInfo object (as we currently declare that the analysis is preserved).
- // The next time get on the wrapper is called, it will force it to recompute
- // the analysis.
- if (!EnableCSE)
- Wrapper.setComputed(false);
- return Result.Changed;
-}
+ RemoveDeadInstFromLists(DeadMI);
+ DeadMI->eraseFromParentAndMarkDBGValuesForRemoval();
+ }
+ LocObserver.checkpoint(
+ VerifyDebugLocs ==
+ DebugLocVerifyLevel::LegalizationsAndArtifactCombiners);
+ Changed = true;
+ continue;
+ }
+ // If this was not an artifact (that could be combined away), this might
+ // need special handling. Add it to InstList, so when it's processed
+ // there, it has to be legal or specially handled.
+ else {
+ LLVM_DEBUG(dbgs() << ".. Not combined, moving to instructions list\n");
+ InstList.insert(&MI);
+ }
+ }
+ } while (!InstList.empty());
+
+ return {Changed, /*FailedOn*/ nullptr};
+}
+
+bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
+ // If the ISel pipeline failed, do not bother running that pass.
+ if (MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::FailedISel))
+ return false;
+ LLVM_DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n');
+ init(MF);
+ const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
+ GISelCSEAnalysisWrapper &Wrapper =
+ getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
+ MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
+
+ const size_t NumBlocks = MF.size();
+
+ std::unique_ptr<MachineIRBuilder> MIRBuilder;
+ GISelCSEInfo *CSEInfo = nullptr;
+ bool EnableCSE = EnableCSEInLegalizer.getNumOccurrences()
+ ? EnableCSEInLegalizer
+ : TPC.isGISelCSEEnabled();
+ if (EnableCSE) {
+ MIRBuilder = std::make_unique<CSEMIRBuilder>();
+ CSEInfo = &Wrapper.get(TPC.getCSEConfig());
+ MIRBuilder->setCSEInfo(CSEInfo);
+ } else
+ MIRBuilder = std::make_unique<MachineIRBuilder>();
+
+ SmallVector<GISelChangeObserver *, 1> AuxObservers;
+ if (EnableCSE && CSEInfo) {
+ // We want CSEInfo in addition to WorkListObserver to observe all changes.
+ AuxObservers.push_back(CSEInfo);
+ }
+ assert(!CSEInfo || !errorToBool(CSEInfo->verify()));
+ LostDebugLocObserver LocObserver(DEBUG_TYPE);
+ if (VerifyDebugLocs > DebugLocVerifyLevel::None)
+ AuxObservers.push_back(&LocObserver);
+
+ const LegalizerInfo &LI = *MF.getSubtarget().getLegalizerInfo();
+ MFResult Result =
+ legalizeMachineFunction(MF, LI, AuxObservers, LocObserver, *MIRBuilder);
+
+ if (Result.FailedOn) {
+ reportGISelFailure(MF, TPC, MORE, "gisel-legalize",
+ "unable to legalize instruction", *Result.FailedOn);
+ return false;
+ }
+ // For now don't support if new blocks are inserted - we would need to fix the
+ // outer loop for that.
+ if (MF.size() != NumBlocks) {
+ MachineOptimizationRemarkMissed R("gisel-legalize", "GISelFailure",
+ MF.getFunction().getSubprogram(),
+ /*MBB=*/nullptr);
+ R << "inserting blocks is not supported yet";
+ reportGISelFailure(MF, TPC, MORE, R);
+ return false;
+ }
+
+ if (LocObserver.getNumLostDebugLocs()) {
+ MachineOptimizationRemarkMissed R("gisel-legalize", "LostDebugLoc",
+ MF.getFunction().getSubprogram(),
+ /*MBB=*/&*MF.begin());
+ R << "lost "
+ << ore::NV("NumLostDebugLocs", LocObserver.getNumLostDebugLocs())
+ << " debug locations during pass";
+ reportGISelWarning(MF, TPC, MORE, R);
+ // Example remark:
+ // --- !Missed
+ // Pass: gisel-legalize
+ // Name: GISelFailure
+ // DebugLoc: { File: '.../legalize-urem.mir', Line: 1, Column: 0 }
+ // Function: test_urem_s32
+ // Args:
+ // - String: 'lost '
+ // - NumLostDebugLocs: '1'
+ // - String: ' debug locations during pass'
+ // ...
+ }
+
+ // If for some reason CSE was not enabled, make sure that we invalidate the
+ // CSEInfo object (as we currently declare that the analysis is preserved).
+ // The next time get on the wrapper is called, it will force it to recompute
+ // the analysis.
+ if (!EnableCSE)
+ Wrapper.setComputed(false);
+ return Result.Changed;
+}