소스 검색

Create pass for Lower static global into allocas. (#341)

Xiang Li 8 년 전
부모
커밋
4aba977775

+ 1 - 0
include/llvm/InitializePasses.h

@@ -253,6 +253,7 @@ void initializeSROA_SSAUpPass(PassRegistry&);
 void initializeSROA_HLSLPass(PassRegistry&);
 void initializeSROA_DT_HLSLPass(PassRegistry&);
 void initializeSROA_Parameter_HLSLPass(PassRegistry&);
+void initializeLowerStaticGlobalIntoAllocaPass(PassRegistry&);
 void initializeDynamicIndexingVectorToArrayPass(PassRegistry&);
 void initializeMultiDimArrayToOneDimArrayPass(PassRegistry&);
 void initializeResourceToHandlePass(PassRegistry&);

+ 8 - 0
include/llvm/Transforms/Scalar.h

@@ -122,6 +122,14 @@ void initializeSROA_DT_HLSLPass(PassRegistry&);
 //
 ModulePass *createSROA_Parameter_HLSL();
 void initializeSROA_Parameter_HLSLPass(PassRegistry&);
+//===----------------------------------------------------------------------===//
+//
+// LowerStaticGlobalIntoAlloca. Replace static globals with alloca if only used
+// in one function.
+//
+ModulePass *createLowerStaticGlobalIntoAlloca();
+void initializeLowerStaticGlobalIntoAllocaPass(PassRegistry&);
+
 //===----------------------------------------------------------------------===//
 //
 // DynamicIndexingVectorToArray 

+ 1 - 0
lib/HLSL/DxcOptimizer.cpp

@@ -121,6 +121,7 @@ HRESULT SetupRegistryPassForHLSL() {
     initializeLoopUnswitchPass(Registry);
     initializeLowerBitSetsPass(Registry);
     initializeLowerExpectIntrinsicPass(Registry);
+    initializeLowerStaticGlobalIntoAllocaPass(Registry);
     initializeMergeFunctionsPass(Registry);
     initializeMergedLoadStoreMotionPass(Registry);
     initializeMultiDimArrayToOneDimArrayPass(Registry);

+ 1 - 0
lib/Transforms/IPO/PassManagerBuilder.cpp

@@ -218,6 +218,7 @@ static void addHLSLPasses(bool HLSLHighLevel, bool NoOpt, hlsl::HLSLExtensionsCo
   MPM.add(createDynamicIndexingVectorToArrayPass(NoOpt));
 
   if (!NoOpt) {
+    MPM.add(createLowerStaticGlobalIntoAlloca());
     // mem2reg
     MPM.add(createPromoteMemoryToRegisterPass());
   }

+ 81 - 36
lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp

@@ -3954,24 +3954,6 @@ public:
       }
     }
 
-    // Lower static global into allocas.
-    staticGVs.clear();
-    for (GlobalVariable &GV : M.globals()) {
-      bool isStaticGlobal =
-          HLModule::IsStaticGlobal(&GV) &&
-          GV.getType()->getAddressSpace() == DXIL::kDefaultAddrSpace;
-      bool noInitializer =
-          !GV.hasInitializer() || isa<UndefValue>(GV.getInitializer());
-      if (isStaticGlobal && noInitializer) {
-        staticGVs.emplace_back(&GV);
-      }
-    }
-
-    const DataLayout &DL = M.getDataLayout();
-    for (GlobalVariable *GV : staticGVs) {
-      lowerStaticGlobalIntoAlloca(GV, DL);
-    }
-
     return true;
   }
 
@@ -4007,7 +3989,6 @@ private:
     unsigned startArgIndex, llvm::StringMap<Type *> &semanticTypeMap);
   bool hasDynamicVectorIndexing(Value *V);
   void flattenGlobal(GlobalVariable *GV);
-  void lowerStaticGlobalIntoAlloca(GlobalVariable *GV, const DataLayout &DL);
   /// DeadInsts - Keep track of instructions we have made dead, so that
   /// we can remove them after we are done working.
   SmallVector<Value *, 32> DeadInsts;
