Skip to content

Commit dc5949e

Browse files
authored
Pull ReplaceDisassemblyText out of DXCTestUtils.cpp (microsoft#4687)
ReplaceDisassemblyText dependency on llvm removed in the case that a regex is unnecessary to replace text in the disassembly.
1 parent 1eea545 commit dc5949e

File tree

5 files changed

+105
-80
lines changed

5 files changed

+105
-80
lines changed

include/dxc/DxilContainer/DxilContainer.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,9 @@
2020
#include "dxc/Support/WinAdapter.h"
2121

2222
struct IDxcContainerReflection;
23-
namespace llvm { class Module; }
2423

2524
namespace hlsl {
2625

27-
class AbstractMemoryStream;
28-
class RootSignatureHandle;
29-
class DxilModule;
30-
3126
#pragma pack(push, 1)
3227

3328
static const size_t DxilContainerHashSize = 16;

include/dxc/Test/DxcTestUtils.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,17 @@ std::string DisassembleProgram(dxc::DxcDllSupport &dllSupport, IDxcBlob *pProgra
175175
void SplitPassList(LPWSTR pPassesBuffer, std::vector<LPCWSTR> &passes);
176176
void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, UINT32 codePoint, _Outptr_ IDxcBlob **ppBlob);
177177
void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, UINT32 codePoint, _Outptr_ IDxcBlobEncoding **ppBlob);
178-
void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors, llvm::ArrayRef<LPCSTR> pReplacements,
179-
bool bRegex, std::string& disassembly);
180-
void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors, llvm::ArrayRef<LPCSTR> pReplacements,
181-
_Outptr_ IDxcBlob **pBlob, bool bRegex, std::string& disassembly, dxc::DxcDllSupport &dllSupport);
178+
void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors,
179+
llvm::ArrayRef<LPCSTR> pReplacements, bool bRegex,
180+
std::string &disassembly);
181+
void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors,
182+
llvm::ArrayRef<LPCSTR> pReplacements,
183+
_Outptr_ IDxcBlob **pBlob, bool bRegex,
184+
std::string &disassembly,
185+
dxc::DxcDllSupport &dllSupport);
186+
void ReplaceDisassemblyTextWithRegex(llvm::ArrayRef<LPCSTR> pLookFors,
187+
llvm::ArrayRef<LPCSTR> pReplacements,
188+
std::string &disassembly);
182189
void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, _Outptr_ IDxcBlob **ppBlob);
183190
void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, _Outptr_ IDxcBlobEncoding **ppBlob);
184191
void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const char *pVal, _Outptr_ IDxcBlobEncoding **ppBlob);

include/dxc/Test/HlslTestUtils.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,46 @@ inline bool CompareHalfEpsilon(const uint16_t &fsrc, const uint16_t &fref, float
511511
return std::abs(src_f32-ref_f32) < epsilon;
512512
}
513513

514+
515+
inline void ReplaceDisassemblyTextWithoutRegex(const std::vector<std::string> &lookFors,
516+
const std::vector<std::string> &replacements,
517+
std::string &disassembly) {
518+
for (unsigned i = 0; i < lookFors.size(); ++i) {
519+
520+
bool bOptional = false;
521+
522+
bool found = false;
523+
size_t pos = 0;
524+
LPCSTR pLookFor = lookFors[i].data();
525+
size_t lookForLen = lookFors[i].size();
526+
if (pLookFor[0] == '?') {
527+
bOptional = true;
528+
pLookFor++;
529+
lookForLen--;
530+
}
531+
if (!pLookFor || !*pLookFor) {
532+
continue;
533+
}
534+
535+
for (;;) {
536+
pos = disassembly.find(pLookFor, pos);
537+
if (pos == std::string::npos)
538+
break;
539+
found = true; // at least once
540+
disassembly.replace(pos, lookForLen, replacements[i]);
541+
pos += replacements[i].size();
542+
}
543+
if (!bOptional) {
544+
if (!found) {
545+
WEX::Logging::Log::Comment(WEX::Common::String().Format(
546+
L"String not found: '%S' in text:\r\n%.*S", pLookFor,
547+
(unsigned)disassembly.size(), disassembly.data()));
548+
}
549+
VERIFY_IS_TRUE(found);
550+
}
551+
}
552+
}
553+
514554
inline bool CompareHalfRelativeEpsilon(const uint16_t &fsrc, const uint16_t &fref, int nRelativeExp) {
515555
return CompareHalfULP(fsrc, fref, (float)(10 - nRelativeExp));
516556
}

