2
0
Эх сурвалжийг харах

Add hidden flag to disable optimization passes (#2962)

It can be helpful to disable an optimization pass or set of passes in
select circumstances. This adds the ability to disable the gvn pass
only, but introduces a way to disable various passes just by accepting
the chosen string to represent them in HLSLOptions and using the
DisablePasses values to determine when a pass needs to be left out in
PassManagerBuilder.
Greg Roth 5 жил өмнө
parent
commit
5f3ee4b904

+ 21 - 0
include/dxc/Support/HLSLOptimizationOptions.h

@@ -0,0 +1,21 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// HLSLOptimizationOptions.h                                                 //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Option defined related to optimization customization.                     //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+namespace hlsl {
+  // Optimizations that can be disabled
+  struct OptimizationOptions {
+    unsigned DisableGVN : 1;
+    unsigned Reserved : 31;
+  };
+}
+

+ 2 - 0
include/dxc/Support/HLSLOptions.h

@@ -18,6 +18,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Option/ArgList.h"
 #include "dxc/dxcapi.h"
+#include "dxc/Support/HLSLOptimizationOptions.h"
 #include "dxc/Support/SPIRVOptions.h"
 
 namespace llvm {
@@ -187,6 +188,7 @@ public:
   bool ResMayAlias = false; // OPT_res_may_alias
   unsigned long ValVerMajor = UINT_MAX, ValVerMinor = UINT_MAX; // OPT_validator_version
   unsigned ScanLimit = 0; // OPT_memdep_block_scan_limit
+  hlsl::OptimizationOptions DxcOptimizationOptions; // OPT_opt_disable
 
   // Rewriter Options
   RewriterOpts RWOpt;

+ 2 - 0
include/dxc/Support/HLSLOptions.td

@@ -156,6 +156,8 @@ def fno_honor_infinities : Flag<["-"], "fno-honor-infinities">, Group<hlsloptz_G
 def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<hlsloptz_Group>;
 def memdep_block_scan_limit : Separate<["-", "/"], "memdep-block-scan-limit">, Group<hlsloptz_Group>, Flags<[CoreOption, DriverOption, HelpHidden]>,
   HelpText<"The number of instructions to scan in a block in memory dependency analysis.">;
+def opt_disable : Separate<["-", "/"], "opt-disable">, Group<hlsloptz_Group>, Flags<[CoreOption, DriverOption, HelpHidden]>,
+  HelpText<"Disable this optimization.">;
 
 /*
 def fno_caret_diagnostics : Flag<["-"], "fno-caret-diagnostics">, Group<hlslcomp_Group>,

+ 2 - 0
include/llvm/Transforms/IPO/PassManagerBuilder.h

@@ -16,6 +16,7 @@
 #define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
 
 #include <vector>
+#include "dxc/Support/HLSLOptimizationOptions.h" // HLSL Change
 
 namespace hlsl {
   class HLSLExtensionsCodegenHelper;
@@ -131,6 +132,7 @@ public:
   hlsl::HLSLExtensionsCodegenHelper *HLSLExtensionsCodeGen = nullptr; // HLSL Change
   bool HLSLResMayAlias = false; // HLSL Change
   unsigned ScanLimit = 0; // HLSL Change
+  hlsl::OptimizationOptions HLSLOptimizationOptions = {0}; // HLSL Change
 
 private:
   /// ExtensionList - This is list of all of the extensions that are registered.

+ 8 - 0
lib/DxcSupport/HLSLOptions.cpp

@@ -492,6 +492,14 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   if (!limit.empty())
     opts.ScanLimit = std::stoul(std::string(limit));
 
+  opts.DxcOptimizationOptions = {0};
+  std::vector<std::string> DisabledOptimizations = Args.getAllArgValues(OPT_opt_disable);
+  for (std::string opt : DisabledOptimizations) {
+    llvm::StringRef gvn("gvn");
+    if (gvn.equals_lower(opt))
+      opts.DxcOptimizationOptions.DisableGVN = true;
+  }
+
   if (!opts.ForceRootSigVer.empty() && opts.ForceRootSigVer != "rootsig_1_0" &&
       opts.ForceRootSigVer != "rootsig_1_1") {
     errors << "Unsupported value '" << opts.ForceRootSigVer

+ 9 - 4
lib/Transforms/IPO/PassManagerBuilder.cpp

@@ -466,9 +466,13 @@ void PassManagerBuilder::populateModulePassManager(
   if (OptLevel > 1) {
     if (EnableMLSM)
       MPM.add(createMergedLoadStoreMotionPass()); // Merge ld/st in diamonds
-    MPM.add(createGVNPass(DisableGVNLoadPRE));  // Remove redundancies
-    if (!HLSLResMayAlias)
-      MPM.add(createDxilSimpleGVNHoistPass()); // HLSL Change - GVN hoist for code size.
+    // HLSL Change Begins
+    if (!(HLSLOptimizationOptions.DisableGVN)) {
+      MPM.add(createGVNPass(DisableGVNLoadPRE));  // Remove redundancies
+      if (!HLSLResMayAlias)
+        MPM.add(createDxilSimpleGVNHoistPass());
+    }
+    // HLSL Change Ends
   }
   // HLSL Change Begins.
   // HLSL don't allow memcpy and memset.
@@ -737,7 +741,8 @@ void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) {
   // PM.add(createLICMPass());                 // Hoist loop invariants.
   if (EnableMLSM)
     PM.add(createMergedLoadStoreMotionPass()); // Merge ld/st in diamonds.
-  PM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies.
+  if (!(HLSLOptimizationOptions.DisableGVN)) // HLSL Change
+    PM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies.
   PM.add(createMemCpyOptPass());            // Remove dead memcpys.
 
   // Nuke dead stores.

+ 3 - 0
tools/clang/include/clang/Frontend/CodeGenOptions.h

@@ -20,6 +20,7 @@
 #include <string>
 #include <vector>
 #include "dxc/HLSL/HLSLExtensionsCodegenHelper.h" // HLSL change
+#include "dxc/Support/HLSLOptimizationOptions.h" // HLSL Change
 #include "dxc/Support/SPIRVOptions.h" // SPIR-V Change
 
 namespace clang {
@@ -220,6 +221,8 @@ public:
   bool HLSLResMayAlias = false;
   /// Lookback scan limit for memory dependencies
   unsigned ScanLimit = 0;
+  /// Disabled optimization passes
+  hlsl::OptimizationOptions HLSLOptimizationOptions = {0};
   // HLSL Change Ends
 
   // SPIRV Change Starts

+ 1 - 0
tools/clang/lib/CodeGen/BackendUtil.cpp

@@ -327,6 +327,7 @@ void EmitAssemblyHelper::CreatePasses() {
   PMBuilder.HLSLExtensionsCodeGen = CodeGenOpts.HLSLExtensionsCodegen.get(); // HLSL Change
   PMBuilder.HLSLResMayAlias = CodeGenOpts.HLSLResMayAlias; // HLSL Change
   PMBuilder.ScanLimit = CodeGenOpts.ScanLimit; // HLSL Change
+  PMBuilder.HLSLOptimizationOptions = CodeGenOpts.HLSLOptimizationOptions; // HLSL Change
 
   PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
   PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;

+ 13 - 0
tools/clang/test/HLSLFileCheck/passes/hl/gvn/disablegvn.hlsl

@@ -0,0 +1,13 @@
+// RUN: %dxc -opt-disable gvn -T ps_6_0 %s | FileCheck %s
+
+// Simple test to verify disabling of gvn pass
+
+// Verify that GVN is disabled by the presence
+// of the second sin(), which GVN would have removed
+// CHECK: call float @dx.op.unary.f32
+// CHECK: call float @dx.op.unary.f32
+
+float main(float a : A) : SV_Target {
+  float res = sin(a);
+  return res + sin(a);
+}

+ 1 - 0
tools/clang/tools/dxcompiler/dxcompilerobj.cpp

@@ -1107,6 +1107,7 @@ public:
     compiler.getCodeGenOpts().HLSLAllowPreserveValues = Opts.AllowPreserveValues;
     compiler.getCodeGenOpts().HLSLResMayAlias = Opts.ResMayAlias;
     compiler.getCodeGenOpts().ScanLimit = Opts.ScanLimit;
+    compiler.getCodeGenOpts().HLSLOptimizationOptions = Opts.DxcOptimizationOptions;
     compiler.getCodeGenOpts().HLSLAllResourcesBound = Opts.AllResourcesBound;
     compiler.getCodeGenOpts().HLSLDefaultRowMajor = Opts.DefaultRowMajor;
     compiler.getCodeGenOpts().HLSLPreferControlFlow = Opts.PreferFlowControl;