diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h b/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h deleted file mode 100644 index 284d9838af7a..000000000000 --- a/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h +++ /dev/null @@ -1,58 +0,0 @@ -//== llvm/CodeGen/GlobalISel/Localizer.h - Localizer -------------*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -/// \file This file describes the interface of the -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_GLOBALISEL_LOCALIZER_H -#define LLVM_CODEGEN_GLOBALISEL_LOCALIZER_H - -#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" -#include "llvm/CodeGen/MachineFunctionPass.h" - -namespace llvm { -// Forward declarations. -class MachineRegisterInfo; - -/// This pass implements the reg bank selector pass used in the GlobalISel -/// pipeline. At the end of this pass, all register operands have been assigned -class Localizer : public MachineFunctionPass { -public: - static char ID; - -private: - /// MRI contains all the register class/bank information that this - /// pass uses and updates. - MachineRegisterInfo *MRI; - - static bool shouldLocalize(const MachineInstr &MI); - - static bool isLocalUse(MachineOperand &MOUse, const MachineInstr &Def, MachineBasicBlock **InsertMBB); - - /// Initialize the field members using \p MF. - void init(MachineFunction &MF); - -public: - Localizer(); - - StringRef getPassName() const override { return "Localizer"; } - - MachineFunctionProperties getRequiredProperties() const override { - return MachineFunctionProperties() - .set(MachineFunctionProperties::Property::IsSSA) - .set(MachineFunctionProperties::Property::Legalized) - .set(MachineFunctionProperties::Property::RegBankSelected); - } - - bool runOnMachineFunction(MachineFunction &MF) override; -}; - -} // End namespace llvm. - -#endif diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h index 1026654da3d7..6e5c6473ff4a 100644 --- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h @@ -642,11 +642,6 @@ public: /// void setRegBank(unsigned Reg, const RegisterBank &RegBank); - void setRegClassOrRegBank(unsigned Reg, - const RegClassOrRegBank &RCOrRB){ - VRegInfo[Reg].first = RCOrRB; - } - /// constrainRegClass - Constrain the register class of the specified virtual /// register to be a common subclass of RC and the current register class, /// but only if the new class has at least MinNumRegs registers. Return the diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 4809c6a7c1bc..1b76c02ef041 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -192,7 +192,6 @@ void initializeLiveVariablesPass(PassRegistry&); void initializeLoadCombinePass(PassRegistry&); void initializeLoadStoreVectorizerPass(PassRegistry&); void initializeLoaderPassPass(PassRegistry&); -void initializeLocalizerPass(PassRegistry&); void initializeLocalStackSlotPassPass(PassRegistry&); void initializeLoopAccessLegacyAnalysisPass(PassRegistry&); void initializeLoopDataPrefetchLegacyPassPass(PassRegistry&); diff --git a/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt b/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt index 705ef74aac7c..03a8c4f5f909 100644 --- a/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt +++ b/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt @@ -8,7 +8,6 @@ set(GLOBAL_ISEL_FILES LegalizerHelper.cpp Legalizer.cpp LegalizerInfo.cpp - Localizer.cpp RegBankSelect.cpp RegisterBank.cpp RegisterBankInfo.cpp diff --git a/llvm/lib/CodeGen/GlobalISel/GlobalISel.cpp b/llvm/lib/CodeGen/GlobalISel/GlobalISel.cpp index 29d1209bb02a..fcd2722f1c2f 100644 --- a/llvm/lib/CodeGen/GlobalISel/GlobalISel.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GlobalISel.cpp @@ -26,7 +26,6 @@ void llvm::initializeGlobalISel(PassRegistry &Registry) { void llvm::initializeGlobalISel(PassRegistry &Registry) { initializeIRTranslatorPass(Registry); initializeLegalizerPass(Registry); - initializeLocalizerPass(Registry); initializeRegBankSelectPass(Registry); initializeInstructionSelectPass(Registry); } diff --git a/llvm/lib/CodeGen/GlobalISel/Localizer.cpp b/llvm/lib/CodeGen/GlobalISel/Localizer.cpp deleted file mode 100644 index e5b1449cdae2..000000000000 --- a/llvm/lib/CodeGen/GlobalISel/Localizer.cpp +++ /dev/null @@ -1,120 +0,0 @@ -//===- Localizer.cpp ---------------------- Localize some instrs -*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// \file -/// This file implements the Localizer class. -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/CodeGen/GlobalISel/Localizer.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Support/Debug.h" - -#define DEBUG_TYPE "localizer" - -using namespace llvm; - -char Localizer::ID = 0; -INITIALIZE_PASS(Localizer, DEBUG_TYPE, - "Move/duplicate certain instructions close to their use", - false, false); - -Localizer::Localizer() : MachineFunctionPass(ID) { - initializeLocalizerPass(*PassRegistry::getPassRegistry()); -} - -void Localizer::init(MachineFunction &MF) { - MRI = &MF.getRegInfo(); -} - -bool Localizer::shouldLocalize(const MachineInstr &MI) { - switch(MI.getOpcode()) { - default: - return false; - // Constants-like instructions should be close to their users. - // We don't want long live-ranges for them. - case TargetOpcode::G_CONSTANT: - case TargetOpcode::G_FRAME_INDEX: - return true; - } -} - -bool Localizer::isLocalUse(MachineOperand &MOUse, const MachineInstr &Def, MachineBasicBlock **InsertMBB) { - MachineInstr &MIUse = *MOUse.getParent(); - *InsertMBB = MIUse.getParent(); - if (MIUse.isPHI()) - *InsertMBB = MIUse.getOperand(MIUse.getOperandNo(&MOUse) + 1).getMBB(); - return *InsertMBB == Def.getParent(); -} - -bool Localizer::runOnMachineFunction(MachineFunction &MF) { - // If the ISel pipeline failed, do not bother running that pass. - if (MF.getProperties().hasProperty( - MachineFunctionProperties::Property::FailedISel)) - return false; - - DEBUG(dbgs() << "Localize instructions for: " << MF.getName() << '\n'); - - init(MF); - - bool Changed = false; - // Keep track of the instructions we localized. - // We won't need to process them if we see them later in the CFG. - SmallPtrSet LocalizedInstrs; - DenseMap, unsigned> MBBWithLocalDef; - // TODO: Do bottom up traversal. - for (MachineBasicBlock &MBB : MF) { - for (MachineInstr &MI : MBB) { - if (LocalizedInstrs.count(&MI) || !shouldLocalize(MI)) - continue; - DEBUG(dbgs() << "Should localize: " << MI); - assert(MI.getDesc().getNumDefs() == 1 && "More than one definition not supported yet"); - unsigned Reg = MI.getOperand(0).getReg(); - // Check if all the users of MI are local. - // We are going to invalidation the list of use operands, so we - // can't use range iterator. - for (auto MOIt = MRI->use_begin(Reg), MOItEnd = MRI->use_end(); - MOIt != MOItEnd;) { - MachineOperand &MOUse = *MOIt++; - // Check if the use is already local. - MachineBasicBlock *InsertMBB; - DEBUG(MachineInstr &MIUse = *MOUse.getParent(); - dbgs() << "Checking use: " << MIUse << " #Opd: " << MIUse.getOperandNo(&MOUse) << '\n'); - if (isLocalUse(MOUse, MI, &InsertMBB)) - continue; - DEBUG(dbgs() << "Fixing non-local use\n"); - Changed = true; - auto MBBAndReg = std::make_pair(InsertMBB, Reg); - auto NewVRegIt = MBBWithLocalDef.find(MBBAndReg); - if (NewVRegIt == MBBWithLocalDef.end()) { - // Create the localized instruction. - MachineInstr *LocalizedMI = MF.CloneMachineInstr(&MI); - LocalizedInstrs.insert(LocalizedMI); - // Move it at the right place. - MachineInstr &MIUse = *MOUse.getParent(); - if (MIUse.getParent() == InsertMBB) - InsertMBB->insert(MIUse, LocalizedMI); - else - InsertMBB->insert(InsertMBB->getFirstNonPHI(), LocalizedMI); - - // Set a new register for the definition. - unsigned NewReg = MRI->createGenericVirtualRegister(MRI->getType(Reg)); - MRI->setRegClassOrRegBank(NewReg, MRI->getRegClassOrRegBank(Reg)); - LocalizedMI->getOperand(0).setReg(NewReg); - NewVRegIt = MBBWithLocalDef.insert(std::make_pair(MBBAndReg, NewReg)).first; - DEBUG(dbgs() << "Inserted: " << *LocalizedMI); - } - DEBUG(dbgs() << "Update use with: " << PrintReg(NewVRegIt->second) << '\n'); - // Update the user reg. - MOUse.setReg(NewVRegIt->second); - } - } - } - return Changed; -} diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/localizer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/localizer.mir deleted file mode 100644 index ea60f5fe135d..000000000000 --- a/llvm/test/CodeGen/AArch64/GlobalISel/localizer.mir +++ /dev/null @@ -1,260 +0,0 @@ -# RUN: llc -O0 -mtriple=aarch64-apple-ios -run-pass=localizer -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefix=CHECK - -# Test the localizer. - ---- | - target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" - - define void @local_use() { ret void } - define void @non_local_1use() { ret void } - define void @non_local_2uses() { ret void } - define void @non_local_phi_use() { ret void } - define void @non_local_phi_use_followed_by_use() { ret void } - define void @non_local_phi_use_followed_by_use_fi() { ret void } -... - ---- -# CHECK-LABEL: name: local_use -name: local_use -legalized: true -regBankSelected: true - -# CHECK: registers: -registers: - - { id: 0, class: gpr } - - { id: 1, class: gpr } - - { id: 2, class: gpr } - -# CHECK: body: -# CHECK: %0(s32) = G_CONSTANT 1 -# CHECK-NEXT: %1(s32) = G_ADD %0, %0 -body: | - bb.0: - %0(s32) = G_CONSTANT 1 - %1(s32) = G_ADD %0, %0 -... - ---- -# CHECK-LABEL: name: non_local_1use -name: non_local_1use -legalized: true -regBankSelected: true - -# CHECK: registers: -# Existing registers should be left untouched -# CHECK: - { id: 0, class: gpr } -#CHECK-NEXT: - { id: 1, class: gpr } -#CHECK-NEXT: - { id: 2, class: gpr } -# The newly created reg should be on the same regbank/regclass as its origin. -#CHECK-NEXT: - { id: 3, class: gpr } - -registers: - - { id: 0, class: gpr } - - { id: 1, class: gpr } - - { id: 2, class: gpr } - -# CHECK: body: -# CHECK: %0(s32) = G_CONSTANT 1 -# CHECK-NEXT: %1(s32) = G_ADD %0, %0 - -# CHECK: bb.1: -# CHECK: %3(s32) = G_CONSTANT 1 -# CHECK-NEXT: %2(s32) = G_ADD %3, %1 -body: | - bb.0: - successors: %bb.1 - - %0(s32) = G_CONSTANT 1 - %1(s32) = G_ADD %0, %0 - - bb.1: - %2(s32) = G_ADD %0, %1 -... - - ---- -# CHECK-LABEL: name: non_local_2uses -name: non_local_2uses -legalized: true -regBankSelected: true - -# CHECK: registers: -# Existing registers should be left untouched -# CHECK: - { id: 0, class: gpr } -#CHECK-NEXT: - { id: 1, class: gpr } -#CHECK-NEXT: - { id: 2, class: gpr } -# The newly created reg should be on the same regbank/regclass as its origin. -#CHECK-NEXT: - { id: 3, class: gpr } - -registers: - - { id: 0, class: gpr } - - { id: 1, class: gpr } - - { id: 2, class: gpr } - -# CHECK: body: -# CHECK: %0(s32) = G_CONSTANT 1 -# CHECK-NEXT: %1(s32) = G_ADD %0, %0 - -# CHECK: bb.1: -# CHECK: %3(s32) = G_CONSTANT 1 -# CHECK-NEXT: %2(s32) = G_ADD %3, %3 -body: | - bb.0: - successors: %bb.1 - - %0(s32) = G_CONSTANT 1 - %1(s32) = G_ADD %0, %0 - - bb.1: - %2(s32) = G_ADD %0, %0 -... - ---- -# CHECK-LABEL: name: non_local_phi_use -name: non_local_phi_use -legalized: true -regBankSelected: true -tracksRegLiveness: true - -# CHECK: registers: -# Existing registers should be left untouched -# CHECK: - { id: 0, class: gpr } -#CHECK-NEXT: - { id: 1, class: gpr } -#CHECK-NEXT: - { id: 2, class: gpr } -#CHECK-NEXT: - { id: 3, class: gpr } -#CHECK-NEXT: - { id: 4, class: gpr } -# The newly created reg should be on the same regbank/regclass as its origin. -#CHECK-NEXT: - { id: 5, class: gpr } - -registers: - - { id: 0, class: gpr } - - { id: 1, class: gpr } - - { id: 2, class: gpr } - - { id: 3, class: gpr } - - { id: 4, class: gpr } - -# CHECK: body: -# CHECK: %0(s32) = G_CONSTANT 1 -# CHECK-NEXT: %1(s32) = G_ADD %0, %0 - -# CHECK: bb.1: -# CHECK: %5(s32) = G_CONSTANT 1 - -# CHECK: bb.2: -# CHECK: %3(s32) = PHI %5(s32), %bb.1 -body: | - bb.0: - successors: %bb.1 - - %0(s32) = G_CONSTANT 1 - %1(s32) = G_ADD %0, %0 - - bb.1: - successors: %bb.2 - - bb.2: - %3(s32) = PHI %0(s32), %bb.1 - %2(s32) = G_ADD %3, %3 -... - ---- -# CHECK-LABEL: name: non_local_phi_use_followed_by_use -name: non_local_phi_use_followed_by_use -legalized: true -regBankSelected: true -tracksRegLiveness: true - -# CHECK: registers: -# Existing registers should be left untouched -# CHECK: - { id: 0, class: gpr } -#CHECK-NEXT: - { id: 1, class: gpr } -#CHECK-NEXT: - { id: 2, class: gpr } -#CHECK-NEXT: - { id: 3, class: gpr } -#CHECK-NEXT: - { id: 4, class: gpr } -# The newly created regs should be on the same regbank/regclass as its origin. -#CHECK-NEXT: - { id: 5, class: gpr } -#CHECK-NEXT: - { id: 6, class: gpr } - -registers: - - { id: 0, class: gpr } - - { id: 1, class: gpr } - - { id: 2, class: gpr } - - { id: 3, class: gpr } - - { id: 4, class: gpr } - -# CHECK: body: -# CHECK: %0(s32) = G_CONSTANT 1 -# CHECK-NEXT: %1(s32) = G_ADD %0, %0 - -# CHECK: bb.1: -# CHECK: %5(s32) = G_CONSTANT 1 - -# CHECK: bb.2: -# CHECK: %3(s32) = PHI %5(s32), %bb.1 -# CHECK-NEXT: %6(s32) = G_CONSTANT 1 -# CHECK-NEXT: %2(s32) = G_ADD %3, %6 -body: | - bb.0: - successors: %bb.1 - - %0(s32) = G_CONSTANT 1 - %1(s32) = G_ADD %0, %0 - - bb.1: - successors: %bb.2 - - bb.2: - %3(s32) = PHI %0(s32), %bb.1 - %2(s32) = G_ADD %3, %0 -... - ---- -# CHECK-LABEL: name: non_local_phi_use_followed_by_use_fi -name: non_local_phi_use_followed_by_use_fi -legalized: true -regBankSelected: true -tracksRegLiveness: true - -# CHECK: registers: -# Existing registers should be left untouched -# CHECK: - { id: 0, class: gpr } -#CHECK-NEXT: - { id: 1, class: gpr } -#CHECK-NEXT: - { id: 2, class: gpr } -#CHECK-NEXT: - { id: 3, class: gpr } -#CHECK-NEXT: - { id: 4, class: gpr } -# The newly created reg should be on the same regbank/regclass as its origin. -#CHECK-NEXT: - { id: 5, class: gpr } -#CHECK-NEXT: - { id: 6, class: gpr } - -registers: - - { id: 0, class: gpr } - - { id: 1, class: gpr } - - { id: 2, class: gpr } - - { id: 3, class: gpr } - - { id: 4, class: gpr } - -# CHECK: body: -# CHECK: %0(s32) = G_FRAME_INDEX 1 -# CHECK-NEXT: %1(s32) = G_ADD %0, %0 - -# CHECK: bb.1: -# CHECK: %5(s32) = G_FRAME_INDEX 1 - -# CHECK: bb.2: -# CHECK: %3(s32) = PHI %5(s32), %bb.1 -# CHECK-NEXT: %6(s32) = G_FRAME_INDEX 1 -# CHECK-NEXT: %2(s32) = G_ADD %3, %6 -body: | - bb.0: - successors: %bb.1 - - %0(s32) = G_FRAME_INDEX 1 - %1(s32) = G_ADD %0, %0 - - bb.1: - successors: %bb.2 - - bb.2: - %3(s32) = PHI %0(s32), %bb.1 - %2(s32) = G_ADD %3, %0 -...