소스 검색

Pull ReplaceDisassemblyText out of DXCTestUtils.cpp (#4687)

ReplaceDisassemblyText dependency on llvm removed in the case that a regex is unnecessary to replace text in the disassembly.
Joshua Batista 3 년 전
부모
커밋
dc5949e167

+ 0 - 5
include/dxc/DxilContainer/DxilContainer.h

@@ -20,14 +20,9 @@
 #include "dxc/Support/WinAdapter.h"
 
 struct IDxcContainerReflection;
-namespace llvm { class Module; }
 
 namespace hlsl {
 
-class AbstractMemoryStream;
-class RootSignatureHandle;
-class DxilModule;
-
 #pragma pack(push, 1)
 
 static const size_t DxilContainerHashSize = 16;

+ 11 - 4
include/dxc/Test/DxcTestUtils.h

@@ -175,10 +175,17 @@ std::string DisassembleProgram(dxc::DxcDllSupport &dllSupport, IDxcBlob *pProgra
 void SplitPassList(LPWSTR pPassesBuffer, std::vector<LPCWSTR> &passes);
 void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, UINT32 codePoint, _Outptr_ IDxcBlob **ppBlob);
 void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, UINT32 codePoint, _Outptr_ IDxcBlobEncoding **ppBlob);
-void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors, llvm::ArrayRef<LPCSTR> pReplacements,
-                            bool bRegex, std::string& disassembly);
-void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors, llvm::ArrayRef<LPCSTR> pReplacements,
-                           _Outptr_ IDxcBlob **pBlob, bool bRegex, std::string& disassembly, dxc::DxcDllSupport &dllSupport);
+void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors,
+                            llvm::ArrayRef<LPCSTR> pReplacements, bool bRegex,
+                            std::string &disassembly);
+void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors,
+                            llvm::ArrayRef<LPCSTR> pReplacements,
+                            _Outptr_ IDxcBlob **pBlob, bool bRegex,
+                            std::string &disassembly,
+                            dxc::DxcDllSupport &dllSupport);
+void ReplaceDisassemblyTextWithRegex(llvm::ArrayRef<LPCSTR> pLookFors,
+                                     llvm::ArrayRef<LPCSTR> pReplacements,
+                                     std::string &disassembly);
 void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, _Outptr_ IDxcBlob **ppBlob);
 void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, _Outptr_ IDxcBlobEncoding **ppBlob);
 void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const char *pVal, _Outptr_ IDxcBlobEncoding **ppBlob);

+ 40 - 0
include/dxc/Test/HlslTestUtils.h

@@ -511,6 +511,46 @@ inline bool CompareHalfEpsilon(const uint16_t &fsrc, const uint16_t &fref, float
   return std::abs(src_f32-ref_f32) < epsilon;
 }
 
+
+inline void ReplaceDisassemblyTextWithoutRegex(const std::vector<std::string> &lookFors,
+                            const std::vector<std::string> &replacements,
+                            std::string &disassembly) {
+  for (unsigned i = 0; i < lookFors.size(); ++i) {
+    
+    bool bOptional = false;
+          
+    bool found = false;
+    size_t pos = 0;
+    LPCSTR pLookFor = lookFors[i].data();
+    size_t lookForLen = lookFors[i].size();
+    if (pLookFor[0] == '?') {
+      bOptional = true;
+      pLookFor++;
+      lookForLen--;
+    }
+    if (!pLookFor || !*pLookFor) {
+      continue;
+    }
+
+    for (;;) {
+      pos = disassembly.find(pLookFor, pos);
+      if (pos == std::string::npos)
+        break;
+      found = true; // at least once
+      disassembly.replace(pos, lookForLen, replacements[i]);
+      pos += replacements[i].size();
+    }
+    if (!bOptional) {
+      if (!found) {
+        WEX::Logging::Log::Comment(WEX::Common::String().Format(
+            L"String not found: '%S' in text:\r\n%.*S", pLookFor,
+            (unsigned)disassembly.size(), disassembly.data()));
+      }
+      VERIFY_IS_TRUE(found);        
+    }
+  }
+}
+
 inline bool CompareHalfRelativeEpsilon(const uint16_t &fsrc, const uint16_t &fref, int nRelativeExp) {
   return CompareHalfULP(fsrc, fref, (float)(10 - nRelativeExp));
 }

