[PATCH] CodeGen: Add IntegerDivisionPass

Michael Ilseman milseman at apple.com
Tue Sep 23 13:57:23 PDT 2014


> On Sep 23, 2014, at 12:48 PM, Tom Stellard <thomas.stellard at amd.com> wrote:
> 
> This pass will expand unsupported div/rem instructions based on
> the result of the newly added TargetLowering::shouldExpandDivRemInIR().
> ---
> 
> A future commit will enable this pass for the R600 backend and add tests.
> 
> include/llvm/CodeGen/Passes.h        |   6 ++
> include/llvm/InitializePasses.h      |   1 +
> include/llvm/Target/TargetLowering.h |   6 ++
> lib/CodeGen/CMakeLists.txt           |   1 +
> lib/CodeGen/IntegerDivisionPass.cpp  | 124 +++++++++++++++++++++++++++++++++++
> 5 files changed, 138 insertions(+)
> create mode 100644 lib/CodeGen/IntegerDivisionPass.cpp
> 
> diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
> index 31fba89..3fedd5a 100644
> --- a/include/llvm/CodeGen/Passes.h
> +++ b/include/llvm/CodeGen/Passes.h
> @@ -376,6 +376,9 @@ namespace llvm {
>   /// load-linked/store-conditional loops.
>   extern char &AtomicExpandID;
> 
> +  /// Lowers unsupported integer division.
> +  extern char &IntegerDivisionID;
> +
>   /// MachineLoopInfo - This pass is a loop analysis pass.
>   extern char &MachineLoopInfoID;
> 
> @@ -598,6 +601,9 @@ namespace llvm {
> 
>   /// createJumpInstrTables - This pass creates jump-instruction tables.
>   ModulePass *createJumpInstrTablesPass();
> +
> +  /// Lower unsupported integer division
> +  FunctionPass *createIntegerDivisionPass(const TargetMachine *TM);
> } // End llvm namespace
> 
> /// This initializer registers TargetMachine constructor, so the pass being
> diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
> index 2964798..99f7ab5 100644
> --- a/include/llvm/InitializePasses.h
> +++ b/include/llvm/InitializePasses.h
> @@ -146,6 +146,7 @@ void initializeInlineCostAnalysisPass(PassRegistry&);
> void initializeInstCombinerPass(PassRegistry&);
> void initializeInstCountPass(PassRegistry&);
> void initializeInstNamerPass(PassRegistry&);
> +void initializeIntegerDivisionPass(PassRegistry&);
> void initializeInternalizePassPass(PassRegistry&);
> void initializeIntervalPartitionPass(PassRegistry&);
> void initializeJumpInstrTableInfoPass(PassRegistry&);
> diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
> index 0a72225..245df33 100644
> --- a/include/llvm/Target/TargetLowering.h
> +++ b/include/llvm/Target/TargetLowering.h
> @@ -1000,6 +1000,12 @@ public:
>     return false;
>   }
> 
> +  /// Returns true if the instruction should be expanded by the IR-level
> +  /// IntegerDivision pass.
> +  virtual bool shouldExpandDivRemInIR(const BinaryOperator &I) const {
> +    return false;
> +  }
> +
>   //===--------------------------------------------------------------------===//
>   // TargetLowering Configuration Methods - These methods should be invoked by
>   // the derived class constructor to configure this object for the target.
> diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
> index 0e06ed0..d002f47 100644
> --- a/lib/CodeGen/CMakeLists.txt
> +++ b/lib/CodeGen/CMakeLists.txt
> @@ -25,6 +25,7 @@ add_llvm_library(LLVMCodeGen
>   GlobalMerge.cpp
>   IfConversion.cpp
>   InlineSpiller.cpp
> +  IntegerDivisionPass.cpp
>   InterferenceCache.cpp
>   IntrinsicLowering.cpp
>   JumpInstrTables.cpp
> diff --git a/lib/CodeGen/IntegerDivisionPass.cpp b/lib/CodeGen/IntegerDivisionPass.cpp
> new file mode 100644
> index 0000000..b198a1f
> --- /dev/null
> +++ b/lib/CodeGen/IntegerDivisionPass.cpp
> @@ -0,0 +1,124 @@
> +//===-- IntegerDivisionPass.cpp - Expand div/mod instructions -------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/CodeGen/Passes.h"
> +#include "llvm/IR/IRBuilder.h"
> +#include "llvm/IR/InstVisitor.h"
> +#include "llvm/Target/TargetLowering.h"
> +#include "llvm/Target/TargetMachine.h"
> +#include "llvm/Target/TargetSubtargetInfo.h"
> +#include "llvm/Transforms/Utils/IntegerDivision.h"
> +using namespace llvm;
> +
> +#define DEBUG_TYPE "integer-division"
> +
> +namespace {
> +
> +class IntegerDivision : public FunctionPass,
> +                        public InstVisitor<IntegerDivision, bool> {
> +
> +  const TargetMachine *TM;
> +  const TargetLowering *TLI;
> +
> +  std::vector<BinaryOperator *> Divs;
> +  std::vector<BinaryOperator *> Rems;
> +

As far as I can tell from the patch, these vectors are not used. What is their intent?

> +  bool shouldExpandDivRem(const BinaryOperator &I);
> +
> +public:
> +  static char ID;
> +  explicit IntegerDivision(const TargetMachine *TM = nullptr)
> +      : FunctionPass(ID), TM(TM), TLI(nullptr) {
> +        initializeIntegerDivisionPass(*PassRegistry::getPassRegistry());
> +      }
> +  bool doInitialization(Module &M) override;
> +  bool runOnFunction(Function &F) override;
> +  const char *getPassName() const override {
> +    return "Integer Division Pass";
> +  }
> +  bool visitInstruction(Instruction &I) { return false; }
> +  bool visitSDiv(BinaryOperator &I);
> +  bool visitUDiv(BinaryOperator &I);
> +  bool visitSRem(BinaryOperator &I);
> +  bool visitURem(BinaryOperator &I);
> +
> +};
> +
> +} // End anonymous namespace
> +
> +char IntegerDivision::ID = 0;
> +char &llvm::IntegerDivisionID = IntegerDivision::ID;
> +INITIALIZE_TM_PASS(IntegerDivision, "integerdivision",
> +                   "Expand integer division", false, false);
> +
> +bool IntegerDivision::doInitialization(Module &M) {
> +  return false;
> +}
> +
> +bool IntegerDivision::runOnFunction(Function &F) {
> +
> +  if (TM)
> +    TLI = TM->getSubtargetImpl()->getTargetLowering();
> +
> +  for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) {
> +       BasicBlock *BB = BBI;
> +    for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE; ++II) {
> +        Instruction *I = II;
> +        if (visit(*I)) {
> +          BBI = F.begin();
> +          break;
> +        }
> +    }
> +  }
> +
> +  return false;
> +}
> +
> +bool IntegerDivision::shouldExpandDivRem(const BinaryOperator &I) {
> +  return TLI && TLI->shouldExpandDivRemInIR(I);
> +}
> +
> +bool IntegerDivision::visitSDiv(BinaryOperator &I) {
> +  if (shouldExpandDivRem(I)) {
> +    expandDivision(&I);
> +    return true;
> +  }
> +  return false;
> +}
> +
> +bool IntegerDivision::visitUDiv(BinaryOperator &I) {
> +  if (shouldExpandDivRem(I)) {
> +    expandDivision(&I);
> +    return true;
> +  }
> +  return false;
> +}
> +
> +bool IntegerDivision::visitSRem(BinaryOperator &I) {
> +  if (shouldExpandDivRem(I)) {
> +    expandRemainder(&I);
> +    return true;
> +  }
> +  return false;
> +}
> +
> +bool IntegerDivision::visitURem(BinaryOperator &I) {
> +  if (shouldExpandDivRem(I)) {
> +    expandRemainder(&I);
> +    return true;
> +  }
> +  return false;
> +}
> +
> +FunctionPass *llvm::createIntegerDivisionPass(const TargetMachine *TM) {
> +  return new IntegerDivision(TM);
> +}
> -- 
> 1.8.5.5
> 




More information about the llvm-commits mailing list