@@ -4148,23 +4129,6 @@ void SROA_Parameter_HLSL::flattenGlobal(GlobalVariable *GV) {
   }
 }
 
-void SROA_Parameter_HLSL::lowerStaticGlobalIntoAlloca(GlobalVariable *GV, const DataLayout &DL) {
-  DxilTypeSystem &typeSys = m_pHLModule->GetTypeSystem();
-  unsigned size = DL.getTypeAllocSize(GV->getType()->getElementType());
-  PointerStatus PS(size);
-  GV->removeDeadConstantUsers();
-  PS.analyzePointer(GV, PS, typeSys, /*bStructElt*/false);
-  // Make sure GV only used in one function.
-  if (PS.HasMultipleAccessingFunctions)
-    return;
-
-  Function *F = const_cast<Function*>(PS.AccessingFunction);
-  IRBuilder<> Builder(F->getEntryBlock().getFirstInsertionPt());
-  AllocaInst *AI = Builder.CreateAlloca(GV->getType()->getElementType());
-  ReplaceConstantWithInst(GV, AI, Builder);
-  GV->eraseFromParent();
-}
-
 static DxilFieldAnnotation &GetEltAnnotation(Type *Ty, unsigned idx, DxilFieldAnnotation &annotation, DxilTypeSystem &dxilTypeSys) {
   while (Ty->isArrayTy())
     Ty = Ty->getArrayElementType();
@@ -6038,6 +6002,87 @@ ModulePass *llvm::createSROA_Parameter_HLSL() {
   return new SROA_Parameter_HLSL();
 }
 
+//===----------------------------------------------------------------------===//
+// Lower static global into Alloca.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class LowerStaticGlobalIntoAlloca : public ModulePass {
+  HLModule *m_pHLModule;
+
+public:
+  static char ID; // Pass identification, replacement for typeid
+  explicit LowerStaticGlobalIntoAlloca() : ModulePass(ID) {}
+  const char *getPassName() const override { return "Lower static global into Alloca"; }
+
+  bool runOnModule(Module &M) override {
+    m_pHLModule = &M.GetOrCreateHLModule();
+
+    // Lower static global into allocas.
+    std::vector<GlobalVariable *> staticGVs;
+    for (GlobalVariable &GV : M.globals()) {
+      bool isStaticGlobal =
+          HLModule::IsStaticGlobal(&GV) &&
+          GV.getType()->getAddressSpace() == DXIL::kDefaultAddrSpace;
+
+      if (isStaticGlobal &&
+          !GV.getType()->getElementType()->isAggregateType()) {
+        staticGVs.emplace_back(&GV);
+      }
+    }
+    bool bUpdated = false;
+
+    const DataLayout &DL = M.getDataLayout();
+    for (GlobalVariable *GV : staticGVs) {
+      bUpdated |= lowerStaticGlobalIntoAlloca(GV, DL);
+    }
+
+    return bUpdated;
+  }
+
+private:
+  bool lowerStaticGlobalIntoAlloca(GlobalVariable *GV, const DataLayout &DL);
+};
+}
+
+bool LowerStaticGlobalIntoAlloca::lowerStaticGlobalIntoAlloca(GlobalVariable *GV, const DataLayout &DL) {
+  DxilTypeSystem &typeSys = m_pHLModule->GetTypeSystem();
+  unsigned size = DL.getTypeAllocSize(GV->getType()->getElementType());
+  PointerStatus PS(size);
+  GV->removeDeadConstantUsers();
+  PS.analyzePointer(GV, PS, typeSys, /*bStructElt*/ false);
+  bool NotStored = (PS.StoredType == PointerStatus::NotStored) ||
+                   (PS.StoredType == PointerStatus::InitializerStored);
+  // Make sure GV only used in one function.
+  // Skip GV which don't have store.
+  if (PS.HasMultipleAccessingFunctions || NotStored)
+    return false;
+
+  Function *F = const_cast<Function*>(PS.AccessingFunction);
+  IRBuilder<> Builder(F->getEntryBlock().getFirstInsertionPt());
+  AllocaInst *AI = Builder.CreateAlloca(GV->getType()->getElementType());
+
+  // Store initializer is exist.
+  if (GV->hasInitializer() && !isa<UndefValue>(GV->getInitializer())) {
+    Builder.CreateStore(GV->getInitializer(), GV);
+  }
+
+  ReplaceConstantWithInst(GV, AI, Builder);
+  GV->eraseFromParent();
+  return true;
+}
+
+char LowerStaticGlobalIntoAlloca::ID = 0;
+
+INITIALIZE_PASS(LowerStaticGlobalIntoAlloca, "static-global-to-alloca",
+  "Lower static global into Alloca", false,
+  false)
+
+// Public interface to the LowerStaticGlobalIntoAlloca pass
+ModulePass *llvm::createLowerStaticGlobalIntoAlloca() {
+  return new LowerStaticGlobalIntoAlloca();
+}
+
 //===----------------------------------------------------------------------===//
 // Lower one type to another type.
 //===----------------------------------------------------------------------===//

