mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 15:10:33 +00:00
aa58b624e7
iteration. Instead, load the byte at the needle length, compare it directly, and save it to use in the lookup table of lengths we can skip forward. I also added an annotation to expect that the comparison fails so that the loop gets laid out contiguously without the call to memcpy (and the substantial register shuffling that the ABI requires of that call). Finally, because this behaves especially badly with a needle length of one (by calling memcmp with a zero length) special case that to directly call memchr, which is what we should have been doing anyways. This was motivated by the fact that there are a large number of test cases in 'check-llvm' where FileCheck's performance is dominated by calls to StringRef::find (in a release, no-asserts build). I'm working on patches to generally improve matters there, but this alone was worth a 12.5% improvement in one test case where FileCheck spent 92% of its time in this routine. I experimented a bunch with different minor variations on this theme, for example setting the pointer *at* the last byte and indexing backwards for the call to memcmp. That didn't improve anything on this version and seemed more complex. I also tried other things to make the loop flow more nicely and none worked. =/ It is a bit unfortunate, the generated code here remains pretty gross, but I don't see any obvious ways to improve it. At this point, most of my ideas would be really elaborate: 1) While the remainder of the string is long enough, we could load a 16-byte or 32-byte vector at the address of the last byte and use palignr to rotate that and check the first 15- or 31-bytes at the front of the next segment, essentially pre-loading the first several bytes of the next iteration so we could quickly detect a mismatch in those bytes without an additional memory access. Down side would be the code complexity, having a fallback loop, and likely misaligned vector load. Plus it would make the common case of the last byte not matching somewhat slower (need some extraction from a vector). 2) While we have space, we could do an aligned load of a 16- or 32-byte vector that *contains* the end byte, and use any peceding bytes to have a more precise "no" test, and any subsequent bytes could be saved for the next iteration. This remove any unaligned load penalty, but still requires us to pay the overhead of vector extraction for the cases where we didn't need to do anything other than load and compare the last byte. 3) Try to walk from the last byte in a way that is more friendly to cache and/or memory pre-fetcher considering we have to poke the last byte anyways. No idea if any of these are really worth pursuing though. They all seem somewhat unlikely to yield big wins in practice and to be a lot of work and complexity. So I settled here, which at least seems like a strict improvement over the previous version. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289373 91177308-0d34-0410-b5e6-96231b3b80d8 |
||
---|---|---|
.. | ||
Unix | ||
Windows | ||
Allocator.cpp | ||
APFloat.cpp | ||
APInt.cpp | ||
APSInt.cpp | ||
ARMBuildAttrs.cpp | ||
ARMWinEH.cpp | ||
Atomic.cpp | ||
BlockFrequency.cpp | ||
BranchProbability.cpp | ||
CachePruning.cpp | ||
Chrono.cpp | ||
circular_raw_ostream.cpp | ||
CMakeLists.txt | ||
COM.cpp | ||
CommandLine.cpp | ||
Compression.cpp | ||
ConvertUTF.cpp | ||
ConvertUTFWrapper.cpp | ||
COPYRIGHT.regex | ||
CrashRecoveryContext.cpp | ||
DAGDeltaAlgorithm.cpp | ||
DataExtractor.cpp | ||
Debug.cpp | ||
DeltaAlgorithm.cpp | ||
Dwarf.cpp | ||
DynamicLibrary.cpp | ||
Errno.cpp | ||
Error.cpp | ||
ErrorHandling.cpp | ||
FileOutputBuffer.cpp | ||
FileUtilities.cpp | ||
FoldingSet.cpp | ||
FormattedStream.cpp | ||
FormatVariadic.cpp | ||
GraphWriter.cpp | ||
Hashing.cpp | ||
Host.cpp | ||
IntEqClasses.cpp | ||
IntervalMap.cpp | ||
IntrusiveRefCntPtr.cpp | ||
JamCRC.cpp | ||
LEB128.cpp | ||
LineIterator.cpp | ||
LLVMBuild.txt | ||
Locale.cpp | ||
LockFileManager.cpp | ||
ManagedStatic.cpp | ||
MathExtras.cpp | ||
MD5.cpp | ||
Memory.cpp | ||
MemoryBuffer.cpp | ||
Mutex.cpp | ||
NativeFormatting.cpp | ||
Options.cpp | ||
Path.cpp | ||
PluginLoader.cpp | ||
PrettyStackTrace.cpp | ||
Process.cpp | ||
Program.cpp | ||
RandomNumberGenerator.cpp | ||
raw_os_ostream.cpp | ||
raw_ostream.cpp | ||
README.txt.system | ||
regcclass.h | ||
regcname.h | ||
regcomp.c | ||
regengine.inc | ||
regerror.c | ||
regex2.h | ||
regex_impl.h | ||
Regex.cpp | ||
regexec.c | ||
regfree.c | ||
regstrlcpy.c | ||
regutils.h | ||
RWMutex.cpp | ||
ScaledNumber.cpp | ||
ScopedPrinter.cpp | ||
SearchForAddressOfSpecialSymbol.cpp | ||
SHA1.cpp | ||
Signals.cpp | ||
SmallPtrSet.cpp | ||
SmallVector.cpp | ||
SourceMgr.cpp | ||
SpecialCaseList.cpp | ||
Statistic.cpp | ||
StringExtras.cpp | ||
StringMap.cpp | ||
StringPool.cpp | ||
StringRef.cpp | ||
StringSaver.cpp | ||
SystemUtils.cpp | ||
TargetParser.cpp | ||
TargetRegistry.cpp | ||
Threading.cpp | ||
ThreadLocal.cpp | ||
ThreadPool.cpp | ||
Timer.cpp | ||
ToolOutputFile.cpp | ||
TrigramIndex.cpp | ||
Triple.cpp | ||
Twine.cpp | ||
Unicode.cpp | ||
Valgrind.cpp | ||
Watchdog.cpp | ||
xxhash.cpp | ||
YAMLParser.cpp | ||
YAMLTraits.cpp |
Design Of lib/System ==================== The software in this directory is designed to completely shield LLVM from any and all operating system specific functionality. It is not intended to be a complete operating system wrapper (such as ACE), but only to provide the functionality necessary to support LLVM. The software located here, of necessity, has very specific and stringent design rules. Violation of these rules means that cracks in the shield could form and the primary goal of the library is defeated. By consistently using this library, LLVM becomes more easily ported to new platforms since the only thing requiring porting is this library. Complete documentation for the library can be found in the file: llvm/docs/SystemLibrary.html or at this URL: http://llvm.org/docs/SystemLibrary.html While we recommend that you read the more detailed documentation, for the impatient, here's a high level summary of the library's requirements. 1. No system header files are to be exposed through the interface. 2. Std C++ and Std C header files are okay to be exposed through the interface. 3. No exposed system-specific functions. 4. No exposed system-specific data. 5. Data in lib/System classes must use only simple C++ intrinsic types. 6. Errors are handled by returning "true" and setting an optional std::string 7. Library must not throw any exceptions, period. 8. Interface functions must not have throw() specifications. 9. No duplicate function impementations are permitted within an operating system class. To accomplish these requirements, the library has numerous design criteria that must be satisfied. Here's a high level summary of the library's design criteria: 1. No unused functionality (only what LLVM needs) 2. High-Level Interfaces 3. Use Opaque Classes 4. Common Implementations 5. Multiple Implementations 6. Minimize Memory Allocation 7. No Virtual Methods