[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