+ 24 - 0
tools/clang/test/CodeGenHLSL/static_matrix.hlsl

@@ -0,0 +1,24 @@
+// RUN: %dxc -E not_main -T ps_6_0 %s | FileCheck %s
+
+// Make sure internal global is removed.
+// CHECK-NOT:  = internal
+
+static float2x2 a;
+
+float2x2 b;
+
+float d;
+
+// Not use main as entry name to disable GlobalOpt.
+float4 not_main() : SV_TARGET
+{
+  a = b+2;
+  float c = 0;
+  // Make big number of instructions to disable gvn.
+  [unroll]
+  for (uint i=0;i<100;i++) {
+    c += sin(i+d);
+  }
+
+  return a - c;
+}

+ 5 - 0
tools/clang/unittests/HLSL/CompilerTest.cpp

@@ -641,6 +641,7 @@ public:
   TEST_METHOD(CodeGenStaticGlobals2)
   TEST_METHOD(CodeGenStaticGlobals3)
   TEST_METHOD(CodeGenStaticGlobals4)
+  TEST_METHOD(CodeGenStaticMatrix)
   TEST_METHOD(CodeGenStaticResource)
   TEST_METHOD(CodeGenStaticResource2)
   TEST_METHOD(CodeGenStruct_Buf1)
@@ -3320,6 +3321,10 @@ TEST_F(CompilerTest, CodeGenStaticGlobals4) {
   CodeGenTest(L"..\\CodeGenHLSL\\staticGlobals4.hlsl");
 }
 
+TEST_F(CompilerTest, CodeGenStaticMatrix) {
+  CodeGenTestCheck(L"..\\CodeGenHLSL\\static_matrix.hlsl");
+}
+
 TEST_F(CompilerTest, CodeGenStaticResource) {
   CodeGenTest(L"..\\CodeGenHLSL\\static_resource.hlsl");
 }

+ 1 - 0
utils/hct/hctdb.py

@@ -1242,6 +1242,7 @@ class db_dxil(object):
         add_pass('scalarrepl-param-hlsl', 'SROA_Parameter_HLSL', 'Scalar Replacement of Aggregates HLSL (parameters)', [])
         add_pass('scalarreplhlsl', 'SROA_DT_HLSL', 'Scalar Replacement of Aggregates HLSL (DT)', [])
         add_pass('scalarreplhlsl-ssa', 'SROA_SSAUp_HLSL', 'Scalar Replacement of Aggregates HLSL (SSAUp)', [])
+        add_pass('static-global-to-alloca', 'LowerStaticGlobalIntoAlloca', 'Lower static global into Alloca', [])
         add_pass('hlmatrixlower', 'HLMatrixLowerPass', 'HLSL High-Level Matrix Lower', [])
         add_pass('dce', 'DCE', 'Dead Code Elimination', [])
         add_pass('die', 'DeadInstElimination', 'Dead Instruction Elimination', [])