Przeglądaj źródła

Enable copy-in copy-out for lib profile. (#2858)

TODO: enable code to avoid the copy.
Xiang Li 5 lat temu
rodzic
commit
eb4a703eb0

+ 4 - 0
lib/HLSL/HLLegalizeParameter.cpp

@@ -229,6 +229,10 @@ void ParameterCopyInCopyOut(hlsl::HLModule &HLM) {
 
 bool HLLegalizeParameter::runOnModule(Module &M) {
   HLModule &HLM = M.GetOrCreateHLModule();
+  // TODO: enable avoid copy for lib profile.
+  if (HLM.GetShaderModel()->IsLib())
+    return false;
+
   auto &typeSys = HLM.GetTypeSystem();
   const DataLayout &DL = M.getDataLayout();
 

+ 28 - 26
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -5479,32 +5479,34 @@ void CGMSHLSLRuntime::EmitHLSLOutParamConversionInit(
       argLV = CGF.EmitLValue(Arg);
       if (argLV.isSimple())
         argAddr = argLV.getAddress();
-      // When there's argument need to lower like buffer/cbuffer load, need to
-      // copy to let the lower not happen on argument when calle is noinline or
-      // extern functions. Will do it in HLLegalizeParameter after known which
-      // functions are extern but before inline.
-      bool bConstGlobal = false;
-      Value *Ptr = argAddr;
-      while (GEPOperator *GEP = dyn_cast_or_null<GEPOperator>(Ptr)) {
-        Ptr = GEP->getPointerOperand();
-      }
-      if (GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(Ptr)) {
-        bConstGlobal = m_ConstVarAnnotationMap.count(GV) | GV->isConstant();
-      }
-
-      // Skip copy-in copy-out when safe.
-      // The unsafe case will be global variable alias with parameter.
-      // Then global variable is updated in the function, the parameter will
-      // be updated silently. For non global variable or constant global
-      // variable, it should be safe.
-      if (argAddr &&
-          (isa<AllocaInst>(Ptr) || isa<Argument>(Ptr) || bConstGlobal)) {
-        llvm::Type *ToTy = CGF.ConvertType(ParamTy.getNonReferenceType());
-        if (argAddr->getType()->getPointerElementType() == ToTy &&
-            // Check clang Type for case like int cast to unsigned.
-            ParamTy.getNonReferenceType().getCanonicalType().getTypePtr() ==
-                Arg->getType().getCanonicalType().getTypePtr())
-          continue;
+      // TODO: enable avoid copy for lib profile.
+      if (!m_bIsLib) {
+        // When there's argument need to lower like buffer/cbuffer load, need to
+        // copy to let the lower not happen on argument when calle is noinline
+        // or extern functions. Will do it in HLLegalizeParameter after known
+        // which functions are extern but before inline.
+        bool bConstGlobal = false;
+        Value *Ptr = argAddr;
+        while (GEPOperator *GEP = dyn_cast_or_null<GEPOperator>(Ptr)) {
+          Ptr = GEP->getPointerOperand();
+        }
+        if (GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(Ptr)) {
+          bConstGlobal = m_ConstVarAnnotationMap.count(GV) | GV->isConstant();
+        }
+        // Skip copy-in copy-out when safe.
+        // The unsafe case will be global variable alias with parameter.
+        // Then global variable is updated in the function, the parameter will
+        // be updated silently. For non global variable or constant global
+        // variable, it should be safe.
+        if (argAddr &&
+            (isa<AllocaInst>(Ptr) || isa<Argument>(Ptr) || bConstGlobal)) {
+          llvm::Type *ToTy = CGF.ConvertType(ParamTy.getNonReferenceType());
+          if (argAddr->getType()->getPointerElementType() == ToTy &&
+              // Check clang Type for case like int cast to unsigned.
+              ParamTy.getNonReferenceType().getCanonicalType().getTypePtr() ==
+                  Arg->getType().getCanonicalType().getTypePtr())
+            continue;
+        }
       }
       argType = argLV.getType();  // TBD: Can this be different than Arg->getType()?
       argAlignment = argLV.getAlignment();

+ 2 - 3
tools/clang/test/HLSLFileCheck/shader_targets/library/lib_arg_flatten/lib_empty_struct_arg.hlsl

@@ -2,10 +2,9 @@
 
 // Make sure calls with empty struct params are well-behaved
 
-// CHECK: define float @"\01?test2@@YAMUT@@@Z"(%struct.T* %[[t:.*]]) #0 {
+// CHECK: %[[alloca:.*]] = alloca %struct.T
 // CHECK-NOT:memcpy
-// Copy from t is a no-op, no code should be generated
-// CHECK: call float @"\01?test@@YAMUT@@@Z"(%struct.T* %[[t]])
+// CHECK-NEXT: call float @"\01?test@@YAMUT@@@Z"(%struct.T* nonnull %[[alloca]])
 
 struct T {
 };