[llvm] r272414 - Interprocedural Register Allocation (IPRA): add a Transformation Pass

Hal Finkel via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 17 00:17:29 PDT 2016


----- Original Message -----
> From: "Mehdi Amini via llvm-commits" <llvm-commits at lists.llvm.org>
> To: llvm-commits at lists.llvm.org
> Sent: Friday, June 10, 2016 1:37:21 PM
> Subject: [llvm] r272414 - Interprocedural Register Allocation (IPRA): add a Transformation Pass
> 
> Author: mehdi_amini
> Date: Fri Jun 10 13:37:21 2016
> New Revision: 272414
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=272414&view=rev
> Log:
> Interprocedural Register Allocation (IPRA): add a Transformation Pass
> 
> Adds a MachineFunctionPass that scans the body to find calls, and
> update the register mask with the one saved by the
> RegUsageInfoCollector analysis in PhysicalRegisterUsageInfo.
> 
> Patch by Vivek Pandya <vivekvpandya at gmail.com>
> 
> Differential Revision: http://reviews.llvm.org/D21180
> 
> Added:
>     llvm/trunk/lib/CodeGen/RegUsageInfoPropagate.cpp
>     llvm/trunk/test/CodeGen/Generic/ipra-transform.ll
> Modified:
>     llvm/trunk/include/llvm/CodeGen/Passes.h
>     llvm/trunk/lib/CodeGen/CMakeLists.txt
>     llvm/trunk/lib/CodeGen/TargetPassConfig.cpp
> 
> Modified: llvm/trunk/include/llvm/CodeGen/Passes.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=272414&r1=272413&r2=272414&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/Passes.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/Passes.h Fri Jun 10 13:37:21 2016
> @@ -365,6 +365,11 @@ namespace llvm {
>    /// This pass is executed POST-RA to collect which physical
>    registers are
>    /// preserved by given machine function.
>    FunctionPass *createRegUsageInfoCollector();
> +
> +  /// Return a MachineFunction pass that identifies call sites
> +  /// and propagates register usage information of callee to caller
> +  /// if available with PysicalRegisterUsageInfo pass.
> +  FunctionPass *createRegUsageInfoPropPass();
>  } // End llvm namespace
>  
>  /// Target machine pass initializer for passes with dependencies.
>  Use with
> 
> Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=272414&r1=272413&r2=272414&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original)
> +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Fri Jun 10 13:37:21 2016
> @@ -103,6 +103,7 @@ add_llvm_library(LLVMCodeGen
>    RenameIndependentSubregs.cpp
>    RegisterUsageInfo.cpp
>    RegUsageInfoCollector.cpp
> +  RegUsageInfoPropagate.cpp
>    SafeStack.cpp
>    ScheduleDAG.cpp
>    ScheduleDAGInstrs.cpp
> 
> Added: llvm/trunk/lib/CodeGen/RegUsageInfoPropagate.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegUsageInfoPropagate.cpp?rev=272414&view=auto
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/RegUsageInfoPropagate.cpp (added)
> +++ llvm/trunk/lib/CodeGen/RegUsageInfoPropagate.cpp Fri Jun 10
> 13:37:21 2016
> @@ -0,0 +1,131 @@
> +//=--- RegUsageInfoPropagate.cpp - Register Usage Informartion
> Propagation --=//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// This pass is required to take advantage of the interprocedural
> register
> +/// allocation infrastructure.
> +///
> +/// This pass iterates through MachineInstrs in a given
> MachineFunction and at
> +/// each callsite queries RegisterUsageInfo for RegMask (calculated
> based on
> +/// actual register allocation) of the callee function, if the
> RegMask detail
> +/// is available then this pass will update the RegMask of the call
> instruction.
> +/// This updated RegMask will be used by the register allocator
> while allocating
> +/// the current MachineFunction.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/CodeGen/MachineBasicBlock.h"
> +#include "llvm/CodeGen/MachineFunctionPass.h"
> +#include "llvm/CodeGen/MachineInstr.h"
> +#include "llvm/CodeGen/MachineRegisterInfo.h"
> +#include "llvm/CodeGen/Passes.h"
> +#include "llvm/CodeGen/RegisterUsageInfo.h"
> +#include "llvm/IR/Module.h"
> +#include "llvm/PassAnalysisSupport.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include "llvm/Target/TargetMachine.h"
> +#include <map>
> +#include <string>
> +
> +namespace llvm {
> +void initializeRegUsageInfoPropagationPassPass(PassRegistry &);
> +}
> +
> +using namespace llvm;
> +
> +#define DEBUG_TYPE "ip-regalloc"
> +
> +#define RUIP_NAME "Register Usage Information Propagation"
> +
> +namespace {
> +class RegUsageInfoPropagationPass : public MachineFunctionPass {
> +
> +public:
> +  RegUsageInfoPropagationPass() : MachineFunctionPass(ID) {
> +    PassRegistry &Registry = *PassRegistry::getPassRegistry();
> +    initializeRegUsageInfoPropagationPassPass(Registry);
> +  }
> +
> +  const char *getPassName() const override { return RUIP_NAME; }
> +
> +  bool runOnMachineFunction(MachineFunction &MF) override;
> +
> +  void getAnalysisUsage(AnalysisUsage &AU) const override;
> +
> +  static char ID;
> +
> +private:
> +  static void setRegMask(MachineInstr &MI, const uint32_t *RegMask)
> {
> +    for (MachineOperand &MO : MI.operands()) {
> +      if (MO.isRegMask())
> +        MO.setRegMask(RegMask);
> +    }
> +  }
> +};
> +} // end of anonymous namespace
> +char RegUsageInfoPropagationPass::ID = 0;
> +
> +INITIALIZE_PASS_BEGIN(RegUsageInfoPropagationPass,
> "reg-usage-propagation",
> +                      RUIP_NAME, false, false)
> +INITIALIZE_PASS_DEPENDENCY(PhysicalRegisterUsageInfo)
> +INITIALIZE_PASS_END(RegUsageInfoPropagationPass,
> "reg-usage-propagation",
> +                    RUIP_NAME, false, false)
> +
> +FunctionPass *llvm::createRegUsageInfoPropPass() {
> +  return new RegUsageInfoPropagationPass();
> +}
> +
> +void RegUsageInfoPropagationPass::getAnalysisUsage(AnalysisUsage
> &AU) const {
> +  AU.addRequired<PhysicalRegisterUsageInfo>();
> +  AU.setPreservesAll();
> +  MachineFunctionPass::getAnalysisUsage(AU);
> +}
> +
> +bool
> RegUsageInfoPropagationPass::runOnMachineFunction(MachineFunction
> &MF) {
> +  const Module *M = MF.getFunction()->getParent();
> +  PhysicalRegisterUsageInfo *PRUI =
> &getAnalysis<PhysicalRegisterUsageInfo>();
> +
> +  DEBUG(dbgs() << " ++++++++++++++++++++ " << getPassName()
> +               << " ++++++++++++++++++++  \n");
> +  DEBUG(dbgs() << "MachineFunction : " << MF.getName() << "\n");
> +
> +  bool Changed = false;
> +
> +  for (MachineBasicBlock &MBB : MF) {
> +    for (MachineInstr &MI : MBB) {
> +      if (!MI.isCall())
> +        continue;
> +      DEBUG(dbgs()
> +            << "Call Instruction Before Register Usage Info
> Propagation : \n");
> +      DEBUG(dbgs() << MI << "\n");
> +
> +      auto UpdateRegMask = [&](const Function *F) {
> +        const auto *RegMask = PRUI->getRegUsageInfo(F);
> +        if (!RegMask)
> +          return;
> +        setRegMask(MI, &(*RegMask)[0]);
> +        Changed = true;
> +      };
> +
> +      MachineOperand &Operand = MI.getOperand(0);
> +      if (Operand.isGlobal())
> +        UpdateRegMask(cast<Function>(Operand.getGlobal()));
> +      else if (Operand.isSymbol())
> +        UpdateRegMask(M->getFunction(Operand.getSymbolName()))

You can't do this for all functions, even if you can see a definition, unless you know that it is *the* definition the linker will choose to use. We need to check F->isDefinitionExact() here.

 -Hal


> +
> +      DEBUG(dbgs()
> +            << "Call Instruction After Register Usage Info
> Propagation : \n");
> +      DEBUG(dbgs() << MI << "\n");
> +    }
> +  }
> +
> +  DEBUG(dbgs() << "
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
> +                  "++++++ \n");
> +  return Changed;
> +}
> 
> Modified: llvm/trunk/lib/CodeGen/TargetPassConfig.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetPassConfig.cpp?rev=272414&r1=272413&r2=272414&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/TargetPassConfig.cpp (original)
> +++ llvm/trunk/lib/CodeGen/TargetPassConfig.cpp Fri Jun 10 13:37:21
> 2016
> @@ -538,6 +538,9 @@ void TargetPassConfig::addISelPrepare()
>  void TargetPassConfig::addMachinePasses() {
>    AddingMachinePasses = true;
>  
> +  if (UseIPRA)
> +    addPass(createRegUsageInfoPropPass());
> +
>    // Insert a machine instr printer pass after the specified pass.
>    if (!StringRef(PrintMachineInstrs.getValue()).equals("") &&
>        !StringRef(PrintMachineInstrs.getValue()).equals("option-unspecified"))
>        {
> 
> Added: llvm/trunk/test/CodeGen/Generic/ipra-transform.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/ipra-transform.ll?rev=272414&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Generic/ipra-transform.ll (added)
> +++ llvm/trunk/test/CodeGen/Generic/ipra-transform.ll Fri Jun 10
> 13:37:21 2016
> @@ -0,0 +1,32 @@
> +
> +; RUN: llc < %s | FileCheck %s -check-prefix=NOIPRA
> +; RUN: llc -enable-ipra < %s | FileCheck %s
> +
> +
> +target triple = "x86_64-unknown-unknown"
> +define void @bar1() {
> +	ret void
> +}
> +define preserve_allcc void @foo()#0 {
> +; Due to preserve_allcc foo() will save some registers at start of
> foo()
> +; prefix NOIPRA will verify that.
> +; NOIPRA-LABEL: foo:
> +; NOIPRA: pushq	%r10
> +; NOIPRA-NEXT: pushq %r9
> +; NOIPRA-NEXT: pushq %r8
> +; NOIPRA: callq bar1
> +; When IPRA is present above registers will not be saved and that is
> verified
> +; by prefix CHECK.
> +; CHECK: foo:
> +; CHECK-NOT: pushq %r10
> +; CHECK-NOT: pushq %r9
> +; CHECK-NOT: pushq %r8
> +; CHECK: callq bar1
> +	call void @bar1()
> +	call void @bar2()
> +	ret void
> +}
> +define void @bar2() {
> +	ret void
> +}
> +attributes #0 = {nounwind}
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory


More information about the llvm-commits mailing list