[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