+ 9 - 27
tools/clang/unittests/HLSL/ExecutionTest.cpp

@@ -11351,36 +11351,20 @@ TEST_F(ExecutionTest, QuadAnyAll) {
 
 // Copies input strings to local storage, so it doesn't rely on lifetime of input string pointers.
 st::ShaderOpTest::TShaderCallbackFn MakeShaderReplacementCallback(
-    llvm::ArrayRef<LPCWSTR> dxcArgs,
-    llvm::ArrayRef<LPCSTR> LookFors,
-    llvm::ArrayRef<LPCSTR> Replacements,
+    std::vector<std::wstring> dxcArgs, std::vector<std::string> lookFors,
+    std::vector<std::string> replacements,
     dxc::DxcDllSupport &dllSupport) {
-  // place ArrayRef arguments in std::vector locals, and copy them by value into the callback function lambda
-  std::vector<std::wstring> ArgsStorage(dxcArgs.size());
-    for (unsigned i = 0; i < dxcArgs.size(); ++i)
-      ArgsStorage[i] = dxcArgs[i];
-  std::vector<std::string> LookForsStorage(LookFors.size());
-    for (unsigned i = 0; i < LookFors.size(); ++i)
-      LookForsStorage[i] = LookFors[i];
-  std::vector<std::string> ReplacementsStorage(Replacements.size());
-    for (unsigned i = 0; i < Replacements.size(); ++i)
-      ReplacementsStorage[i] = Replacements[i];
+  
   auto ShaderInitFn = 
-      [ArgsStorage, LookForsStorage, ReplacementsStorage, &dllSupport]
+      [dxcArgs, lookFors, replacements, &dllSupport]
       (LPCSTR Name, LPCSTR pText, IDxcBlob **ppShaderBlob, st::ShaderOp *pShaderOp) {
     
     UNREFERENCED_PARAMETER(pShaderOp);
     UNREFERENCED_PARAMETER(Name);
     // Create pointer vectors from local storage to supply API needs
-    std::vector<LPCWSTR> Args(ArgsStorage.size());
-    for (unsigned i = 0; i < ArgsStorage.size(); ++i)
-      Args[i] = ArgsStorage[i].c_str();
-    std::vector<LPCSTR> LookFors(LookForsStorage.size());
-    for (unsigned i = 0; i < LookForsStorage.size(); ++i)
-      LookFors[i] = LookForsStorage[i].c_str();
-    std::vector<LPCSTR> Replacements(ReplacementsStorage.size());
-    for (unsigned i = 0; i < ReplacementsStorage.size(); ++i)
-      Replacements[i] = ReplacementsStorage[i].c_str();
+    std::vector<LPCWSTR> Args(dxcArgs.size());
+    for (unsigned i = 0; i < dxcArgs.size(); ++i)
+      Args[i] = dxcArgs[i].c_str();    
 
     CComPtr<IDxcUtils> pUtils;
     VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcUtils, &pUtils));
@@ -11389,12 +11373,10 @@ st::ShaderOpTest::TShaderCallbackFn MakeShaderReplacementCallback(
     VerifyCompileOK(dllSupport, pText, L"cs_6_0", Args, &compiledShader);
     std::string disassembly = DisassembleProgram(dllSupport, compiledShader);
     // Replace op
-    ReplaceDisassemblyText(
-      LookFors,
-      Replacements,
-      /*bRegex*/false,
+    ReplaceDisassemblyTextWithoutRegex(lookFors, replacements,      
       disassembly
     );
+
     // Wrap text in UTF8 blob
     // No need to copy, disassembly won't be changed again and will live as long as rewrittenDisassembly.
     // c_str() guarantees null termination; passing size + 1 to include it will create an IDxcBlobUtf8 without copying.

+ 45 - 44
tools/clang/unittests/HLSLTestLib/DxcTestUtils.cpp

@@ -195,9 +195,9 @@ void AssembleToContainer(dxc::DxcDllSupport &dllSupport, IDxcBlob *pModule,
   CheckOperationSucceeded(pResult, pContainer);
 }
 
-void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors,
+void ReplaceDisassemblyTextWithRegex(llvm::ArrayRef<LPCSTR> pLookFors,
                 llvm::ArrayRef<LPCSTR> pReplacements,
-                bool bRegex, std::string& disassembly) {
+                std::string& disassembly) {
   for (unsigned i = 0; i < pLookFors.size(); ++i) {
     LPCSTR pLookFor = pLookFors[i];
     bool bOptional = false;
@@ -207,56 +207,57 @@ void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors,
     }
     LPCSTR pReplacement = pReplacements[i];
     if (pLookFor && *pLookFor) {
-      if (bRegex) {
-        llvm::Regex RE(pLookFor);
-        std::string reErrors;
-        if (!RE.isValid(reErrors)) {
+      llvm::Regex RE(pLookFor);
+      std::string reErrors;
+      if (!RE.isValid(reErrors)) {
+        WEX::Logging::Log::Comment(WEX::Common::String().Format(
+            L"Regex errors:\r\n%.*S\r\nWhile compiling expression '%S'",
+            (unsigned)reErrors.size(), reErrors.data(),
+            pLookFor));
+      }
+      VERIFY_IS_TRUE(RE.isValid(reErrors));
+      std::string replaced = RE.sub(pReplacement, disassembly, &reErrors);
+      if (!bOptional) {
+        if (!reErrors.empty()) {
           WEX::Logging::Log::Comment(WEX::Common::String().Format(
-              L"Regex errors:\r\n%.*S\r\nWhile compiling expression '%S'",
+              L"Regex errors:\r\n%.*S\r\nWhile searching for '%S' in text:\r\n%.*S",
               (unsigned)reErrors.size(), reErrors.data(),
-              pLookFor));
-        }
-        VERIFY_IS_TRUE(RE.isValid(reErrors));
-        std::string replaced = RE.sub(pReplacement, disassembly, &reErrors);
-        if (!bOptional) {
-          if (!reErrors.empty()) {
-            WEX::Logging::Log::Comment(WEX::Common::String().Format(
-                L"Regex errors:\r\n%.*S\r\nWhile searching for '%S' in text:\r\n%.*S",
-                (unsigned)reErrors.size(), reErrors.data(),
-                pLookFor,
-                (unsigned)disassembly.size(), disassembly.data()));
-          }
-          VERIFY_ARE_NOT_EQUAL(disassembly, replaced);
-          VERIFY_IS_TRUE(reErrors.empty());
-        }
-        disassembly = std::move(replaced);
-      } else {
-        bool found = false;
-        size_t pos = 0;
-        size_t lookForLen = strlen(pLookFor);
-        size_t replaceLen = strlen(pReplacement);
-        for (;;) {
-          pos = disassembly.find(pLookFor, pos);
-          if (pos == std::string::npos)
-            break;
-          found = true; // at least once
-          disassembly.replace(pos, lookForLen, pReplacement);
-          pos += replaceLen;
-        }
-        if (!bOptional) {
-          if (!found) {
-            WEX::Logging::Log::Comment(WEX::Common::String().Format(
-                L"String not found: '%S' in text:\r\n%.*S",
-                pLookFor,
-                (unsigned)disassembly.size(), disassembly.data()));
-          }
-          VERIFY_IS_TRUE(found);
+              pLookFor,
+              (unsigned)disassembly.size(), disassembly.data()));
         }
+        VERIFY_ARE_NOT_EQUAL(disassembly, replaced);
+        VERIFY_IS_TRUE(reErrors.empty());
       }
+      disassembly = std::move(replaced);
     }
   }
 }
 
+void ConvertLLVMStringArrayToStringVector(llvm::ArrayRef<LPCSTR> a,
+                                          std::vector<std::string> &ret) {
+  ret.clear();
+  ret.reserve(a.size());
+  for (unsigned int i = 0; i < a.size(); i++) {
+    ret.emplace_back(a[i]);
+  }
+}
+
+void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors,
+                            llvm::ArrayRef<LPCSTR> pReplacements, bool bRegex,
+                            std::string &disassembly) {
+  if (bRegex) {
+    ReplaceDisassemblyTextWithRegex(pLookFors, pReplacements, disassembly);
+  } 
+  else {
+    std::vector<std::string> pLookForStrs;
+    ConvertLLVMStringArrayToStringVector(pLookFors, pLookForStrs);
+    std::vector<std::string> pReplacementsStrs;
+    ConvertLLVMStringArrayToStringVector(pReplacements, pReplacementsStrs); 
+    ReplaceDisassemblyTextWithoutRegex(pLookForStrs, pReplacementsStrs,
+                                       disassembly);
+  }
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Helper functions to deal with passes.