[llvm] r299283 - Localizer fun
Quentin Colombet via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 31 18:40:20 PDT 2017
Reverted in 299287… Pushed hack/WIP from my local git.
Sorry guys.
> On Mar 31, 2017, at 6:21 PM, Quentin Colombet via llvm-commits <llvm-commits at lists.llvm.org> wrote:
>
> Author: qcolombet
> Date: Fri Mar 31 20:21:28 2017
> New Revision: 299283
>
> URL: http://llvm.org/viewvc/llvm-project?rev=299283&view=rev
> Log:
> Localizer fun
>
> WIP
>
> Added:
> llvm/trunk/include/llvm/CodeGen/GlobalISel/Localizer.h
> llvm/trunk/lib/CodeGen/GlobalISel/Localizer.cpp
> llvm/trunk/test/CodeGen/AArch64/GlobalISel/localizer.mir
> Modified:
> llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h
> llvm/trunk/include/llvm/InitializePasses.h
> llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt
> llvm/trunk/lib/CodeGen/GlobalISel/GlobalISel.cpp
>
> Added: llvm/trunk/include/llvm/CodeGen/GlobalISel/Localizer.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/Localizer.h?rev=299283&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/Localizer.h (added)
> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/Localizer.h Fri Mar 31 20:21:28 2017
> @@ -0,0 +1,58 @@
> +//== 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
>
> Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h?rev=299283&r1=299282&r2=299283&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h Fri Mar 31 20:21:28 2017
> @@ -642,6 +642,11 @@ 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
>
> Modified: llvm/trunk/include/llvm/InitializePasses.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=299283&r1=299282&r2=299283&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/InitializePasses.h (original)
> +++ llvm/trunk/include/llvm/InitializePasses.h Fri Mar 31 20:21:28 2017
> @@ -192,6 +192,7 @@ void initializeLiveVariablesPass(PassReg
> void initializeLoadCombinePass(PassRegistry&);
> void initializeLoadStoreVectorizerPass(PassRegistry&);
> void initializeLoaderPassPass(PassRegistry&);
> +void initializeLocalizerPass(PassRegistry&);
> void initializeLocalStackSlotPassPass(PassRegistry&);
> void initializeLoopAccessLegacyAnalysisPass(PassRegistry&);
> void initializeLoopDataPrefetchLegacyPassPass(PassRegistry&);
>
> Modified: llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt?rev=299283&r1=299282&r2=299283&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt (original)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt Fri Mar 31 20:21:28 2017
> @@ -8,6 +8,7 @@ set(GLOBAL_ISEL_FILES
> LegalizerHelper.cpp
> Legalizer.cpp
> LegalizerInfo.cpp
> + Localizer.cpp
> RegBankSelect.cpp
> RegisterBank.cpp
> RegisterBankInfo.cpp
>
> Modified: llvm/trunk/lib/CodeGen/GlobalISel/GlobalISel.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/GlobalISel.cpp?rev=299283&r1=299282&r2=299283&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/GlobalISel.cpp (original)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/GlobalISel.cpp Fri Mar 31 20:21:28 2017
> @@ -26,6 +26,7 @@ void llvm::initializeGlobalISel(PassRegi
> void llvm::initializeGlobalISel(PassRegistry &Registry) {
> initializeIRTranslatorPass(Registry);
> initializeLegalizerPass(Registry);
> + initializeLocalizerPass(Registry);
> initializeRegBankSelectPass(Registry);
> initializeInstructionSelectPass(Registry);
> }
>
> Added: llvm/trunk/lib/CodeGen/GlobalISel/Localizer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/Localizer.cpp?rev=299283&view=auto
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/Localizer.cpp (added)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/Localizer.cpp Fri Mar 31 20:21:28 2017
> @@ -0,0 +1,120 @@
> +//===- 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<MachineInstr *, 16> LocalizedInstrs;
> + DenseMap<std::pair<MachineBasicBlock *, unsigned>, 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;
> +}
>
> Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/localizer.mir
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/localizer.mir?rev=299283&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/GlobalISel/localizer.mir (added)
> +++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/localizer.mir Fri Mar 31 20:21:28 2017
> @@ -0,0 +1,260 @@
> +# 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
> +...
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list