tools/clang/unittests/HLSL/ExecutionTest.cpp

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11351,36 +11351,20 @@ TEST_F(ExecutionTest, QuadAnyAll) {
1135111351

1135211352
// Copies input strings to local storage, so it doesn't rely on lifetime of input string pointers.
1135311353
st::ShaderOpTest::TShaderCallbackFn MakeShaderReplacementCallback(
11354-
llvm::ArrayRef<LPCWSTR> dxcArgs,
11355-
llvm::ArrayRef<LPCSTR> LookFors,
11356-
llvm::ArrayRef<LPCSTR> Replacements,
11354+
std::vector<std::wstring> dxcArgs, std::vector<std::string> lookFors,
11355+
std::vector<std::string> replacements,
1135711356
dxc::DxcDllSupport &dllSupport) {
11358-
// place ArrayRef arguments in std::vector locals, and copy them by value into the callback function lambda
11359-
std::vector<std::wstring> ArgsStorage(dxcArgs.size());
11360-
for (unsigned i = 0; i < dxcArgs.size(); ++i)
11361-
ArgsStorage[i] = dxcArgs[i];
11362-
std::vector<std::string> LookForsStorage(LookFors.size());
11363-
for (unsigned i = 0; i < LookFors.size(); ++i)
11364-
LookForsStorage[i] = LookFors[i];
11365-
std::vector<std::string> ReplacementsStorage(Replacements.size());
11366-
for (unsigned i = 0; i < Replacements.size(); ++i)
11367-
ReplacementsStorage[i] = Replacements[i];
11357+
1136811358
auto ShaderInitFn =
11369-
[ArgsStorage, LookForsStorage, ReplacementsStorage, &dllSupport]
11359+
[dxcArgs, lookFors, replacements, &dllSupport]
1137011360
(LPCSTR Name, LPCSTR pText, IDxcBlob **ppShaderBlob, st::ShaderOp *pShaderOp) {
1137111361

1137211362
UNREFERENCED_PARAMETER(pShaderOp);
1137311363
UNREFERENCED_PARAMETER(Name);
1137411364
// Create pointer vectors from local storage to supply API needs
11375-
std::vector<LPCWSTR> Args(ArgsStorage.size());
11376-
for (unsigned i = 0; i < ArgsStorage.size(); ++i)
11377-
Args[i] = ArgsStorage[i].c_str();
11378-
std::vector<LPCSTR> LookFors(LookForsStorage.size());
11379-
for (unsigned i = 0; i < LookForsStorage.size(); ++i)
11380-
LookFors[i] = LookForsStorage[i].c_str();
11381-
std::vector<LPCSTR> Replacements(ReplacementsStorage.size());
11382-
for (unsigned i = 0; i < ReplacementsStorage.size(); ++i)
11383-
Replacements[i] = ReplacementsStorage[i].c_str();
11365+
std::vector<LPCWSTR> Args(dxcArgs.size());
11366+
for (unsigned i = 0; i < dxcArgs.size(); ++i)
11367+
Args[i] = dxcArgs[i].c_str();
1138411368

1138511369
CComPtr<IDxcUtils> pUtils;
1138611370
VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcUtils, &pUtils));
@@ -11389,12 +11373,10 @@ st::ShaderOpTest::TShaderCallbackFn MakeShaderReplacementCallback(
1138911373
VerifyCompileOK(dllSupport, pText, L"cs_6_0", Args, &compiledShader);
1139011374
std::string disassembly = DisassembleProgram(dllSupport, compiledShader);
1139111375
// Replace op
11392-
ReplaceDisassemblyText(
11393-
LookFors,
11394-
Replacements,
11395-
/*bRegex*/false,
11376+
ReplaceDisassemblyTextWithoutRegex(lookFors, replacements,
1139611377
disassembly
1139711378
);
11379+
1139811380
// Wrap text in UTF8 blob
1139911381
// No need to copy, disassembly won't be changed again and will live as long as rewrittenDisassembly.
1140011382
// c_str() guarantees null termination; passing size + 1 to include it will create an IDxcBlobUtf8 without copying.

tools/clang/unittests/HLSLTestLib/DxcTestUtils.cpp

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ void AssembleToContainer(dxc::DxcDllSupport &dllSupport, IDxcBlob *pModule,
195195
CheckOperationSucceeded(pResult, pContainer);
196196
}
197197

198-
void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors,
198+
void ReplaceDisassemblyTextWithRegex(llvm::ArrayRef<LPCSTR> pLookFors,
199199
llvm::ArrayRef<LPCSTR> pReplacements,
200-
bool bRegex, std::string& disassembly) {
200+
std::string& disassembly) {
201201
for (unsigned i = 0; i < pLookFors.size(); ++i) {
202202
LPCSTR pLookFor = pLookFors[i];
203203
bool bOptional = false;
@@ -207,56 +207,57 @@ void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors,
207207
}
208208
LPCSTR pReplacement = pReplacements[i];
209209
if (pLookFor && *pLookFor) {
210-
if (bRegex) {
211-
llvm::Regex RE(pLookFor);
212-
std::string reErrors;
213-
if (!RE.isValid(reErrors)) {
210+
llvm::Regex RE(pLookFor);
211+
std::string reErrors;
212+
if (!RE.isValid(reErrors)) {
213+
WEX::Logging::Log::Comment(WEX::Common::String().Format(
214+
L"Regex errors:\r\n%.*S\r\nWhile compiling expression '%S'",
215+
(unsigned)reErrors.size(), reErrors.data(),
216+
pLookFor));
217+
}
218+
VERIFY_IS_TRUE(RE.isValid(reErrors));
219+
std::string replaced = RE.sub(pReplacement, disassembly, &reErrors);
220+
if (!bOptional) {
221+
if (!reErrors.empty()) {
214222
WEX::Logging::Log::Comment(WEX::Common::String().Format(
215-
L"Regex errors:\r\n%.*S\r\nWhile compiling expression '%S'",
223+
L"Regex errors:\r\n%.*S\r\nWhile searching for '%S' in text:\r\n%.*S",
216224
(unsigned)reErrors.size(), reErrors.data(),
217-
pLookFor));
218-
}
219-
VERIFY_IS_TRUE(RE.isValid(reErrors));
220-
std::string replaced = RE.sub(pReplacement, disassembly, &reErrors);
221-
if (!bOptional) {
222-
if (!reErrors.empty()) {
223-
WEX::Logging::Log::Comment(WEX::Common::String().Format(
224-
L"Regex errors:\r\n%.*S\r\nWhile searching for '%S' in text:\r\n%.*S",
225-
(unsigned)reErrors.size(), reErrors.data(),
226-
pLookFor,
227-
(unsigned)disassembly.size(), disassembly.data()));
228-
}
229-
VERIFY_ARE_NOT_EQUAL(disassembly, replaced);
230-
VERIFY_IS_TRUE(reErrors.empty());
231-
}
232-
disassembly = std::move(replaced);
233-
} else {
234-
bool found = false;
235-
size_t pos = 0;
236-
size_t lookForLen = strlen(pLookFor);
237-
size_t replaceLen = strlen(pReplacement);
238-
for (;;) {
239-
pos = disassembly.find(pLookFor, pos);
240-
if (pos == std::string::npos)
241-
break;
242-
found = true; // at least once
243-
disassembly.replace(pos, lookForLen, pReplacement);
244-
pos += replaceLen;
245-
}
246-
if (!bOptional) {
247-
if (!found) {
248-
WEX::Logging::Log::Comment(WEX::Common::String().Format(
249-
L"String not found: '%S' in text:\r\n%.*S",
250-
pLookFor,
251-
(unsigned)disassembly.size(), disassembly.data()));
252-
}
253-
VERIFY_IS_TRUE(found);
225+
pLookFor,
226+
(unsigned)disassembly.size(), disassembly.data()));
254227
}
228+
VERIFY_ARE_NOT_EQUAL(disassembly, replaced);
229+
VERIFY_IS_TRUE(reErrors.empty());
255230
}
231+
disassembly = std::move(replaced);
256232
}
257233
}
258234
}
259235

236+
void ConvertLLVMStringArrayToStringVector(llvm::ArrayRef<LPCSTR> a,
237+
std::vector<std::string> &ret) {
238+
ret.clear();
239+
ret.reserve(a.size());
240+
for (unsigned int i = 0; i < a.size(); i++) {
241+
ret.emplace_back(a[i]);
242+
}
243+
}
244+
245+
void ReplaceDisassemblyText(llvm::ArrayRef<LPCSTR> pLookFors,
246+
llvm::ArrayRef<LPCSTR> pReplacements, bool bRegex,
247+
std::string &disassembly) {
248+
if (bRegex) {
249+
ReplaceDisassemblyTextWithRegex(pLookFors, pReplacements, disassembly);
250+
}
251+
else {
252+
std::vector<std::string> pLookForStrs;
253+
ConvertLLVMStringArrayToStringVector(pLookFors, pLookForStrs);
254+
std::vector<std::string> pReplacementsStrs;
255+
ConvertLLVMStringArrayToStringVector(pReplacements, pReplacementsStrs);
256+
ReplaceDisassemblyTextWithoutRegex(pLookForStrs, pReplacementsStrs,
257+
disassembly);
258+
}
259+
}
260+
260261
///////////////////////////////////////////////////////////////////////////////
261262
// Helper functions to deal with passes.
262263

0 commit comments

Comments
 (0)