[PATCH] CodeGen: Add IntegerDivisionPass
Tom Stellard
tom at stellard.net
Wed Sep 24 11:36:39 PDT 2014
On Wed, Sep 24, 2014 at 11:19:47AM -0700, Michael Ilseman wrote:
> +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;
> +}
>
> You should have a bool for whether the code changed, and return that[1]. It’s probably worth building up a worklist of basic blocks up front, to avoid the repeated visiting of already-handled blocks. Also, we know that many of the blocks that are generated from division-expansion would not themselves have rem or div in them.
>
>
> +bool IntegerDivision::shouldExpandDivRem(const BinaryOperator &I) {
> + return TLI && TLI->shouldExpandDivRemInIR(I);
> +}
>
> You could do the TLI-is-not-null check in runOnFunction, which is a good place to bail early. Thereafter you can have an assert. I don’t know who would be using this pass normally, though.
>
> Otherwise the patch LGTM. What is your use case of wanting a full-fledged pass for this? If you have other codegen-prepare-like things to do to the IR, it seems suboptimal to do a pass over every instruction just for div/rem, at least from a low-latency compilation time perspective.
>
No specific reason for using a pass. Do you think it would be better to add
this to CodegenPrepare instead?
-Tom
>
> [1] http://llvm.org/docs/WritingAnLLVMPass.html#the-runonfunction-method
>
>
>
>
>
>
> On Sep 24, 2014, at 10:06 AM, Tom Stellard <tom at stellard.net> wrote:
>
> > On Tue, Sep 23, 2014 at 01:57:23PM -0700, Michael Ilseman wrote:
> >>
> >>> 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?
> >>
> >
> > These are leftover from a previous version of the patch. Here is an updated
> > patch with them removed.
> >
> > -Tom
> > <0001-CodeGen-Add-IntegerDivisionPass.patch>
>
More information about the llvm-commits
mailing list