diff options
| author | Stanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com> | 2017-03-17 17:13:41 +0000 | 
|---|---|---|
| committer | Stanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com> | 2017-03-17 17:13:41 +0000 | 
| commit | ee2dd785f617101cc7f02e7fb192761154867327 (patch) | |
| tree | 254df54eb1c8484d84e8e269a4c10d7371d539c0 /llvm/lib/Transforms | |
| parent | d06b025c9c7e4f0518ac9c5221f25c879c004c07 (diff) | |
| download | bcm5719-llvm-ee2dd785f617101cc7f02e7fb192761154867327.tar.gz bcm5719-llvm-ee2dd785f617101cc7f02e7fb192761154867327.zip | |
Only unswitch loops with uniform conditions
Loop unswitching can be extremely harmful for a SIMT target. In case
if hoisted condition is not uniform a SIMT machine will execute both
clones of a loop sequentially. Therefor LoopUnswitch checks if the
condition is non-divergent.
Since DivergenceAnalysis adds an expensive PostDominatorTree analysis
not needed for non-SIMT targets a new option is added to avoid unneded
analysis initialization. The method getAnalysisUsage is called when
TargetTransformInfo is not yet available and we cannot use it here.
For that reason a new field DivergentTarget is added to PassManagerBuilder
to control the behavior and set this field from a target.
Differential Revision: https://reviews.llvm.org/D30796
llvm-svn: 298104
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/IPO/PassManagerBuilder.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopUnswitch.cpp | 23 | 
2 files changed, 22 insertions, 6 deletions
| diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp index c3acd9ff30d..842f3958284 100644 --- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -168,6 +168,7 @@ PassManagerBuilder::PassManagerBuilder() {      PGOInstrUse = RunPGOInstrUse;      PrepareForThinLTO = EnablePrepareForThinLTO;      PerformThinLTO = false; +    DivergentTarget = false;  }  PassManagerBuilder::~PassManagerBuilder() { @@ -307,7 +308,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(    // Rotate Loop - disable header duplication at -Oz    MPM.add(createLoopRotatePass(SizeLevel == 2 ? 0 : -1));    MPM.add(createLICMPass());                  // Hoist loop invariants -  MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3)); +  MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3, DivergentTarget));    MPM.add(createCFGSimplificationPass());    addInstructionCombiningPass(MPM);    MPM.add(createIndVarSimplifyPass());        // Canonicalize indvars @@ -588,7 +589,7 @@ void PassManagerBuilder::populateModulePassManager(      MPM.add(createCorrelatedValuePropagationPass());      addInstructionCombiningPass(MPM);      MPM.add(createLICMPass()); -    MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3)); +    MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3, DivergentTarget));      MPM.add(createCFGSimplificationPass());      addInstructionCombiningPass(MPM);    } diff --git a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp index a670c6ed692..fe4161ac948 100644 --- a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -33,6 +33,7 @@  #include "llvm/Analysis/GlobalsModRef.h"  #include "llvm/Analysis/AssumptionCache.h"  #include "llvm/Analysis/CodeMetrics.h" +#include "llvm/Analysis/DivergenceAnalysis.h"  #include "llvm/Analysis/InstructionSimplify.h"  #include "llvm/Analysis/LoopInfo.h"  #include "llvm/Analysis/LoopPass.h" @@ -180,12 +181,14 @@ namespace {      // NewBlocks contained cloned copy of basic blocks from LoopBlocks.      std::vector<BasicBlock*> NewBlocks; +    bool hasBranchDivergence; +    public:      static char ID; // Pass ID, replacement for typeid -    explicit LoopUnswitch(bool Os = false) : +    explicit LoopUnswitch(bool Os = false, bool hasBranchDivergence = false) :        LoopPass(ID), OptimizeForSize(Os), redoLoop(false),        currentLoop(nullptr), DT(nullptr), loopHeader(nullptr), -      loopPreheader(nullptr) { +      loopPreheader(nullptr), hasBranchDivergence(hasBranchDivergence) {          initializeLoopUnswitchPass(*PassRegistry::getPassRegistry());        } @@ -198,6 +201,8 @@ namespace {      void getAnalysisUsage(AnalysisUsage &AU) const override {        AU.addRequired<AssumptionCacheTracker>();        AU.addRequired<TargetTransformInfoWrapperPass>(); +      if (hasBranchDivergence) +        AU.addRequired<DivergenceAnalysis>();        getLoopAnalysisUsage(AU);      } @@ -367,11 +372,12 @@ INITIALIZE_PASS_BEGIN(LoopUnswitch, "loop-unswitch", "Unswitch loops",  INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)  INITIALIZE_PASS_DEPENDENCY(LoopPass)  INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DivergenceAnalysis)  INITIALIZE_PASS_END(LoopUnswitch, "loop-unswitch", "Unswitch loops",                        false, false) -Pass *llvm::createLoopUnswitchPass(bool Os) { -  return new LoopUnswitch(Os); +Pass *llvm::createLoopUnswitchPass(bool Os, bool hasBranchDivergence) { +  return new LoopUnswitch(Os, hasBranchDivergence);  }  /// Operator chain lattice. @@ -808,6 +814,15 @@ bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val,                   << ". Cost too high.\n");      return false;    } +  if (hasBranchDivergence && +      getAnalysis<DivergenceAnalysis>().isDivergent(LoopCond)) { +    DEBUG(dbgs() << "NOT unswitching loop %" +                 << currentLoop->getHeader()->getName() +                 << " at non-trivial condition '" << *Val +                 << "' == " << *LoopCond << "\n" +                 << ". Condition is divergent.\n"); +    return false; +  }    UnswitchNontrivialCondition(LoopCond, Val, currentLoop, TI);    return true; | 

