From bigcheesegs at gmail.com Mon Dec 12 00:03:33 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Mon, 12 Dec 2011 06:03:33 -0000 Subject: [llvm-commits] [llvm] r146362 - in /llvm/trunk/lib/Support: PathV2.cpp Windows/PathV2.inc Windows/Program.inc Windows/Windows.h Message-ID: <20111212060334.09BF72A6C12C@llvm.org> Author: mspencer Date: Mon Dec 12 00:03:33 2011 New Revision: 146362 URL: http://llvm.org/viewvc/llvm-project?rev=146362&view=rev Log: Support/Windows: Cleanup scoped handles. Modified: llvm/trunk/lib/Support/PathV2.cpp llvm/trunk/lib/Support/Windows/PathV2.inc llvm/trunk/lib/Support/Windows/Program.inc llvm/trunk/lib/Support/Windows/Windows.h Modified: llvm/trunk/lib/Support/PathV2.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PathV2.cpp?rev=146362&r1=146361&r2=146362&view=diff ============================================================================== --- llvm/trunk/lib/Support/PathV2.cpp (original) +++ llvm/trunk/lib/Support/PathV2.cpp Mon Dec 12 00:03:33 2011 @@ -753,7 +753,9 @@ if (ft == file_type::directory_file) { // This code would be a lot better with exceptions ;/. error_code ec; - for (directory_iterator i(path, ec), e; i != e; i.increment(ec)) { + directory_iterator i(path, ec); + if (ec) return ec; + for (directory_iterator e; i != e; i.increment(ec)) { if (ec) return ec; file_status st; if (error_code ec = i->status(st)) return ec; Modified: llvm/trunk/lib/Support/Windows/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/PathV2.inc?rev=146362&r1=146361&r2=146362&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/PathV2.inc (original) +++ llvm/trunk/lib/Support/Windows/PathV2.inc Mon Dec 12 00:03:33 2011 @@ -17,7 +17,6 @@ //===----------------------------------------------------------------------===// #include "Windows.h" -#include #include #include #include @@ -112,14 +111,6 @@ return success; } - // Forwarder for ScopedHandle. - BOOL WINAPI CryptReleaseContext(HCRYPTPROV Provider) { - return ::CryptReleaseContext(Provider, 0); - } - - typedef ScopedHandle - ScopedCryptContext; bool is_separator(const wchar_t value) { switch (value) { case L'\\': @@ -372,7 +363,7 @@ if (error_code ec = UTF8ToUTF16(a, wide_a)) return ec; if (error_code ec = UTF8ToUTF16(b, wide_b)) return ec; - AutoHandle HandleB( + ScopedFileHandle HandleB( ::CreateFileW(wide_b.begin(), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, @@ -381,7 +372,7 @@ FILE_FLAG_BACKUP_SEMANTICS, 0)); - AutoHandle HandleA( + ScopedFileHandle HandleA( ::CreateFileW(wide_a.begin(), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, @@ -391,13 +382,11 @@ 0)); // If both handles are invalid, it's an error. - if (HandleA == INVALID_HANDLE_VALUE && - HandleB == INVALID_HANDLE_VALUE) + if (!HandleA && !HandleB) return windows_error(::GetLastError()); // If only one is invalid, it's false. - if (HandleA == INVALID_HANDLE_VALUE && - HandleB == INVALID_HANDLE_VALUE) { + if (!HandleA || !HandleB) { result = false; return success; } @@ -488,7 +477,7 @@ // Handle reparse points. if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { - AutoHandle h( + ScopedFileHandle h( ::CreateFileW(path_utf16.begin(), 0, // Attributes only. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, @@ -496,7 +485,7 @@ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); - if (h == INVALID_HANDLE_VALUE) + if (!h) goto handle_status_error; } Modified: llvm/trunk/lib/Support/Windows/Program.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Program.inc?rev=146362&r1=146361&r2=146362&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/Program.inc (original) +++ llvm/trunk/lib/Support/Windows/Program.inc Mon Dec 12 00:03:33 2011 @@ -299,14 +299,14 @@ Data_ = wpi; // Make sure these get closed no matter what. - AutoHandle hThread(pi.hThread); + ScopedCommonHandle hThread(pi.hThread); // Assign the process to a job if a memory limit is defined. - AutoHandle hJob(0); + ScopedJobHandle hJob; if (memoryLimit != 0) { hJob = CreateJobObject(0, 0); bool success = false; - if (hJob != 0) { + if (hJob) { JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli; memset(&jeli, 0, sizeof(jeli)); jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY; Modified: llvm/trunk/lib/Support/Windows/Windows.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Windows.h?rev=146362&r1=146361&r2=146362&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/Windows.h (original) +++ llvm/trunk/lib/Support/Windows/Windows.h Mon Dec 12 00:03:33 2011 @@ -26,6 +26,7 @@ #include "llvm/Config/config.h" // Get build system configuration settings #include +#include #include #include #include @@ -41,70 +42,99 @@ return true; } -class AutoHandle { - HANDLE handle; +template +class ScopedHandle { + typedef typename HandleTraits::handle_type handle_type; + handle_type Handle; + ScopedHandle(const ScopedHandle &other); // = delete; + void operator=(const ScopedHandle &other); // = delete; public: - AutoHandle(HANDLE h) : handle(h) {} + ScopedHandle() + : Handle(HandleTraits::GetInvalid()) {} + + explicit ScopedHandle(handle_type h) + : Handle(h) {} - ~AutoHandle() { - if (handle) - CloseHandle(handle); + ~ScopedHandle() { + if (HandleTraits::IsValid(Handle)) + HandleTraits::Close(Handle); } - operator HANDLE() { - return handle; + handle_type take() { + handle_type t = Handle; + Handle = HandleTraits::GetInvalid(); + return t; } - AutoHandle &operator=(HANDLE h) { - handle = h; + ScopedHandle &operator=(handle_type h) { + if (HandleTraits::IsValid(Handle)) + HandleTraits::Close(Handle); + Handle = h; return *this; } + + // True if Handle is valid. + operator bool() const { + return HandleTraits::IsValid(Handle) ? true : false; + } + + operator handle_type() const { + return Handle; + } }; -template -class ScopedHandle { - HandleType Handle; +struct CommonHandleTraits { + typedef HANDLE handle_type; -public: - ScopedHandle() : Handle(InvalidHandle) {} - ScopedHandle(HandleType handle) : Handle(handle) {} + static handle_type GetInvalid() { + return INVALID_HANDLE_VALUE; + } - ~ScopedHandle() { - if (Handle != HandleType(InvalidHandle)) - D(Handle); + static void Close(handle_type h) { + ::CloseHandle(h); } - HandleType take() { - HandleType temp = Handle; - Handle = HandleType(InvalidHandle); - return temp; + static bool IsValid(handle_type h) { + return h != GetInvalid(); } +}; - operator HandleType() const { return Handle; } +struct JobHandleTraits : CommonHandleTraits { + static handle_type GetInvalid() { + return NULL; + } +}; - ScopedHandle &operator=(HandleType handle) { - Handle = handle; - return *this; +struct CryptContextTraits : CommonHandleTraits { + typedef HCRYPTPROV handle_type; + + static handle_type GetInvalid() { + return 0; } - typedef void (*unspecified_bool_type)(); - static void unspecified_bool_true() {} + static void Close(handle_type h) { + ::CryptReleaseContext(h, 0); + } - // True if Handle is valid. - operator unspecified_bool_type() const { - return Handle == HandleType(InvalidHandle) ? 0 : unspecified_bool_true; + static bool IsValid(handle_type h) { + return h != GetInvalid(); } +}; - bool operator!() const { - return Handle == HandleType(InvalidHandle); +struct FindHandleTraits : CommonHandleTraits { + static void Close(handle_type h) { + ::FindClose(h); } }; -typedef ScopedHandle - ScopedFindHandle; +struct FileHandleTraits : CommonHandleTraits {}; + +typedef ScopedHandle ScopedCommonHandle; +typedef ScopedHandle ScopedFileHandle; +typedef ScopedHandle ScopedCryptContext; +typedef ScopedHandle ScopedFindHandle; +typedef ScopedHandle ScopedJobHandle; namespace llvm { template From bigcheesegs at gmail.com Mon Dec 12 00:04:02 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Mon, 12 Dec 2011 06:04:02 -0000 Subject: [llvm-commits] [llvm] r146363 - in /llvm/trunk: include/llvm/Support/FileSystem.h lib/Support/Unix/PathV2.inc lib/Support/Windows/PathV2.inc lib/Support/Windows/Windows.h unittests/Support/Path.cpp Message-ID: <20111212060402.62D332A6C12C@llvm.org> Author: mspencer Date: Mon Dec 12 00:04:01 2011 New Revision: 146363 URL: http://llvm.org/viewvc/llvm-project?rev=146363&view=rev Log: Support/FileSystem: Implement canonicalize. Modified: llvm/trunk/include/llvm/Support/FileSystem.h llvm/trunk/lib/Support/Unix/PathV2.inc llvm/trunk/lib/Support/Windows/PathV2.inc llvm/trunk/lib/Support/Windows/Windows.h llvm/trunk/unittests/Support/Path.cpp Modified: llvm/trunk/include/llvm/Support/FileSystem.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/FileSystem.h?rev=146363&r1=146362&r2=146363&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/FileSystem.h (original) +++ llvm/trunk/include/llvm/Support/FileSystem.h Mon Dec 12 00:04:01 2011 @@ -370,8 +370,12 @@ /// @brief Canonicalize path. /// -/// Sets result to the file system's idea of what path is. The result is always -/// absolute and has the same capitalization as the file system. +/// Sets result to the file system's idea of what path is. Path must be +/// absolute. The result has the same case as the file system. +/// +/// Example: Give a file system with "C:\a\b\c\file.txt". +/// +/// C:\A\b\C\fIlE.TxT => C:\a\b\c\file.txt /// /// @param path Input path. /// @param result Set to the canonicalized version of \a path. Modified: llvm/trunk/lib/Support/Unix/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/PathV2.inc?rev=146363&r1=146362&r2=146363&view=diff ============================================================================== --- llvm/trunk/lib/Support/Unix/PathV2.inc (original) +++ llvm/trunk/lib/Support/Unix/PathV2.inc Mon Dec 12 00:04:01 2011 @@ -439,6 +439,13 @@ return success; } +error_code canonicalize(const Twine &path, SmallVectorImpl &result) { + // Paths are already canonicalized on posix systems. + assert(path::is_absolute(path) && "path must be absolute!"); + path.toVector(result); + return success; +} + error_code detail::directory_iterator_construct(detail::DirIterState &it, StringRef path){ SmallString<128> path_null(path); Modified: llvm/trunk/lib/Support/Windows/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/PathV2.inc?rev=146363&r1=146362&r2=146363&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/PathV2.inc (original) +++ llvm/trunk/lib/Support/Windows/PathV2.inc Mon Dec 12 00:04:01 2011 @@ -638,6 +638,44 @@ return success; } +error_code canonicalize(const Twine &path, SmallVectorImpl &result) { + assert(path::is_absolute(path) && "path must be absolute!"); + SmallString<128> path_storage; + StringRef p = path.toStringRef(path_storage); + SmallVector path_utf16; + result.set_size(0); + + // Convert path to UTF-16. + if (error_code ec = UTF8ToUTF16(p, path_utf16)) + return ec; + + DWORD size = ::GetShortPathNameW(c_str(path_utf16), NULL, 0); + SmallVector short_path; + short_path.reserve(size + 1); + size = ::GetShortPathNameW( c_str(path_utf16) + , short_path.data() + , short_path.capacity()); + if (!size) + return windows_error(::GetLastError()); + + short_path.set_size(size); + + size = ::GetLongPathNameW(c_str(short_path), NULL, 0); + path_utf16.reserve(size + 1); + size = ::GetLongPathNameW( c_str(short_path) + , path_utf16.data() + , path_utf16.capacity()); + if (!size) + return windows_error(::GetLastError()); + + path_utf16.set_size(size); + + if (error_code ec = UTF16ToUTF8(path_utf16.data(), path_utf16.size(), result)) + return ec; + + return success; +} + error_code get_magic(const Twine &path, uint32_t len, SmallVectorImpl &result) { SmallString<128> path_storage; Modified: llvm/trunk/lib/Support/Windows/Windows.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Windows.h?rev=146363&r1=146362&r2=146363&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/Windows.h (original) +++ llvm/trunk/lib/Support/Windows/Windows.h Mon Dec 12 00:04:01 2011 @@ -128,6 +128,24 @@ } }; +struct FileMappingHandleTraits : CommonHandleTraits { + static handle_type GetInvalid() { + return 0; + } +}; + +struct MappedViewOfFileHandleTraits : CommonHandleTraits { + typedef LPVOID handle_type; + + static handle_type GetInvalid() { + return 0; + } + + static void Close(handle_type h) { + ::UnmapViewOfFile(h); + } +}; + struct FileHandleTraits : CommonHandleTraits {}; typedef ScopedHandle ScopedCommonHandle; @@ -135,6 +153,8 @@ typedef ScopedHandle ScopedCryptContext; typedef ScopedHandle ScopedFindHandle; typedef ScopedHandle ScopedJobHandle; +typedef ScopedHandle ScopedFileMappingHandle; +typedef ScopedHandle ScopedMappedViewOfFileHandle; namespace llvm { template Modified: llvm/trunk/unittests/Support/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Path.cpp?rev=146363&r1=146362&r2=146363&view=diff ============================================================================== --- llvm/trunk/unittests/Support/Path.cpp (original) +++ llvm/trunk/unittests/Support/Path.cpp Mon Dec 12 00:04:01 2011 @@ -304,4 +304,32 @@ } } +TEST_F(FileSystemTest, Canonicalize) { + SmallString<128> file_pathname(TestDirectory); + path::append(file_pathname, "canonicalize", "a0", "aa1"); + + bool existed; + ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) + + "/canonicalize/a0/aa1", existed)); + + { + path::append(file_pathname, "file.txt"); + std::string ErrMsg; + raw_fd_ostream file(file_pathname.c_str(), ErrMsg); + file << "hello\n"; + } + + SmallString<0> res; + ASSERT_NO_ERROR(fs::canonicalize(Twine(TestDirectory) + + "/cAnOnIcAlIzE/A0/aA1/fIlE.TxT", res)); + // Only check if we actually found the file. As we won't find it on case + // sensitive file systems. + if (fs::exists(res.str())) { + ASSERT_TRUE(res.str().find("canonicalize") != StringRef::npos); + ASSERT_TRUE(res.str().find("a0") != StringRef::npos); + ASSERT_TRUE(res.str().find("aa1") != StringRef::npos); + ASSERT_TRUE(res.str().find("file.txt") != StringRef::npos); + } +} + } // anonymous namespace From bigcheesegs at gmail.com Mon Dec 12 00:04:28 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Mon, 12 Dec 2011 06:04:28 -0000 Subject: [llvm-commits] [llvm] r146364 - in /llvm/trunk: include/llvm/Support/FileSystem.h lib/Support/Unix/PathV2.inc lib/Support/Windows/PathV2.inc unittests/Support/Path.cpp Message-ID: <20111212060429.01D1D2A6C12C@llvm.org> Author: mspencer Date: Mon Dec 12 00:04:28 2011 New Revision: 146364 URL: http://llvm.org/viewvc/llvm-project?rev=146364&view=rev Log: Support/FileSystem: Implement bool equivalent(file_status A, file_status B); Modified: llvm/trunk/include/llvm/Support/FileSystem.h llvm/trunk/lib/Support/Unix/PathV2.inc llvm/trunk/lib/Support/Windows/PathV2.inc llvm/trunk/unittests/Support/Path.cpp Modified: llvm/trunk/include/llvm/Support/FileSystem.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/FileSystem.h?rev=146364&r1=146363&r2=146364&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/FileSystem.h (original) +++ llvm/trunk/include/llvm/Support/FileSystem.h Mon Dec 12 00:04:28 2011 @@ -39,6 +39,10 @@ #include #include +#if HAVE_SYS_STAT_H +#include +#endif + namespace llvm { namespace sys { namespace fs { @@ -94,7 +98,20 @@ /// a platform specific member to store the result. class file_status { - // implementation defined status field. + #if defined(LLVM_ON_UNIX) + dev_t st_dev; + ino_t st_ino; + #elif defined (LLVM_ON_WIN32) + uint32_t LastWriteTimeHigh; + uint32_t LastWriteTimeLow; + uint32_t VolumeSerialNumber; + uint32_t FileSizeHigh; + uint32_t FileSizeLow; + uint32_t FileIndexHigh; + uint32_t FileIndexLow; + #endif + friend bool equivalent(file_status A, file_status B); + friend error_code status(const Twine &path, file_status &result); file_type Type; public: explicit file_status(file_type v=file_type::status_error) @@ -244,6 +261,8 @@ /// @brief Do paths represent the same thing? /// +/// assert(status_known(A) || status_known(B)); +/// /// @param A Input path A. /// @param B Input path B. /// @param result Set to true if stat(A) and stat(B) have the same device and Modified: llvm/trunk/lib/Support/Unix/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/PathV2.inc?rev=146364&r1=146363&r2=146364&view=diff ============================================================================== --- llvm/trunk/lib/Support/Unix/PathV2.inc (original) +++ llvm/trunk/lib/Support/Unix/PathV2.inc Mon Dec 12 00:04:28 2011 @@ -273,28 +273,17 @@ return success; } -error_code equivalent(const Twine &A, const Twine &B, bool &result) { - // Get arguments. - SmallString<128> a_storage; - SmallString<128> b_storage; - StringRef a = A.toNullTerminatedStringRef(a_storage); - StringRef b = B.toNullTerminatedStringRef(b_storage); - - struct stat stat_a, stat_b; - int error_b = ::stat(b.begin(), &stat_b); - int error_a = ::stat(a.begin(), &stat_a); - - // If both are invalid, it's an error. If only one is, the result is false. - if (error_a != 0 || error_b != 0) { - if (error_a == error_b) - return error_code(errno, system_category()); - result = false; - } else { - result = - stat_a.st_dev == stat_b.st_dev && - stat_a.st_ino == stat_b.st_ino; - } +bool equivalent(file_status A, file_status B) { + assert(status_known(A) && status_known(B)); + return A.st_dev == B.st_dev && + A.st_ino == B.st_ino; +} +error_code equivalent(const Twine &A, const Twine &B, bool &result) { + file_status fsA, fsB; + if (error_code ec = status(A, fsA)) return ec; + if (error_code ec = status(B, fsB)) return ec; + result = equivalent(fsA, fsB); return success; } @@ -341,6 +330,9 @@ else result = file_status(file_type::type_unknown); + result.st_dev = status.st_dev; + result.st_ino = status.st_ino; + return success; } Modified: llvm/trunk/lib/Support/Windows/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/PathV2.inc?rev=146364&r1=146363&r2=146364&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/PathV2.inc (original) +++ llvm/trunk/lib/Support/Windows/PathV2.inc Mon Dec 12 00:04:28 2011 @@ -350,66 +350,22 @@ return success; } -error_code equivalent(const Twine &A, const Twine &B, bool &result) { - // Get arguments. - SmallString<128> a_storage; - SmallString<128> b_storage; - StringRef a = A.toStringRef(a_storage); - StringRef b = B.toStringRef(b_storage); - - // Convert to utf-16. - SmallVector wide_a; - SmallVector wide_b; - if (error_code ec = UTF8ToUTF16(a, wide_a)) return ec; - if (error_code ec = UTF8ToUTF16(b, wide_b)) return ec; - - ScopedFileHandle HandleB( - ::CreateFileW(wide_b.begin(), - 0, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - 0)); - - ScopedFileHandle HandleA( - ::CreateFileW(wide_a.begin(), - 0, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - 0)); - - // If both handles are invalid, it's an error. - if (!HandleA && !HandleB) - return windows_error(::GetLastError()); - - // If only one is invalid, it's false. - if (!HandleA || !HandleB) { - result = false; - return success; - } - - // Get file information. - BY_HANDLE_FILE_INFORMATION InfoA, InfoB; - if (!::GetFileInformationByHandle(HandleA, &InfoA)) - return windows_error(::GetLastError()); - if (!::GetFileInformationByHandle(HandleB, &InfoB)) - return windows_error(::GetLastError()); - - // See if it's all the same. - result = - InfoA.dwVolumeSerialNumber == InfoB.dwVolumeSerialNumber && - InfoA.nFileIndexHigh == InfoB.nFileIndexHigh && - InfoA.nFileIndexLow == InfoB.nFileIndexLow && - InfoA.nFileSizeHigh == InfoB.nFileSizeHigh && - InfoA.nFileSizeLow == InfoB.nFileSizeLow && - InfoA.ftLastWriteTime.dwLowDateTime == - InfoB.ftLastWriteTime.dwLowDateTime && - InfoA.ftLastWriteTime.dwHighDateTime == - InfoB.ftLastWriteTime.dwHighDateTime; +bool equivalent(file_status A, file_status B) { + assert(status_known(A) && status_known(B)); + return A.FileIndexHigh == B.FileIndexHigh && + A.FileIndexLow == B.FileIndexLow && + A.FileSizeHigh == B.FileSizeHigh && + A.FileSizeLow == B.FileSizeLow && + A.LastWriteTimeHigh == B.LastWriteTimeHigh && + A.LastWriteTimeLow == B.LastWriteTimeLow && + A.VolumeSerialNumber == B.VolumeSerialNumber; +} +error_code equivalent(const Twine &A, const Twine &B, bool &result) { + file_status fsA, fsB; + if (error_code ec = status(A, fsA)) return ec; + if (error_code ec = status(B, fsB)) return ec; + result = equivalent(fsA, fsB); return success; } @@ -467,8 +423,7 @@ return success; } - if (error_code ec = UTF8ToUTF16(path8, - path_utf16)) + if (error_code ec = UTF8ToUTF16(path8, path_utf16)) return ec; DWORD attr = ::GetFileAttributesW(path_utf16.begin()); @@ -491,8 +446,29 @@ if (attr & FILE_ATTRIBUTE_DIRECTORY) result = file_status(file_type::directory_file); - else + else { result = file_status(file_type::regular_file); + ScopedFileHandle h( + ::CreateFileW(path_utf16.begin(), + 0, // Attributes only. + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + 0)); + if (!h) + goto handle_status_error; + BY_HANDLE_FILE_INFORMATION Info; + if (!::GetFileInformationByHandle(h, &Info)) + goto handle_status_error; + result.FileIndexHigh = Info.nFileIndexHigh; + result.FileIndexLow = Info.nFileIndexLow; + result.FileSizeHigh = Info.nFileSizeHigh; + result.FileSizeLow = Info.nFileSizeLow; + result.LastWriteTimeHigh = Info.ftLastWriteTime.dwHighDateTime; + result.LastWriteTimeLow = Info.ftLastWriteTime.dwLowDateTime; + result.VolumeSerialNumber = Info.dwVolumeSerialNumber; + } return success; Modified: llvm/trunk/unittests/Support/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Path.cpp?rev=146364&r1=146363&r2=146364&view=diff ============================================================================== --- llvm/trunk/unittests/Support/Path.cpp (original) +++ llvm/trunk/unittests/Support/Path.cpp Mon Dec 12 00:04:28 2011 @@ -183,6 +183,11 @@ ASSERT_NO_ERROR(fs::unique_file("%%-%%-%%-%%.temp", FD2, TempPath2)); ASSERT_NE(TempPath.str(), TempPath2.str()); + fs::file_status A, B; + ASSERT_NO_ERROR(fs::status(Twine(TempPath), A)); + ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B)); + EXPECT_FALSE(fs::equivalent(A, B)); + // Try to copy the first to the second. EXPECT_EQ( fs::copy_file(Twine(TempPath), Twine(TempPath2)), errc::file_exists); @@ -204,6 +209,9 @@ bool equal; ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal)); EXPECT_TRUE(equal); + ASSERT_NO_ERROR(fs::status(Twine(TempPath), A)); + ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B)); + EXPECT_TRUE(fs::equivalent(A, B)); // Remove Temp1. ::close(FileDescriptor); From glider at google.com Mon Dec 12 02:07:52 2011 From: glider at google.com (Alexander Potapenko) Date: Mon, 12 Dec 2011 12:07:52 +0400 Subject: [llvm-commits] [llvm] r146284 - /llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp In-Reply-To: <20111209220933.4FEFC1BE003@llvm.org> References: <20111209220933.4FEFC1BE003@llvm.org> Message-ID: > > ? appendToGlobalCtors(M, AsanCtorFunction, 1 /*high priority*/); > + ?appendToPreinitArray(M, AsanInitFunction); > I see this function is called on Mac as well as on Linux. Have you fixed this? From stpworld at narod.ru Mon Dec 12 02:50:52 2011 From: stpworld at narod.ru (Stepan Dyatkovskiy) Date: Mon, 12 Dec 2011 12:50:52 +0400 Subject: [llvm-commits] [LLVM, SwitchInst, case ranges] Auxiliary patch #1 In-Reply-To: <4EE25B61.9070006@narod.ru> References: <4EAA9B5D.802@narod.ru> <4EAA9DE8.80000@free.fr> <485181319805488@web67.yandex.ru> <4EAB079D.6000606@free.fr> <4EB18F12.6060409@narod.ru> <4EB7C319.1000709@narod.ru> <4EDE7D75.704@narod.ru> <4EDFD0F4.1040204@narod.ru> <4EE25B61.9070006@narod.ru> Message-ID: <4EE5C06C.3050705@narod.ru> Ping. -Stepan. Stepan Dyatkovskiy wrote: > ping. > > Stepan Dyatkovskiy wrote: >> Ping. >> >> -Stepan. >> >> Stepan Dyatkovskiy wrote: >>> ping. >>> >>> -Stepan. >>> >>> Stepan Dyatkovskiy wrote: >>>> ping. >>>> -Stepan. >>>> >>>> Stepan Dyatkovskiy wrote: >>>>> Hello, Duncan. >>>>> >>>>> Duncan Sands wrote: >>>>> > I guess Anton can comment on codegen, but the fact that it doesn't make >>>>> > codegen >>>>> > harder has nothing to do with increasing the complexity of the >>>>> > optimizers, since >>>>> > they work at the IR level. It may be that case ranges allow the >>>>> > optimizers to >>>>> > do a better job. It may be that they simplify the optimizers. But it >>>>> > also may >>>>> > be the opposite: they might make switches harder to work with and reason >>>>> > about >>>>> > for no advantage. Which is it? Do you have an example where case ranges >>>>> > would >>>>> > result in better code, or make it easier to produce better code? >>>>> >>>>> I made impact analysis for new case ranges feature. >>>>> 24 out of more than 100 optimizations are affected. 20 of 24 just >>>>> require an integration of a new "case-range" type, i.e. small change of >>>>> code without. The remaining 4 requires some bigger changes. All affected >>>>> optimizers are listed in attached spreadsheet. >>>>> >>>>> Patches that are submitted in this branch are just functionality >>>>> extension for current classes. These patches doesn't brake any of >>>>> existing optimizations and keeps its speed without changes. >>>>> >>>>> Well. Let's enumerate 4 optimizations that should be reworked. >>>>> >>>>> 1. LowerSwitch::Clusterify >>>>> >>>>> This method groups neighbouring cases (by value) that goes to the same >>>>> destination. >>>>> >>>>> For example: >>>>> >>>>> switch i32 %cond, label %default [ >>>>> i32 1, label %successorA >>>>> i32 2, label %successorA >>>>> i32 5, label %successorB >>>>> i32 3, label %successorA >>>>> i32 6, label %successorB >>>>> ] >>>>> >>>>> will be grouped to the two clusters: >>>>> >>>>> [[i32 1] .. [i32 3]], label %successorA >>>>> [[i32 5] .. [i32 6]], label %successorB >>>>> >>>>> This method will work faster if clusters will presented explicitly using >>>>> new case ranges feature. >>>>> >>>>> 2. SimplifyCFG.cpp, TurnSwitchRangeIntoICmp (static function) >>>>> >>>>> "Turns a switch that contains only an integer range comparison into a >>>>> sub, an icmp and a branch." (written in method comments). Algorithm that >>>>> determines "solid" case range should be changed. >>>>> >>>>> Now compare two switches (don't look at syntax of second switch, it is >>>>> still a subject of another discussion): >>>>> >>>>> switch i32 %cond, label %default [ >>>>> i32 1, label %successorA >>>>> i32 2, label %successorA >>>>> i32 3, label %successorA >>>>> ] >>>>> >>>>> and hypothetical switch: >>>>> >>>>> switch i32 %cond, label %default [ >>>>> [[i32 1],[i32 3]], label %successorA ; case range [1..3] >>>>> ] >>>>> >>>>> or even this one: >>>>> >>>>> switch i32 %cond, label %default [ >>>>> [[i32 1],[i32 2]], label %successorA ; case range [1..2] >>>>> i32 3, label %successorA ; single case value "3" >>>>> ] >>>>> >>>>> Its obvious that last two switches will be processed faster than the >>>>> first one. We doesn't need to perform analysis for each separated case >>>>> value. We already know - that it is a range. >>>>> >>>>> 3. SimplifyCFG.cpp, EliminateDeadSwitchCases (static function). >>>>> >>>>> Here switch condition is analysed. We try to determine "1" and "0" bits >>>>> that MUST be in condition value. If we found them, then we look at case >>>>> values; if these bits are absent in case value we remove it since it >>>>> will be never equal to condition. >>>>> I need to think more about the ways of case ranges processing here. At >>>>> least we can represent case range as separated values set and apply >>>>> current algorithm to it. It slow down the processing a little bit, but >>>>> the complexity itself will be not increased. I'm sure that there are >>>>> also exists algorithms that allows to eliminate whole case ranges: e.g. >>>>> we can apply current algorithm to high bits that are constant in case >>>>> range. >>>>> >>>>> 4. lib/Transforms/Scalar/LoopUnswitch.cpp (the set of methods). >>>>> >>>>> Just a quote from LoopUnswitch.cpp header >>>>> >>>>> [quote] >>>>> This pass transforms loops that contain branches on loop-invariant >>>>> conditions >>>>> to have multiple loops. For example, it turns the left into the right code. >>>>> >>>>> for (...) if (lic) >>>>> A for (...) >>>>> if (lic) A; B; C >>>>> B else >>>>> C for (...) >>>>> A; C >>>>> [/quote] >>>>> >>>>> I also must think more about case ranges unswithing here. >>>>> By now loops with switch instruction are unswitched value-by-value. >>>>> There is no any case-values clustering before unswitching. For example >>>>> for case range [0..9] we need to run unswitch process 10 times! >>>>> Theoretically, explicitly given case ranges and properly implemented >>>>> unswitching should make this optimization better. >>>>> >>>>> So, as you can see complexity will not changed and even some of >>>>> optimizations will work faster. >>>>> >>>>> Regards, >>>>> Stepan. >>>>> >>>>> >>>>> _______________________________________________ >>>>> llvm-commits mailing list >>>>> llvm-commits at cs.uiuc.edu >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>>> >>>> _______________________________________________ >>>> llvm-commits mailing list >>>> llvm-commits at cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Mon Dec 12 03:14:06 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 12 Dec 2011 10:14:06 +0100 Subject: [llvm-commits] [llvm] r146357 - in /llvm/trunk: include/llvm/Intrinsics.td lib/Analysis/ConstantFolding.cpp lib/Transforms/Scalar/SimplifyLibCalls.cpp lib/VMCore/AutoUpgrade.cpp In-Reply-To: <20111212042605.0FE8E2A6C12C@llvm.org> References: <20111212042605.0FE8E2A6C12C@llvm.org> Message-ID: <4EE5C5DE.4010900@free.fr> Hi Chandler, > Switch llvm.cttz and llvm.ctlz to accept a second i1 parameter which > indicates whether the intrinsic has a defined result for a first > argument equal to zero. is this flag really useful, i.e. isn't the undef form enough? To get the other form you can test the parameter against zero and use a select. Then codegen can zap the select on targets where the processor instruction does the right thing for an argument of zero. > --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) > +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Sun Dec 11 22:26:04 2011 > @@ -1418,6 +1414,14 @@ > }; > return ConstantStruct::get(cast(F->getReturnType()), Ops); > } > + case Intrinsic::cttz: > + // FIXME: This should check for Op2 == 1, and become unreachable if Don't you mean "undef" rather than "unreachable"? > + // Op1 == 0. > + return ConstantInt::get(Ty, Op1->getValue().countTrailingZeros()); > + case Intrinsic::ctlz: > + // FIXME: This should check for Op2 == 1, and become unreachable if > + // Op1 == 0. > + return ConstantInt::get(Ty, Op1->getValue().countLeadingZeros()); > } > } > > > --- llvm/trunk/lib/VMCore/AutoUpgrade.cpp (original) > +++ llvm/trunk/lib/VMCore/AutoUpgrade.cpp Sun Dec 11 22:26:04 2011 > @@ -40,7 +40,20 @@ > > switch (Name[0]) { > default: break; > - // SOMEDAY: Add some. > + case 'c': { > + Type *Tys[] = { F->arg_begin()->getType() }; If one day there is an llvm intrinsic with a name starting with "c" with no arguments, won't this explode? > + if (Name.startswith("ctlz.")&& F->arg_size() == 1) { > + F->setName(Name + ".old"); > + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz, Tys); > + return true; > + } > + if (Name.startswith("cttz.")&& F->arg_size() == 1) { > + F->setName(Name + ".old"); > + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz, Tys); > + return true; > + } > + break; > + } > } > > // This may not belong here. This function is effectively being overloaded Ciao, Duncan. From chandlerc at google.com Mon Dec 12 03:56:39 2011 From: chandlerc at google.com (Chandler Carruth) Date: Mon, 12 Dec 2011 01:56:39 -0800 Subject: [llvm-commits] [llvm] r146357 - in /llvm/trunk: include/llvm/Intrinsics.td lib/Analysis/ConstantFolding.cpp lib/Transforms/Scalar/SimplifyLibCalls.cpp lib/VMCore/AutoUpgrade.cpp In-Reply-To: <4EE5C5DE.4010900@free.fr> References: <20111212042605.0FE8E2A6C12C@llvm.org> <4EE5C5DE.4010900@free.fr> Message-ID: On Mon, Dec 12, 2011 at 1:14 AM, Duncan Sands wrote: > Hi Chandler, > > > Switch llvm.cttz and llvm.ctlz to accept a second i1 parameter which > > indicates whether the intrinsic has a defined result for a first > > argument equal to zero. > > is this flag really useful, i.e. isn't the undef form enough? To get the > other form you can test the parameter against zero and use a select. Then > codegen can zap the select on targets where the processor instruction does > the right thing for an argument of zero. > I completely agree. Chris wanted it this way, and although it makes the implementation more complex and more work, I didn't feel like arguing. Feel free to do so, and if you win, I'll change it. =D > > --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) > > +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Sun Dec 11 22:26:04 2011 > > @@ -1418,6 +1414,14 @@ > > }; > > return > ConstantStruct::get(cast(F->getReturnType()), Ops); > > } > > + case Intrinsic::cttz: > > + // FIXME: This should check for Op2 == 1, and become > unreachable if > > Don't you mean "undef" rather than "unreachable"? > Yea, sorry, I'll clean up these comments when I start implementing the proper behavior for this case. > > + // Op1 == 0. > > + return ConstantInt::get(Ty, > Op1->getValue().countTrailingZeros()); > > + case Intrinsic::ctlz: > > + // FIXME: This should check for Op2 == 1, and become > unreachable if > > + // Op1 == 0. > > + return ConstantInt::get(Ty, > Op1->getValue().countLeadingZeros()); > > } > > } > > > > > > --- llvm/trunk/lib/VMCore/AutoUpgrade.cpp (original) > > +++ llvm/trunk/lib/VMCore/AutoUpgrade.cpp Sun Dec 11 22:26:04 2011 > > @@ -40,7 +40,20 @@ > > > > switch (Name[0]) { > > default: break; > > - // SOMEDAY: Add some. > > + case 'c': { > > + Type *Tys[] = { F->arg_begin()->getType() }; > > If one day there is an llvm intrinsic with a name starting with "c" with no > arguments, won't this explode? > Yikes, good catch. Will fix. =] Thanks for the review! -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20111212/650a5091/attachment.html From baldrick at free.fr Mon Dec 12 04:07:25 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 12 Dec 2011 11:07:25 +0100 Subject: [llvm-commits] [llvm] r146357 - in /llvm/trunk: include/llvm/Intrinsics.td lib/Analysis/ConstantFolding.cpp lib/Transforms/Scalar/SimplifyLibCalls.cpp lib/VMCore/AutoUpgrade.cpp In-Reply-To: References: <20111212042605.0FE8E2A6C12C@llvm.org> <4EE5C5DE.4010900@free.fr> Message-ID: <4EE5D25D.4030408@free.fr> Hi Chandler, don't listen to that Chris guy, what does he know?! :) Given the amount of codegen ugliness (i.e. either duplicating the set of CTTZ etc nodes, one for each flag version, or modifying a ton of patterns to expect more than one argument) hopefully Chris will accept the simpler version of your patch in which there is only the "undef" form of the intrinsics. Someone can wlays add a flag later if there proves to be a really compelling need for it such as codegen finding it too hard to get rid of pointless comparisons of the argument with zero on platforms with always-well-defined bit counting instructions. Ciao, Duncan. On 12/12/11 10:56, Chandler Carruth wrote: > On Mon, Dec 12, 2011 at 1:14 AM, Duncan Sands > wrote: > > Hi Chandler, > > > Switch llvm.cttz and llvm.ctlz to accept a second i1 parameter which > > indicates whether the intrinsic has a defined result for a first > > argument equal to zero. > > is this flag really useful, i.e. isn't the undef form enough? To get the > other form you can test the parameter against zero and use a select. Then > codegen can zap the select on targets where the processor instruction does > the right thing for an argument of zero. > > > I completely agree. Chris wanted it this way, and although it makes the > implementation more complex and more work, I didn't feel like arguing. Feel free > to do so, and if you win, I'll change it. =D > > > --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) > > +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Sun Dec 11 22:26:04 2011 > > @@ -1418,6 +1414,14 @@ > > }; > > return > ConstantStruct::get(cast(F->getReturnType()), Ops); > > } > > + case Intrinsic::cttz: > > + // FIXME: This should check for Op2 == 1, and become > unreachable if > > Don't you mean "undef" rather than "unreachable"? > > > Yea, sorry, I'll clean up these comments when I start implementing the proper > behavior for this case. > > > > + // Op1 == 0. > > + return ConstantInt::get(Ty, Op1->getValue().countTrailingZeros()); > > + case Intrinsic::ctlz: > > + // FIXME: This should check for Op2 == 1, and become > unreachable if > > + // Op1 == 0. > > + return ConstantInt::get(Ty, Op1->getValue().countLeadingZeros()); > > } > > } > > > > > > --- llvm/trunk/lib/VMCore/AutoUpgrade.cpp (original) > > +++ llvm/trunk/lib/VMCore/AutoUpgrade.cpp Sun Dec 11 22:26:04 2011 > > @@ -40,7 +40,20 @@ > > > > switch (Name[0]) { > > default: break; > > - // SOMEDAY: Add some. > > + case 'c': { > > + Type *Tys[] = { F->arg_begin()->getType() }; > > If one day there is an llvm intrinsic with a name starting with "c" with no > arguments, won't this explode? > > > Yikes, good catch. Will fix. =] > > Thanks for the review! From chandlerc at gmail.com Mon Dec 12 04:57:20 2011 From: chandlerc at gmail.com (Chandler Carruth) Date: Mon, 12 Dec 2011 10:57:20 -0000 Subject: [llvm-commits] [llvm] r146368 - /llvm/trunk/lib/VMCore/AutoUpgrade.cpp Message-ID: <20111212105720.AB3CE2A6C12C@llvm.org> Author: chandlerc Date: Mon Dec 12 04:57:20 2011 New Revision: 146368 URL: http://llvm.org/viewvc/llvm-project?rev=146368&view=rev Log: Don't rely in there being one argument before we've actually identified a function to upgrade. Also, simplify the code a bit at the expense of one line. Modified: llvm/trunk/lib/VMCore/AutoUpgrade.cpp Modified: llvm/trunk/lib/VMCore/AutoUpgrade.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AutoUpgrade.cpp?rev=146368&r1=146367&r2=146368&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AutoUpgrade.cpp (original) +++ llvm/trunk/lib/VMCore/AutoUpgrade.cpp Mon Dec 12 04:57:20 2011 @@ -41,15 +41,16 @@ switch (Name[0]) { default: break; case 'c': { - Type *Tys[] = { F->arg_begin()->getType() }; if (Name.startswith("ctlz.") && F->arg_size() == 1) { F->setName(Name + ".old"); - NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz, Tys); + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz, + F->arg_begin()->getType()); return true; } if (Name.startswith("cttz.") && F->arg_size() == 1) { F->setName(Name + ".old"); - NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz, Tys); + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz, + F->arg_begin()->getType()); return true; } break; From chandlerc at gmail.com Mon Dec 12 05:23:12 2011 From: chandlerc at gmail.com (Chandler Carruth) Date: Mon, 12 Dec 2011 11:23:12 -0000 Subject: [llvm-commits] [llvm] r146369 - /llvm/trunk/test/Assembler/auto_upgrade_intrinsics.ll Message-ID: <20111212112312.292262A6C12C@llvm.org> Author: chandlerc Date: Mon Dec 12 05:23:11 2011 New Revision: 146369 URL: http://llvm.org/viewvc/llvm-project?rev=146369&view=rev Log: Add an explicit test of the auto-upgrade functionality for the new intrinsic syntax. Now that this is explicitly covered, I plan to upgrade the existing test suite to use an explicit immediate. Note that I plan to specify 'true' in most places rather than the auto-upgraded value as that is the far more common value to end up here as that is the value coming from GCC's builtins. The only place I'm likely to put a 'false' in is when testing x86 which actually has different instructions for the two variants. Added: llvm/trunk/test/Assembler/auto_upgrade_intrinsics.ll Added: llvm/trunk/test/Assembler/auto_upgrade_intrinsics.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/auto_upgrade_intrinsics.ll?rev=146369&view=auto ============================================================================== --- llvm/trunk/test/Assembler/auto_upgrade_intrinsics.ll (added) +++ llvm/trunk/test/Assembler/auto_upgrade_intrinsics.ll Mon Dec 12 05:23:11 2011 @@ -0,0 +1,44 @@ +; Test to make sure intrinsics are automatically upgraded. +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +declare i8 @llvm.ctlz.i8(i8) +declare i16 @llvm.ctlz.i16(i16) +declare i32 @llvm.ctlz.i32(i32) +declare i42 @llvm.ctlz.i42(i42) ; Not a power-of-2 + +define void @test.ctlz(i8 %a, i16 %b, i32 %c, i42 %d) { +; CHECK: @test.ctlz + +entry: + ; CHECK: call i8 @llvm.ctlz.i8(i8 %a, i1 false) + call i8 @llvm.ctlz.i8(i8 %a) + ; CHECK: call i16 @llvm.ctlz.i16(i16 %b, i1 false) + call i16 @llvm.ctlz.i16(i16 %b) + ; CHECK: call i32 @llvm.ctlz.i32(i32 %c, i1 false) + call i32 @llvm.ctlz.i32(i32 %c) + ; CHECK: call i42 @llvm.ctlz.i42(i42 %d, i1 false) + call i42 @llvm.ctlz.i42(i42 %d) + + ret void +} + +declare i8 @llvm.cttz.i8(i8) +declare i16 @llvm.cttz.i16(i16) +declare i32 @llvm.cttz.i32(i32) +declare i42 @llvm.cttz.i42(i42) ; Not a power-of-2 + +define void @test.cttz(i8 %a, i16 %b, i32 %c, i42 %d) { +; CHECK: @test.cttz + +entry: + ; CHECK: call i8 @llvm.cttz.i8(i8 %a, i1 false) + call i8 @llvm.cttz.i8(i8 %a) + ; CHECK: call i16 @llvm.cttz.i16(i16 %b, i1 false) + call i16 @llvm.cttz.i16(i16 %b) + ; CHECK: call i32 @llvm.cttz.i32(i32 %c, i1 false) + call i32 @llvm.cttz.i32(i32 %c) + ; CHECK: call i42 @llvm.cttz.i42(i42 %d, i1 false) + call i42 @llvm.cttz.i42(i42 %d) + + ret void +} From chandlerc at gmail.com Mon Dec 12 05:59:11 2011 From: chandlerc at gmail.com (Chandler Carruth) Date: Mon, 12 Dec 2011 11:59:11 -0000 Subject: [llvm-commits] [llvm] r146370 - in /llvm/trunk/test: Analysis/BasicAA/ CodeGen/ARM/ CodeGen/Generic/ CodeGen/Mips/ CodeGen/PowerPC/ CodeGen/Thumb2/ CodeGen/X86/ Feature/ Transforms/ConstProp/ Transforms/InstCombine/ Transforms/SCCP/ Message-ID: <20111212115911.BE8D02A6C12C@llvm.org> Author: chandlerc Date: Mon Dec 12 05:59:10 2011 New Revision: 146370 URL: http://llvm.org/viewvc/llvm-project?rev=146370&view=rev Log: Manually upgrade the test suite to specify the flag to cttz and ctlz. I followed three heuristics for deciding whether to set 'true' or 'false': - Everything target independent got 'true' as that is the expected common output of the GCC builtins. - If the target arch only has one way of implementing this operation, set the flag in the way that exercises the most of codegen. For most architectures this is also the likely path from a GCC builtin, with 'true' being set. It will (eventually) require lowering away that difference, and then lowering to the architecture's operation. - Otherwise, set the flag differently dependending on which target operation should be tested. Let me know if anyone has any issue with this pattern or would like specific tests of another form. This should allow the x86 codegen to just iteratively improve as I teach the backend how to differentiate between the two forms, and everything else should remain exactly the same. Modified: llvm/trunk/test/Analysis/BasicAA/2007-08-05-GetOverloadedModRef.ll llvm/trunk/test/CodeGen/ARM/clz.ll llvm/trunk/test/CodeGen/ARM/ctz.ll llvm/trunk/test/CodeGen/ARM/fold-const.ll llvm/trunk/test/CodeGen/Generic/2008-02-04-Ctlz.ll llvm/trunk/test/CodeGen/Generic/llvm-ct-intrinsics.ll llvm/trunk/test/CodeGen/Mips/2008-08-08-ctlz.ll llvm/trunk/test/CodeGen/Mips/2010-11-09-CountLeading.ll llvm/trunk/test/CodeGen/Mips/mips64instrs.ll llvm/trunk/test/CodeGen/PowerPC/2007-03-24-cntlzd.ll llvm/trunk/test/CodeGen/PowerPC/cttz.ll llvm/trunk/test/CodeGen/Thumb2/thumb2-clz.ll llvm/trunk/test/CodeGen/X86/bmi.ll llvm/trunk/test/CodeGen/X86/clz.ll llvm/trunk/test/CodeGen/X86/lzcnt.ll llvm/trunk/test/CodeGen/X86/vec_ctbits.ll llvm/trunk/test/Feature/intrinsics.ll llvm/trunk/test/Transforms/ConstProp/2007-11-23-cttz.ll llvm/trunk/test/Transforms/InstCombine/bitcount.ll llvm/trunk/test/Transforms/InstCombine/intrinsics.ll llvm/trunk/test/Transforms/InstCombine/sext.ll llvm/trunk/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll Modified: llvm/trunk/test/Analysis/BasicAA/2007-08-05-GetOverloadedModRef.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/2007-08-05-GetOverloadedModRef.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/2007-08-05-GetOverloadedModRef.ll (original) +++ llvm/trunk/test/Analysis/BasicAA/2007-08-05-GetOverloadedModRef.ll Mon Dec 12 05:59:10 2011 @@ -3,12 +3,12 @@ ; RUN: grep {ret i32 0} ; END. -declare i16 @llvm.cttz.i16(i16) +declare i16 @llvm.cttz.i16(i16, i1) define i32 @test(i32* %P, i16* %Q) { %A = load i16* %Q ; [#uses=1] %x = load i32* %P ; [#uses=1] - %B = call i16 @llvm.cttz.i16( i16 %A ) ; [#uses=1] + %B = call i16 @llvm.cttz.i16( i16 %A, i1 true ) ; [#uses=1] %y = load i32* %P ; [#uses=1] store i16 %B, i16* %Q %z = sub i32 %x, %y ; [#uses=1] Modified: llvm/trunk/test/CodeGen/ARM/clz.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/clz.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/clz.ll (original) +++ llvm/trunk/test/CodeGen/ARM/clz.ll Mon Dec 12 05:59:10 2011 @@ -1,10 +1,10 @@ ; RUN: llc < %s -march=arm -mattr=+v5t | FileCheck %s -declare i32 @llvm.ctlz.i32(i32) +declare i32 @llvm.ctlz.i32(i32, i1) define i32 @test(i32 %x) { ; CHECK: test ; CHECK: clz r0, r0 - %tmp.1 = call i32 @llvm.ctlz.i32( i32 %x ) + %tmp.1 = call i32 @llvm.ctlz.i32( i32 %x, i1 true ) ret i32 %tmp.1 } Modified: llvm/trunk/test/CodeGen/ARM/ctz.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ctz.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/ctz.ll (original) +++ llvm/trunk/test/CodeGen/ARM/ctz.ll Mon Dec 12 05:59:10 2011 @@ -1,11 +1,11 @@ ; RUN: llc < %s -march=arm -mattr=+v6t2 | FileCheck %s -declare i32 @llvm.cttz.i32(i32) +declare i32 @llvm.cttz.i32(i32, i1) define i32 @f1(i32 %a) { ; CHECK: f1: ; CHECK: rbit ; CHECK: clz - %tmp = call i32 @llvm.cttz.i32( i32 %a ) + %tmp = call i32 @llvm.cttz.i32( i32 %a, i1 true ) ret i32 %tmp } Modified: llvm/trunk/test/CodeGen/ARM/fold-const.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fold-const.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fold-const.ll (original) +++ llvm/trunk/test/CodeGen/ARM/fold-const.ll Mon Dec 12 05:59:10 2011 @@ -3,7 +3,7 @@ define i32 @f(i32 %a) nounwind readnone optsize ssp { entry: %conv = zext i32 %a to i64 - %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %conv) + %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %conv, i1 true) ; CHECK: clz ; CHECK-NOT: adds %cast = trunc i64 %tmp1 to i32 @@ -11,4 +11,4 @@ ret i32 %sub } -declare i64 @llvm.ctlz.i64(i64) nounwind readnone +declare i64 @llvm.ctlz.i64(i64, i1) nounwind readnone Modified: llvm/trunk/test/CodeGen/Generic/2008-02-04-Ctlz.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/2008-02-04-Ctlz.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Generic/2008-02-04-Ctlz.ll (original) +++ llvm/trunk/test/CodeGen/Generic/2008-02-04-Ctlz.ll Mon Dec 12 05:59:10 2011 @@ -4,8 +4,8 @@ define i32 @main(i64 %arg) nounwind { entry: - %tmp37 = tail call i64 @llvm.ctlz.i64( i64 %arg ) ; [#uses=1] - %tmp47 = tail call i64 @llvm.cttz.i64( i64 %arg ) ; [#uses=1] + %tmp37 = tail call i64 @llvm.ctlz.i64( i64 %arg, i1 true ) ; [#uses=1] + %tmp47 = tail call i64 @llvm.cttz.i64( i64 %arg, i1 true ) ; [#uses=1] %tmp57 = tail call i64 @llvm.ctpop.i64( i64 %arg ) ; [#uses=1] %tmp38 = trunc i64 %tmp37 to i32 ; :0 [#uses=1] %tmp48 = trunc i64 %tmp47 to i32 ; :0 [#uses=1] @@ -16,6 +16,6 @@ declare i32 @printf(i8* noalias , ...) nounwind -declare i64 @llvm.ctlz.i64(i64) nounwind readnone -declare i64 @llvm.cttz.i64(i64) nounwind readnone +declare i64 @llvm.ctlz.i64(i64, i1) nounwind readnone +declare i64 @llvm.cttz.i64(i64, i1) nounwind readnone declare i64 @llvm.ctpop.i64(i64) nounwind readnone Modified: llvm/trunk/test/CodeGen/Generic/llvm-ct-intrinsics.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/llvm-ct-intrinsics.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Generic/llvm-ct-intrinsics.ll (original) +++ llvm/trunk/test/CodeGen/Generic/llvm-ct-intrinsics.ll Mon Dec 12 05:59:10 2011 @@ -21,19 +21,19 @@ ret void } -declare i64 @llvm.ctlz.i64(i64) +declare i64 @llvm.ctlz.i64(i64, i1) -declare i32 @llvm.ctlz.i32(i32) +declare i32 @llvm.ctlz.i32(i32, i1) -declare i16 @llvm.ctlz.i16(i16) +declare i16 @llvm.ctlz.i16(i16, i1) -declare i8 @llvm.ctlz.i8(i8) +declare i8 @llvm.ctlz.i8(i8, i1) define void @ctlztest(i8 %A, i16 %B, i32 %C, i64 %D, i8* %AP, i16* %BP, i32* %CP, i64* %DP) { - %a = call i8 @llvm.ctlz.i8( i8 %A ) ; [#uses=1] - %b = call i16 @llvm.ctlz.i16( i16 %B ) ; [#uses=1] - %c = call i32 @llvm.ctlz.i32( i32 %C ) ; [#uses=1] - %d = call i64 @llvm.ctlz.i64( i64 %D ) ; [#uses=1] + %a = call i8 @llvm.ctlz.i8( i8 %A, i1 true ) ; [#uses=1] + %b = call i16 @llvm.ctlz.i16( i16 %B, i1 true ) ; [#uses=1] + %c = call i32 @llvm.ctlz.i32( i32 %C, i1 true ) ; [#uses=1] + %d = call i64 @llvm.ctlz.i64( i64 %D, i1 true ) ; [#uses=1] store i8 %a, i8* %AP store i16 %b, i16* %BP store i32 %c, i32* %CP @@ -41,19 +41,19 @@ ret void } -declare i64 @llvm.cttz.i64(i64) +declare i64 @llvm.cttz.i64(i64, i1) -declare i32 @llvm.cttz.i32(i32) +declare i32 @llvm.cttz.i32(i32, i1) -declare i16 @llvm.cttz.i16(i16) +declare i16 @llvm.cttz.i16(i16, i1) -declare i8 @llvm.cttz.i8(i8) +declare i8 @llvm.cttz.i8(i8, i1) define void @cttztest(i8 %A, i16 %B, i32 %C, i64 %D, i8* %AP, i16* %BP, i32* %CP, i64* %DP) { - %a = call i8 @llvm.cttz.i8( i8 %A ) ; [#uses=1] - %b = call i16 @llvm.cttz.i16( i16 %B ) ; [#uses=1] - %c = call i32 @llvm.cttz.i32( i32 %C ) ; [#uses=1] - %d = call i64 @llvm.cttz.i64( i64 %D ) ; [#uses=1] + %a = call i8 @llvm.cttz.i8( i8 %A, i1 true ) ; [#uses=1] + %b = call i16 @llvm.cttz.i16( i16 %B, i1 true ) ; [#uses=1] + %c = call i32 @llvm.cttz.i32( i32 %C, i1 true ) ; [#uses=1] + %d = call i64 @llvm.cttz.i64( i64 %D, i1 true ) ; [#uses=1] store i8 %a, i8* %AP store i16 %b, i16* %BP store i32 %c, i32* %CP Modified: llvm/trunk/test/CodeGen/Mips/2008-08-08-ctlz.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/2008-08-08-ctlz.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/2008-08-08-ctlz.ll (original) +++ llvm/trunk/test/CodeGen/Mips/2008-08-08-ctlz.ll Mon Dec 12 05:59:10 2011 @@ -3,8 +3,8 @@ define i32 @A0(i32 %u) nounwind { entry: ; CHECK: clz - call i32 @llvm.ctlz.i32( i32 %u ) + call i32 @llvm.ctlz.i32( i32 %u, i1 true ) ret i32 %0 } -declare i32 @llvm.ctlz.i32(i32) nounwind readnone +declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone Modified: llvm/trunk/test/CodeGen/Mips/2010-11-09-CountLeading.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/2010-11-09-CountLeading.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/2010-11-09-CountLeading.ll (original) +++ llvm/trunk/test/CodeGen/Mips/2010-11-09-CountLeading.ll Mon Dec 12 05:59:10 2011 @@ -3,16 +3,16 @@ ; CHECK: clz $2, $4 define i32 @t1(i32 %X) nounwind readnone { entry: - %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %X) + %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %X, i1 true) ret i32 %tmp1 } -declare i32 @llvm.ctlz.i32(i32) nounwind readnone +declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone ; CHECK: clz $2, $4 define i32 @t2(i32 %X) nounwind readnone { entry: - %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %X) + %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %X, i1 true) ret i32 %tmp1 } @@ -20,7 +20,7 @@ define i32 @t3(i32 %X) nounwind readnone { entry: %neg = xor i32 %X, -1 - %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %neg) + %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %neg, i1 true) ret i32 %tmp1 } @@ -28,6 +28,6 @@ define i32 @t4(i32 %X) nounwind readnone { entry: %neg = xor i32 %X, -1 - %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %neg) + %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %neg, i1 true) ret i32 %tmp1 } Modified: llvm/trunk/test/CodeGen/Mips/mips64instrs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/mips64instrs.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/mips64instrs.ll (original) +++ llvm/trunk/test/CodeGen/Mips/mips64instrs.ll Mon Dec 12 05:59:10 2011 @@ -116,12 +116,12 @@ ret i64 %rem } -declare i64 @llvm.ctlz.i64(i64) nounwind readnone +declare i64 @llvm.ctlz.i64(i64, i1) nounwind readnone define i64 @f18(i64 %X) nounwind readnone { entry: ; CHECK: dclz $2, $4 - %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %X) + %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %X, i1 true) ret i64 %tmp1 } @@ -129,7 +129,7 @@ entry: ; CHECK: dclo $2, $4 %neg = xor i64 %X, -1 - %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %neg) + %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %neg, i1 true) ret i64 %tmp1 } Modified: llvm/trunk/test/CodeGen/PowerPC/2007-03-24-cntlzd.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-03-24-cntlzd.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/2007-03-24-cntlzd.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/2007-03-24-cntlzd.ll Mon Dec 12 05:59:10 2011 @@ -2,11 +2,11 @@ define i32 @_ZNK4llvm5APInt17countLeadingZerosEv(i64 *%t) nounwind { %tmp19 = load i64* %t - %tmp22 = tail call i64 @llvm.ctlz.i64( i64 %tmp19 ) ; [#uses=1] + %tmp22 = tail call i64 @llvm.ctlz.i64( i64 %tmp19, i1 true ) ; [#uses=1] %tmp23 = trunc i64 %tmp22 to i32 %tmp89 = add i32 %tmp23, -64 ; [#uses=1] %tmp90 = add i32 %tmp89, 0 ; [#uses=1] ret i32 %tmp90 } -declare i64 @llvm.ctlz.i64(i64) +declare i64 @llvm.ctlz.i64(i64, i1) Modified: llvm/trunk/test/CodeGen/PowerPC/cttz.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/cttz.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/cttz.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/cttz.ll Mon Dec 12 05:59:10 2011 @@ -1,11 +1,11 @@ ; Make sure this testcase does not use ctpop ; RUN: llc < %s -march=ppc32 | grep -i cntlzw -declare i32 @llvm.cttz.i32(i32) +declare i32 @llvm.cttz.i32(i32, i1) define i32 @bar(i32 %x) { entry: - %tmp.1 = call i32 @llvm.cttz.i32( i32 %x ) ; [#uses=1] + %tmp.1 = call i32 @llvm.cttz.i32( i32 %x, i1 true ) ; [#uses=1] ret i32 %tmp.1 } Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-clz.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-clz.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/thumb2-clz.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/thumb2-clz.ll Mon Dec 12 05:59:10 2011 @@ -3,8 +3,8 @@ define i32 @f1(i32 %a) { ; CHECK: f1: ; CHECK: clz r - %tmp = tail call i32 @llvm.ctlz.i32(i32 %a) + %tmp = tail call i32 @llvm.ctlz.i32(i32 %a, i1 true) ret i32 %tmp } -declare i32 @llvm.ctlz.i32(i32) nounwind readnone +declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone Modified: llvm/trunk/test/CodeGen/X86/bmi.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bmi.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/bmi.ll (original) +++ llvm/trunk/test/CodeGen/X86/bmi.ll Mon Dec 12 05:59:10 2011 @@ -1,40 +1,40 @@ ; RUN: llc < %s -march=x86-64 -mattr=+bmi,+bmi2 | FileCheck %s define i32 @t1(i32 %x) nounwind { - %tmp = tail call i32 @llvm.cttz.i32( i32 %x ) + %tmp = tail call i32 @llvm.cttz.i32( i32 %x, i1 false ) ret i32 %tmp ; CHECK: t1: ; CHECK: tzcntl } -declare i32 @llvm.cttz.i32(i32) nounwind readnone +declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone define i16 @t2(i16 %x) nounwind { - %tmp = tail call i16 @llvm.cttz.i16( i16 %x ) + %tmp = tail call i16 @llvm.cttz.i16( i16 %x, i1 false ) ret i16 %tmp ; CHECK: t2: ; CHECK: tzcntw } -declare i16 @llvm.cttz.i16(i16) nounwind readnone +declare i16 @llvm.cttz.i16(i16, i1) nounwind readnone define i64 @t3(i64 %x) nounwind { - %tmp = tail call i64 @llvm.cttz.i64( i64 %x ) + %tmp = tail call i64 @llvm.cttz.i64( i64 %x, i1 false ) ret i64 %tmp ; CHECK: t3: ; CHECK: tzcntq } -declare i64 @llvm.cttz.i64(i64) nounwind readnone +declare i64 @llvm.cttz.i64(i64, i1) nounwind readnone define i8 @t4(i8 %x) nounwind { - %tmp = tail call i8 @llvm.cttz.i8( i8 %x ) + %tmp = tail call i8 @llvm.cttz.i8( i8 %x, i1 false ) ret i8 %tmp ; CHECK: t4: ; CHECK: tzcntw } -declare i8 @llvm.cttz.i8(i8) nounwind readnone +declare i8 @llvm.cttz.i8(i8, i1) nounwind readnone define i32 @andn32(i32 %x, i32 %y) nounwind readnone { %tmp1 = xor i32 %x, -1 Modified: llvm/trunk/test/CodeGen/X86/clz.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/clz.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/clz.ll (original) +++ llvm/trunk/test/CodeGen/X86/clz.ll Mon Dec 12 05:59:10 2011 @@ -1,36 +1,36 @@ ; RUN: llc < %s -march=x86 -mcpu=yonah | FileCheck %s define i32 @t1(i32 %x) nounwind { - %tmp = tail call i32 @llvm.ctlz.i32( i32 %x ) + %tmp = tail call i32 @llvm.ctlz.i32( i32 %x, i1 true ) ret i32 %tmp ; CHECK: t1: ; CHECK: bsrl ; CHECK: cmov } -declare i32 @llvm.ctlz.i32(i32) nounwind readnone +declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone define i32 @t2(i32 %x) nounwind { - %tmp = tail call i32 @llvm.cttz.i32( i32 %x ) + %tmp = tail call i32 @llvm.cttz.i32( i32 %x, i1 true ) ret i32 %tmp ; CHECK: t2: ; CHECK: bsfl ; CHECK: cmov } -declare i32 @llvm.cttz.i32(i32) nounwind readnone +declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone define i16 @t3(i16 %x, i16 %y) nounwind { entry: %tmp1 = add i16 %x, %y - %tmp2 = tail call i16 @llvm.ctlz.i16( i16 %tmp1 ) ; [#uses=1] + %tmp2 = tail call i16 @llvm.ctlz.i16( i16 %tmp1, i1 true ) ; [#uses=1] ret i16 %tmp2 ; CHECK: t3: ; CHECK: bsrw ; CHECK: cmov } -declare i16 @llvm.ctlz.i16(i16) nounwind readnone +declare i16 @llvm.ctlz.i16(i16, i1) nounwind readnone ; Don't generate the cmovne when the source is known non-zero (and bsr would ; not set ZF). @@ -43,6 +43,6 @@ ; CHECK-NOT: cmov ; CHECK: ret %or = or i32 %n, 1 - %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %or) + %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %or, i1 true) ret i32 %tmp1 } Modified: llvm/trunk/test/CodeGen/X86/lzcnt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/lzcnt.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/lzcnt.ll (original) +++ llvm/trunk/test/CodeGen/X86/lzcnt.ll Mon Dec 12 05:59:10 2011 @@ -1,38 +1,38 @@ ; RUN: llc < %s -march=x86-64 -mattr=+lzcnt | FileCheck %s define i32 @t1(i32 %x) nounwind { - %tmp = tail call i32 @llvm.ctlz.i32( i32 %x ) + %tmp = tail call i32 @llvm.ctlz.i32( i32 %x, i1 false ) ret i32 %tmp ; CHECK: t1: ; CHECK: lzcntl } -declare i32 @llvm.ctlz.i32(i32) nounwind readnone +declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone define i16 @t2(i16 %x) nounwind { - %tmp = tail call i16 @llvm.ctlz.i16( i16 %x ) + %tmp = tail call i16 @llvm.ctlz.i16( i16 %x, i1 false ) ret i16 %tmp ; CHECK: t2: ; CHECK: lzcntw } -declare i16 @llvm.ctlz.i16(i16) nounwind readnone +declare i16 @llvm.ctlz.i16(i16, i1) nounwind readnone define i64 @t3(i64 %x) nounwind { - %tmp = tail call i64 @llvm.ctlz.i64( i64 %x ) + %tmp = tail call i64 @llvm.ctlz.i64( i64 %x, i1 false ) ret i64 %tmp ; CHECK: t3: ; CHECK: lzcntq } -declare i64 @llvm.ctlz.i64(i64) nounwind readnone +declare i64 @llvm.ctlz.i64(i64, i1) nounwind readnone define i8 @t4(i8 %x) nounwind { - %tmp = tail call i8 @llvm.ctlz.i8( i8 %x ) + %tmp = tail call i8 @llvm.ctlz.i8( i8 %x, i1 false ) ret i8 %tmp ; CHECK: t4: ; CHECK: lzcntw } -declare i8 @llvm.ctlz.i8(i8) nounwind readnone +declare i8 @llvm.ctlz.i8(i8, i1) nounwind readnone Modified: llvm/trunk/test/CodeGen/X86/vec_ctbits.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_ctbits.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_ctbits.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_ctbits.ll Mon Dec 12 05:59:10 2011 @@ -1,15 +1,15 @@ ; RUN: llc < %s -march=x86-64 -declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>) -declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>) +declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>, i1) +declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1) declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) define <2 x i64> @footz(<2 x i64> %a) nounwind { - %c = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a) + %c = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a, i1 true) ret <2 x i64> %c } define <2 x i64> @foolz(<2 x i64> %a) nounwind { - %c = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %a) + %c = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %a, i1 true) ret <2 x i64> %c } define <2 x i64> @foopop(<2 x i64> %a) nounwind { Modified: llvm/trunk/test/Feature/intrinsics.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/intrinsics.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/Feature/intrinsics.ll (original) +++ llvm/trunk/test/Feature/intrinsics.ll Mon Dec 12 05:59:10 2011 @@ -15,21 +15,21 @@ declare i64 @llvm.ctpop.i64(i64) -declare i8 @llvm.cttz.i8(i8) +declare i8 @llvm.cttz.i8(i8, i1) -declare i16 @llvm.cttz.i16(i16) +declare i16 @llvm.cttz.i16(i16, i1) -declare i32 @llvm.cttz.i32(i32) +declare i32 @llvm.cttz.i32(i32, i1) -declare i64 @llvm.cttz.i64(i64) +declare i64 @llvm.cttz.i64(i64, i1) -declare i8 @llvm.ctlz.i8(i8) +declare i8 @llvm.ctlz.i8(i8, i1) -declare i16 @llvm.ctlz.i16(i16) +declare i16 @llvm.ctlz.i16(i16, i1) -declare i32 @llvm.ctlz.i32(i32) +declare i32 @llvm.ctlz.i32(i32, i1) -declare i64 @llvm.ctlz.i64(i64) +declare i64 @llvm.ctlz.i64(i64, i1) declare float @llvm.sqrt.f32(float) @@ -46,14 +46,14 @@ call i16 @llvm.ctpop.i16( i16 11 ) ; :6 [#uses=0] call i32 @llvm.ctpop.i32( i32 12 ) ; :7 [#uses=0] call i64 @llvm.ctpop.i64( i64 13 ) ; :8 [#uses=0] - call i8 @llvm.ctlz.i8( i8 14 ) ; :9 [#uses=0] - call i16 @llvm.ctlz.i16( i16 15 ) ; :10 [#uses=0] - call i32 @llvm.ctlz.i32( i32 16 ) ; :11 [#uses=0] - call i64 @llvm.ctlz.i64( i64 17 ) ; :12 [#uses=0] - call i8 @llvm.cttz.i8( i8 18 ) ; :13 [#uses=0] - call i16 @llvm.cttz.i16( i16 19 ) ; :14 [#uses=0] - call i32 @llvm.cttz.i32( i32 20 ) ; :15 [#uses=0] - call i64 @llvm.cttz.i64( i64 21 ) ; :16 [#uses=0] + call i8 @llvm.ctlz.i8( i8 14, i1 true ) ; :9 [#uses=0] + call i16 @llvm.ctlz.i16( i16 15, i1 true ) ; :10 [#uses=0] + call i32 @llvm.ctlz.i32( i32 16, i1 true ) ; :11 [#uses=0] + call i64 @llvm.ctlz.i64( i64 17, i1 true ) ; :12 [#uses=0] + call i8 @llvm.cttz.i8( i8 18, i1 true ) ; :13 [#uses=0] + call i16 @llvm.cttz.i16( i16 19, i1 true ) ; :14 [#uses=0] + call i32 @llvm.cttz.i32( i32 20, i1 true ) ; :15 [#uses=0] + call i64 @llvm.cttz.i64( i64 21, i1 true ) ; :16 [#uses=0] ret void } Modified: llvm/trunk/test/Transforms/ConstProp/2007-11-23-cttz.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstProp/2007-11-23-cttz.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ConstProp/2007-11-23-cttz.ll (original) +++ llvm/trunk/test/Transforms/ConstProp/2007-11-23-cttz.ll Mon Dec 12 05:59:10 2011 @@ -1,8 +1,8 @@ ; RUN: opt < %s -constprop -S | grep {ret i13 13} ; PR1816 -declare i13 @llvm.cttz.i13(i13) +declare i13 @llvm.cttz.i13(i13, i1) define i13 @test() { - %X = call i13 @llvm.cttz.i13(i13 0) + %X = call i13 @llvm.cttz.i13(i13 0, i1 true) ret i13 %X } Modified: llvm/trunk/test/Transforms/InstCombine/bitcount.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/bitcount.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/bitcount.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/bitcount.ll Mon Dec 12 05:59:10 2011 @@ -4,13 +4,13 @@ ; RUN: grep -v declare | not grep llvm.ct declare i31 @llvm.ctpop.i31(i31 %val) -declare i32 @llvm.cttz.i32(i32 %val) -declare i33 @llvm.ctlz.i33(i33 %val) +declare i32 @llvm.cttz.i32(i32 %val, i1) +declare i33 @llvm.ctlz.i33(i33 %val, i1) define i32 @test(i32 %A) { %c1 = call i31 @llvm.ctpop.i31(i31 12415124) - %c2 = call i32 @llvm.cttz.i32(i32 87359874) - %c3 = call i33 @llvm.ctlz.i33(i33 87359874) + %c2 = call i32 @llvm.cttz.i32(i32 87359874, i1 true) + %c3 = call i33 @llvm.ctlz.i33(i33 87359874, i1 true) %t1 = zext i31 %c1 to i32 %t3 = trunc i33 %c3 to i32 %r1 = add i32 %t1, %c2 Modified: llvm/trunk/test/Transforms/InstCombine/intrinsics.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/intrinsics.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/intrinsics.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/intrinsics.ll Mon Dec 12 05:59:10 2011 @@ -5,10 +5,10 @@ declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8) declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8) declare double @llvm.powi.f64(double, i32) nounwind readonly -declare i32 @llvm.cttz.i32(i32) nounwind readnone -declare i32 @llvm.ctlz.i32(i32) nounwind readnone +declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone +declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone declare i32 @llvm.ctpop.i32(i32) nounwind readnone -declare i8 @llvm.ctlz.i8(i8) nounwind readnone +declare i8 @llvm.ctlz.i8(i8, i1) nounwind readnone define i8 @uaddtest1(i8 %A, i8 %B) { %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %A, i8 %B) @@ -161,7 +161,7 @@ entry: %or = or i32 %a, 8 %and = and i32 %or, -8 - %count = tail call i32 @llvm.cttz.i32(i32 %and) nounwind readnone + %count = tail call i32 @llvm.cttz.i32(i32 %and, i1 true) nounwind readnone ret i32 %count ; CHECK: @cttz ; CHECK-NEXT: entry: @@ -172,7 +172,7 @@ entry: %or = or i8 %a, 32 %and = and i8 %or, 63 - %count = tail call i8 @llvm.ctlz.i8(i8 %and) nounwind readnone + %count = tail call i8 @llvm.ctlz.i8(i8 %and, i1 true) nounwind readnone ret i8 %count ; CHECK: @ctlz ; CHECK-NEXT: entry: @@ -181,10 +181,10 @@ define void @cmp.simplify(i32 %a, i32 %b, i1* %c) { entry: - %lz = tail call i32 @llvm.ctlz.i32(i32 %a) nounwind readnone + %lz = tail call i32 @llvm.ctlz.i32(i32 %a, i1 true) nounwind readnone %lz.cmp = icmp eq i32 %lz, 32 store volatile i1 %lz.cmp, i1* %c - %tz = tail call i32 @llvm.cttz.i32(i32 %a) nounwind readnone + %tz = tail call i32 @llvm.cttz.i32(i32 %a, i1 true) nounwind readnone %tz.cmp = icmp ne i32 %tz, 32 store volatile i1 %tz.cmp, i1* %c %pop = tail call i32 @llvm.ctpop.i32(i32 %b) nounwind readnone @@ -203,7 +203,7 @@ define i32 @cttz_simplify1(i32 %x) nounwind readnone ssp { - %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %x) ; [#uses=1] + %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true) ; [#uses=1] %shr3 = lshr i32 %tmp1, 5 ; [#uses=1] ret i32 %shr3 Modified: llvm/trunk/test/Transforms/InstCombine/sext.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sext.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/sext.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/sext.ll Mon Dec 12 05:59:10 2011 @@ -3,8 +3,8 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" declare i32 @llvm.ctpop.i32(i32) -declare i32 @llvm.ctlz.i32(i32) -declare i32 @llvm.cttz.i32(i32) +declare i32 @llvm.ctlz.i32(i32, i1) +declare i32 @llvm.cttz.i32(i32, i1) define i64 @test1(i32 %x) { %t = call i32 @llvm.ctpop.i32(i32 %x) @@ -16,7 +16,7 @@ } define i64 @test2(i32 %x) { - %t = call i32 @llvm.ctlz.i32(i32 %x) + %t = call i32 @llvm.ctlz.i32(i32 %x, i1 true) %s = sext i32 %t to i64 ret i64 %s @@ -25,7 +25,7 @@ } define i64 @test3(i32 %x) { - %t = call i32 @llvm.cttz.i32(i32 %x) + %t = call i32 @llvm.cttz.i32(i32 %x, i1 true) %s = sext i32 %t to i64 ret i64 %s Modified: llvm/trunk/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll?rev=146370&r1=146369&r2=146370&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll (original) +++ llvm/trunk/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll Mon Dec 12 05:59:10 2011 @@ -6,9 +6,9 @@ define i32 @x(i32 %b) { entry: - %val = call i32 @llvm.cttz.i32(i32 undef) + %val = call i32 @llvm.cttz.i32(i32 undef, i1 true) ret i32 %val } -declare i32 @llvm.cttz.i32(i32) +declare i32 @llvm.cttz.i32(i32, i1) From nobled at dreamwidth.org Mon Dec 12 07:05:41 2011 From: nobled at dreamwidth.org (nobled) Date: Mon, 12 Dec 2011 08:05:41 -0500 Subject: [llvm-commits] [PATCH] cmake: work with CMake < 2.8.5 Message-ID: CMake versions 2.8.4 and earlier were giving this error since r146323: "string end index: -1 is out of range 0 - 6" Passing -1 as the length of the desired substring was a new feature added in CMake 2.8.5: http://www.cmake.org/Bug/view.php?id=10740 -------------- next part -------------- A non-text attachment was scrubbed... Name: 0004-cmake-work-with-CMake-2.8.5.patch Type: text/x-patch Size: 1387 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20111212/14e48dde/attachment.bin From nobled at dreamwidth.org Mon Dec 12 07:06:25 2011 From: nobled at dreamwidth.org (Dylan Noblesmith) Date: Mon, 12 Dec 2011 13:06:25 -0000 Subject: [llvm-commits] [llvm] r146372 - /llvm/trunk/cmake/modules/VersionFromVCS.cmake Message-ID: <20111212130625.45DFF1BE003@llvm.org> Author: nobled Date: Mon Dec 12 07:06:25 2011 New Revision: 146372 URL: http://llvm.org/viewvc/llvm-project?rev=146372&view=rev Log: cmake: work with CMake < 2.8.5 CMake versions 2.8.4 and earlier were giving this error since r146323: "string end index: -1 is out of range 0 - 6" Passing -1 as the length of the desired substring was a new feature added in CMake 2.8.5: http://www.cmake.org/Bug/view.php?id=10740 Modified: llvm/trunk/cmake/modules/VersionFromVCS.cmake Modified: llvm/trunk/cmake/modules/VersionFromVCS.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/VersionFromVCS.cmake?rev=146372&r1=146371&r2=146372&view=diff ============================================================================== --- llvm/trunk/cmake/modules/VersionFromVCS.cmake (original) +++ llvm/trunk/cmake/modules/VersionFromVCS.cmake Mon Dec 12 07:06:25 2011 @@ -30,7 +30,9 @@ OUTPUT_VARIABLE git_output) if( git_result EQUAL 0 ) string(REGEX MATCH r[0-9]+ git_svn_rev ${git_output}) - string(SUBSTRING "${git_svn_rev}" 1 -1 git_svn_rev_number) + string(LENGTH "${git_svn_rev}" rev_length) + math(EXPR rev_length "${rev_length}-1") + string(SUBSTRING "${git_svn_rev}" 1 ${rev_length} git_svn_rev_number) set(SVN_REVISION ${git_svn_rev_number} PARENT_SCOPE) set(git_svn_rev "-svn-${git_svn_rev}") From stpworld at narod.ru Mon Dec 12 07:13:55 2011 From: stpworld at narod.ru (Stepan Dyatkovskiy) Date: Mon, 12 Dec 2011 17:13:55 +0400 Subject: [llvm-commits] [LLVM, loop-unswitch, bugfix for #11429] Wrong behaviour for switches. In-Reply-To: <4EE4D8FE.6020309@narod.ru> References: <4ECF4A5A.9030607@narod.ru> <4ED36D99.1080306@narod.ru> <4ED51EEC.6050000@narod.ru> <4ED749D0.8030101@narod.ru> <4ED88CDF.2020104@narod.ru> <4EDCC136.1040903@narod.ru> <566DBA1B-7099-44E0-B2EB-3413A054F5E3@apple.com> <4EDF700A.3080605@narod.ru> <9F9EFCC2-3F32-49F8-97D6-B8BAC580B6F7@apple.com> <4EE36B3F.3090307@narod.ru> <4EE4D8FE.6020309@narod.ru> Message-ID: <4EE5FE13.8090908@narod.ru> Ping. -Stepan. Stepan Dyatkovskiy wrote: > Ping. > > -Stepan. > > Stepan Dyatkovskiy wrote: >> I fixed code heuristics. How it works now: >> >> 1. Calculate average number of produced instructions and basics blocks: >> number-of-instructions=current-loop->number-of-instructions * >> unswitched-number >> number-of-bb=current-loop->number-of-bb * unswitched-number >> >> 2. If number-of-instructions> Threshold || number-of-bb*5> Threshold, >> stop unswitching. >> >> By default Threshold is 50. But user can set custom threshold using >> -loop-unswitch-threshold option. This option existed >> before my patch, and I kept it without changes though. >> >> I compiled ffmpeg (ffmpeg.org) with llvm + clang toolchain (with and >> without my patch). I got the next results: >> >> Without patch: ffmpeg size is 7369612 bytes. >> Threshold = 50: ffmpeg size is 7349132 bytes (less then in ToT version). >> Threshold = 200: ffmpeg size is 7439244 bytes. >> >> I also checked the ffmpeg build time in all cases it was 2 mins, 35 secs. >> Transcoding time with ffmpeg (mp3 -> mp2) in all cases was also the >> same: process took 1 min, 19 secs. >> >> I added unit test that checks unswitch kicking in case of insufficient >> size. Unit tests and fixed patch (default threshold is 50) are attached >> to this post. >> >> Thanks. >> -Stepan. >> >> Dan Gohman wrote: >>> >>> On Dec 7, 2011, at 5:54 AM, Stepan Dyatkovskiy wrote: >>> >>>> Dan Gohman wrote: >>>> >>>>> This sounds good. How sure are you that the existing size heuristics >>>>> are actually kicking in for the new unrollings? I don't have a reason >>>>> to suspect a bug, other than that you're asking code to work in cases >>>>> that it hasn't before. >>>> >>>> The main reason to suspect a bug is that the pass doesn't work as it >>>> was planned initially. I made this conclusion after reading the code >>>> and its comments. Especially this ones (LoopUnswitch.cpp, string #277): >>>> // FIXME: this should choose the most expensive case! >>>> // FIXME: scan for a case with a non-critical edge? >>>> Programmer placed the stub by now: >>>> Constant *UnswitchVal = SI->getCaseValue(1); >>>> >>>> Probably he missed one thing. Since we selected 1-st case always, all >>>> other cases will never unswitched. But there is no comments about it. >>>> This "feature" looks unplanned. If not - ok, it is not a bug then. I >>>> proposed to insert additional comments though. >>>> >>>> Size heuristics currently analyses the size of loop to be unswitched. >>>> If number of instructions, or number of BBs exceeds some threshold, >>>> then the loop will skipped. We can also control the number cases to >>>> be unswitched. >>> >>> Oh, I don't doubt it may a bug. And there's no master plan behind >>> non-trivial loop unswitching for switches. My point was just that >>> it's been the way it is for a long time, and possibly other things >>> have become accustomed to it, or accidentally reliant on it, >>> working that way. >>> >>>> >>>>> Each unswitched case has the potential to increase performance, >>>>> if conditions are favorable. But if code size is increased, there's >>>>> also the possibility of decreased performance. >>>> >>>> Before unswitchment, loop executes switch N times. The switch is >>>> lowered to several "icmp" checks (let it be "n"). Depending on >>>> lowering algorithm selected the "n" is either linear or logarithmic >>>> function on cases number ( n=k*num_cases or n=k*log(num_cases) ). >>>> Summary we have N*n "icmp" checks. >>>> >>>> After unswitchment all checks will moved out of loop. And we got >>>> 1*n_us "icmp" checks in this case. But the "n_us" is always linear >>>> after unswitchment. So if (1*n_us< N*n) then performance will >>>> increased. Else - it will decreased. >>> >>> On most architectures, those checks will usually be predictable -- the >>> conditions are loop-invariant after all -- and thus fairly cheap, >>> depending >>> on what else is in the loop. But this isn't important here. >>> >>>> >>>>> If you can confirm >>>>> that that's working as expected, it should be fine. >>>> >>>> Did you mean the regression tests? If yes - they are attached in >>>> initial post. These tests checks that all working as expected for >>>> loop with single switch instruction and for loop with two switches. >>>> >>>> In my patch I fixed the stub described above. I also can improve the >>>> size heuristics if you need. >>> >>> >>> I just meant that it would be good to have testcases in which the code >>> size heuristic actually has to kick in and prevent it from unswitching >>> out of control. >>> >>> Also, if you could do a rough check of code size on some general >>> real-world >>> application code, that would be good too. >>> >>> With these precautions, I think the patch is fine. >>> >>> Dan >>> >> >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From grosser at fim.uni-passau.de Mon Dec 12 08:52:31 2011 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Mon, 12 Dec 2011 14:52:31 -0000 Subject: [llvm-commits] [polly] r146373 - /polly/trunk/utils/checkout_cloog.sh Message-ID: <20111212145231.D29471BE003@llvm.org> Author: grosser Date: Mon Dec 12 08:52:31 2011 New Revision: 146373 URL: http://llvm.org/viewvc/llvm-project?rev=146373&view=rev Log: Upgrade to CLooG 0.17.0 Modified: polly/trunk/utils/checkout_cloog.sh Modified: polly/trunk/utils/checkout_cloog.sh URL: http://llvm.org/viewvc/llvm-project/polly/trunk/utils/checkout_cloog.sh?rev=146373&r1=146372&r2=146373&view=diff ============================================================================== --- polly/trunk/utils/checkout_cloog.sh (original) +++ polly/trunk/utils/checkout_cloog.sh Mon Dec 12 08:52:31 2011 @@ -1,6 +1,6 @@ #!/bin/sh -CLOOG_HASH="63add93017c20f63455d67cf5127661dbb016d33" +CLOOG_HASH="57470e76bfd58a0c38c598e816411663193e0f45" ISL_HASH="0a2810732967eee50d8c55a371a28704d8a1ec17" PWD=`pwd` From pbarrio at die.upm.es Mon Dec 12 05:59:51 2011 From: pbarrio at die.upm.es (Pablo Barrio) Date: Mon, 12 Dec 2011 12:59:51 +0100 Subject: [llvm-commits] [LLVMdev] Turning on/off instruction extensions In-Reply-To: <1322856408.2507.2956.camel@sapling> References: <1322145210.2507.451.camel@sapling> <5D288300-8F23-4E9B-8846-57A88BF061F3@die.upm.es> <1322502723.2507.790.camel@sapling> <1322581121.2507.1184.camel@sapling> <1322856408.2507.2956.camel@sapling> Message-ID: <4EE5ECB7.4070300@die.upm.es> Hi Hal, On 02/12/11 21:06, Hal Finkel wrote: > On Fri, 2011-12-02 at 19:08 +0100, Pablo Barrio wrote: >> I applied the patch to the trunk version successfully, although I get an error in between: >> >> 1 out of 1 hunk FAILED -- saving rejects to file lib/Transforms/IPO/CMakeLists.txt.rej >> >> Can I ignore the error? The patch exits normally except for that error. > The attached patch should apply cleanly. > > Thanks for the feedback, > Hal I'm still getting the following error: --- 1 out of 3 hunks FAILED -- saving rejects to file lib/Transforms/IPO/PassManagerBuilder.cpp.rej --- I'm using LLVM rev. 146369 (current trunk). Is it the same as you? If not, tell me your revision and I'll try again. Suggestion: would it be possible to have a patch for the stable version (LLVM 3.0)? Thanks ahead, Pablo >> Also, I tried to apply the patch to the LLVM 3.0 but does not work at all. Is the trunk version the only one where the patch can be applied? >> >> Thanks ahead, >> Pablo >> >> On 29/11/2011, at 16:38, Hal Finkel wrote: >> >>> On Tue, 2011-11-29 at 16:26 +0100, Pablo Barrio wrote: >>>> On 28/11/2011, at 18:52, Hal Finkel wrote: >>>> >>>>> On Mon, 2011-11-28 at 17:49 +0100, Pablo Barrio wrote: >>>>>> How can I install the patch? Any step-by-step guide? >>>>> First, grab the trunk versions of llvm and clang. This is detailed on >>>>> http://clang.llvm.org/get_started.html >>>>> >>>>> Then you apply the patch. On a Unix-like system, this is something like: >>>>> cd llvm >>>>> patch -p1< /path/to/the-patch-file.diff >>>>> >>>> I tried to apply the patch to llvm 2.9 (not the trunk) but it shows a lot of "... hunk FAILED -- saving rejects to file ...". Is it safe to ignore these errors? Is it impossible to apply this patch to LLVM 2.9? Do you have a version of the patch compatible with 2.9? >>>> >>> Unfortunately, I don't have a version for 2.9. >>> >>> -Hal >>> >>>> Right now I cannot switch to the trunk version. >>>> >>>> Thanks in advance, >>>> Pablo >>>> >>>>> Then you rebuild. >>>>> >>>>> If you have any further questions, or need a more-detailed answer, >>>>> please let me know. >>>>> >>>>> -Hal >>>>> >>>>>> Thanks, >>>>>> Pablo >>>>>> >>>>>> On 24/11/2011, at 15:33, Hal Finkel wrote: >>>>>> >>>>>>> On Thu, 2011-11-24 at 15:09 +0100, Pablo Barrio L?pez-Cortijo wrote: >>>>>>>> Hi everybody, >>>>>>>> >>>>>>>> I'm trying to run some examples with different backend options (turning >>>>>>>> on/off SSE, 3dnow, or MMX instructions). However, I don't see any >>>>>>>> difference in terms of execution time. Does anybody know which language >>>>>>>> constructs (in C/C++ preferably) should I try to make these instructions >>>>>>>> generated (and thus make a difference between a backend that enables >>>>>>>> them or not) ? >>>>>>>> >>>>>>>> I tried generating vector instructions with loops but it's not >>>>>>>> happening. Perhaps Polly can generate vector instructions? >>>>>>> You can also try my basic-block autovectorization patch. >>>>>>> >>>>>>> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20111121/132206.html >>>>>>> >>>>>>> After applying the patch (I recommend applying it to the current trunk), >>>>>>> then run clang with the flags: >>>>>>> -mllvm -vectorize -mllvm -unroll-allow-partial >>>>>>> (the -unroll-allow-partial is not necessary for the vectorization, but >>>>>>> tends to expose additional vectorization opportunities). The basic-block >>>>>>> vectorizer has a number of flags that can be used to customize its >>>>>>> behavior, so if it is not vectorizing something that you think it should >>>>>>> be (or is doing something performance detrimental), please let me know >>>>>>> and I'll be happy to help. >>>>>>> >>>>>>> -Hal >>>>>>> >>>>>>>> Thanks ahead, >>>>>>>> >>>>>>>> Pablo >>>>>>>> DIE-UPM >>>>>>>> Madrid >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> LLVM Developers mailing list >>>>>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>>>>> -- >>>>>>> Hal Finkel >>>>>>> Postdoctoral Appointee >>>>>>> Leadership Computing Facility >>>>>>> Argonne National Laboratory >>>>>>> >>>>> -- >>>>> Hal Finkel >>>>> Postdoctoral Appointee >>>>> Leadership Computing Facility >>>>> Argonne National Laboratory >>>>> >>> -- >>> Hal Finkel >>> Postdoctoral Appointee >>> Leadership Computing Facility >>> Argonne National Laboratory >>> -- Pablo Barrio Dpt. Electrical Engineering - Technical University of Madrid Despacho C-203 Avda. Complutense s/n, 28040 Madrid (+34) 915495700 ext. 4234 @: pbarrio at die.upm.es From hfinkel at anl.gov Mon Dec 12 10:07:51 2011 From: hfinkel at anl.gov (Hal Finkel) Date: Mon, 12 Dec 2011 10:07:51 -0600 Subject: [llvm-commits] [LLVMdev] Turning on/off instruction extensions In-Reply-To: <4EE5ECB7.4070300@die.upm.es> References: <1322145210.2507.451.camel@sapling> <5D288300-8F23-4E9B-8846-57A88BF061F3@die.upm.es> <1322502723.2507.790.camel@sapling> <1322581121.2507.1184.camel@sapling> <1322856408.2507.2956.camel@sapling> <4EE5ECB7.4070300@die.upm.es> Message-ID: <1323706071.590.381.camel@sapling> On Mon, 2011-12-12 at 12:59 +0100, Pablo Barrio wrote: > Hi Hal, > > On 02/12/11 21:06, Hal Finkel wrote: > > On Fri, 2011-12-02 at 19:08 +0100, Pablo Barrio wrote: > >> I applied the patch to the trunk version successfully, although I get an error in between: > >> > >> 1 out of 1 hunk FAILED -- saving rejects to file lib/Transforms/IPO/CMakeLists.txt.rej > >> > >> Can I ignore the error? The patch exits normally except for that error. > > The attached patch should apply cleanly. > > > > Thanks for the feedback, > > Hal > > I'm still getting the following error: > > --- > 1 out of 3 hunks FAILED -- saving rejects to file > lib/Transforms/IPO/PassManagerBuilder.cpp.rej > --- > > I'm using LLVM rev. 146369 (current trunk). Is it the same as you? If > not, tell me your revision and I'll try again. LLVM develops quickly ;) -- The patch you have is again out of sync. I'll send an updated patch to the list soon. > > Suggestion: would it be possible to have a patch for the stable version > (LLVM 3.0)? I'll add that to my TODO list, but I probably won't get to it until after the current patch finishes code review. I'll worry about backporting after that. -Hal > > Thanks ahead, > Pablo > >> Also, I tried to apply the patch to the LLVM 3.0 but does not work at all. Is the trunk version the only one where the patch can be applied? > >> > >> Thanks ahead, > >> Pablo > >> > >> On 29/11/2011, at 16:38, Hal Finkel wrote: > >> > >>> On Tue, 2011-11-29 at 16:26 +0100, Pablo Barrio wrote: > >>>> On 28/11/2011, at 18:52, Hal Finkel wrote: > >>>> > >>>>> On Mon, 2011-11-28 at 17:49 +0100, Pablo Barrio wrote: > >>>>>> How can I install the patch? Any step-by-step guide? > >>>>> First, grab the trunk versions of llvm and clang. This is detailed on > >>>>> http://clang.llvm.org/get_started.html > >>>>> > >>>>> Then you apply the patch. On a Unix-like system, this is something like: > >>>>> cd llvm > >>>>> patch -p1< /path/to/the-patch-file.diff > >>>>> > >>>> I tried to apply the patch to llvm 2.9 (not the trunk) but it shows a lot of "... hunk FAILED -- saving rejects to file ...". Is it safe to ignore these errors? Is it impossible to apply this patch to LLVM 2.9? Do you have a version of the patch compatible with 2.9? > >>>> > >>> Unfortunately, I don't have a version for 2.9. > >>> > >>> -Hal > >>> > >>>> Right now I cannot switch to the trunk version. > >>>> > >>>> Thanks in advance, > >>>> Pablo > >>>> > >>>>> Then you rebuild. > >>>>> > >>>>> If you have any further questions, or need a more-detailed answer, > >>>>> please let me know. > >>>>> > >>>>> -Hal > >>>>> > >>>>>> Thanks, > >>>>>> Pablo > >>>>>> > >>>>>> On 24/11/2011, at 15:33, Hal Finkel wrote: > >>>>>> > >>>>>>> On Thu, 2011-11-24 at 15:09 +0100, Pablo Barrio L?pez-Cortijo wrote: > >>>>>>>> Hi everybody, > >>>>>>>> > >>>>>>>> I'm trying to run some examples with different backend options (turning > >>>>>>>> on/off SSE, 3dnow, or MMX instructions). However, I don't see any > >>>>>>>> difference in terms of execution time. Does anybody know which language > >>>>>>>> constructs (in C/C++ preferably) should I try to make these instructions > >>>>>>>> generated (and thus make a difference between a backend that enables > >>>>>>>> them or not) ? > >>>>>>>> > >>>>>>>> I tried generating vector instructions with loops but it's not > >>>>>>>> happening. Perhaps Polly can generate vector instructions? > >>>>>>> You can also try my basic-block autovectorization patch. > >>>>>>> > >>>>>>> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20111121/132206.html > >>>>>>> > >>>>>>> After applying the patch (I recommend applying it to the current trunk), > >>>>>>> then run clang with the flags: > >>>>>>> -mllvm -vectorize -mllvm -unroll-allow-partial > >>>>>>> (the -unroll-allow-partial is not necessary for the vectorization, but > >>>>>>> tends to expose additional vectorization opportunities). The basic-block > >>>>>>> vectorizer has a number of flags that can be used to customize its > >>>>>>> behavior, so if it is not vectorizing something that you think it should > >>>>>>> be (or is doing something performance detrimental), please let me know > >>>>>>> and I'll be happy to help. > >>>>>>> > >>>>>>> -Hal > >>>>>>> > >>>>>>>> Thanks ahead, > >>>>>>>> > >>>>>>>> Pablo > >>>>>>>> DIE-UPM > >>>>>>>> Madrid > >>>>>>>> > >>>>>>>> _______________________________________________ > >>>>>>>> LLVM Developers mailing list > >>>>>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > >>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >>>>>>> -- > >>>>>>> Hal Finkel > >>>>>>> Postdoctoral Appointee > >>>>>>> Leadership Computing Facility > >>>>>>> Argonne National Laboratory > >>>>>>> > >>>>> -- > >>>>> Hal Finkel > >>>>> Postdoctoral Appointee > >>>>> Leadership Computing Facility > >>>>> Argonne National Laboratory > >>>>> > >>> -- > >>> Hal Finkel > >>> Postdoctoral Appointee > >>> Leadership Computing Facility > >>> Argonne National Laboratory > >>> > > -- Hal Finkel Postdoctoral Appointee Leadership Computing Facility Argonne National Laboratory From stoklund at 2pi.dk Mon Dec 12 10:16:24 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 12 Dec 2011 16:16:24 -0000 Subject: [llvm-commits] [llvm] r146374 - in /llvm/trunk/utils/TableGen: CodeGenRegisters.cpp CodeGenRegisters.h Message-ID: <20111212161624.4E3641BE003@llvm.org> Author: stoklund Date: Mon Dec 12 10:16:24 2011 New Revision: 146374 URL: http://llvm.org/viewvc/llvm-project?rev=146374&view=rev Log: Extract a method. Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.cpp llvm/trunk/utils/TableGen/CodeGenRegisters.h Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.cpp?rev=146374&r1=146373&r2=146374&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenRegisters.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenRegisters.cpp Mon Dec 12 10:16:24 2011 @@ -582,6 +582,23 @@ Key2RC.insert(std::make_pair(K, RC)); } +// Create a synthetic sub-class if it is missing. +CodeGenRegisterClass* +CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC, + const CodeGenRegister::Set *Members, + StringRef Name) { + // Synthetic sub-class has the same size and alignment as RC. + CodeGenRegisterClass::Key K(Members, RC->SpillSize, RC->SpillAlignment); + RCKeyMap::const_iterator FoundI = Key2RC.find(K); + if (FoundI != Key2RC.end()) + return FoundI->second; + + // Sub-class doesn't exist, create a new one. + CodeGenRegisterClass *NewRC = new CodeGenRegisterClass(Name, K); + addToMaps(NewRC); + return NewRC; +} + CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) { if (CodeGenRegisterClass *RC = Def2RC[Def]) return RC; @@ -778,21 +795,11 @@ RC.setSubClassWithSubReg(SubIdx, &RC); continue; } - // This is a real subset. See if we have a matching class. - CodeGenRegisterClass::Key K(&I->second, RC.SpillSize, RC.SpillAlignment); - RCKeyMap::const_iterator FoundI = Key2RC.find(K); - if (FoundI != Key2RC.end()) { - RC.setSubClassWithSubReg(SubIdx, FoundI->second); - continue; - } - - // Class doesn't exist. - CodeGenRegisterClass *NewRC = - new CodeGenRegisterClass(RC.getName() + "_with_" + - I->first->getName(), K); - addToMaps(NewRC); - RC.setSubClassWithSubReg(SubIdx, NewRC); + CodeGenRegisterClass *SubRC = + getOrCreateSubClass(&RC, &I->second, + RC.getName() + "_with_" + I->first->getName()); + RC.setSubClassWithSubReg(SubIdx, SubRC); } } } Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.h?rev=146374&r1=146373&r2=146374&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenRegisters.h (original) +++ llvm/trunk/utils/TableGen/CodeGenRegisters.h Mon Dec 12 10:16:24 2011 @@ -237,6 +237,11 @@ // Add RC to *2RC maps. void addToMaps(CodeGenRegisterClass*); + // Create a synthetic sub-class if it is missing. + CodeGenRegisterClass *getOrCreateSubClass(const CodeGenRegisterClass *RC, + const CodeGenRegister::Set *Membs, + StringRef Name); + // Infer missing register classes. void computeInferredRegisterClasses(); From stoklund at 2pi.dk Mon Dec 12 10:41:01 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 12 Dec 2011 08:41:01 -0800 Subject: [llvm-commits] [llvm] r146363 - in /llvm/trunk: include/llvm/Support/FileSystem.h lib/Support/Unix/PathV2.inc lib/Support/Windows/PathV2.inc lib/Support/Windows/Windows.h unittests/Support/Path.cpp In-Reply-To: <20111212060402.62D332A6C12C@llvm.org> References: <20111212060402.62D332A6C12C@llvm.org> Message-ID: <330FD7CC-BCF7-4532-9262-AB3A355A4D19@2pi.dk> On Dec 11, 2011, at 10:04 PM, Michael J. Spencer wrote: > Author: mspencer > Date: Mon Dec 12 00:04:01 2011 > New Revision: 146363 > > URL: http://llvm.org/viewvc/llvm-project?rev=146363&view=rev > Log: > Support/FileSystem: Implement canonicalize. > > Modified: > llvm/trunk/include/llvm/Support/FileSystem.h > llvm/trunk/lib/Support/Unix/PathV2.inc > llvm/trunk/lib/Support/Windows/PathV2.inc > llvm/trunk/lib/Support/Windows/Windows.h > llvm/trunk/unittests/Support/Path.cpp This is failing on OS X Lion: ******************** TEST 'LLVM-Unit :: Support/Release+Asserts/SupportTests/FileSystemTest.Canonicalize' FAILED ******************** Note: Google Test filter = FileSystemTest.Canonicalize [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from FileSystemTest [ RUN ] FileSystemTest.Canonicalize /Volumes/Krask/g/llvm/unittests/Support/Path.cpp:336: Failure Value of: res.str().find("canonicalize") != StringRef::npos Actual: false Expected: true [ FAILED ] FileSystemTest.Canonicalize (5 ms) [----------] 1 test from FileSystemTest (5 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. (6 ms total) [ PASSED ] 0 tests. [ FAILED ] 1 test, listed below: [ FAILED ] FileSystemTest.Canonicalize 1 FAILED TEST From stoklund at 2pi.dk Mon Dec 12 10:49:37 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 12 Dec 2011 16:49:37 -0000 Subject: [llvm-commits] [llvm] r146375 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Message-ID: <20111212164937.F21F41BE003@llvm.org> Author: stoklund Date: Mon Dec 12 10:49:37 2011 New Revision: 146375 URL: http://llvm.org/viewvc/llvm-project?rev=146375&view=rev Log: Add a -arm-align-constant-islands flag, default off. Order constant pool entries by descending alignment in the initial island to ensure packing and correct alignment. When the command line flag is set, also align the basic block containing the constant pool entries. This is only a partial implementation of constant island alignment. More to come. Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=146375&r1=146374&r2=146375&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Dec 12 10:49:37 2011 @@ -52,6 +52,10 @@ AdjustJumpTableBlocks("arm-adjust-jump-tables", cl::Hidden, cl::init(true), cl::desc("Adjust basic block layout to better use TB[BH]")); +static cl::opt +AlignConstantIslands("arm-align-constant-island", cl::Hidden, + cl::desc("Align constant islands in code")); + /// UnknownPadding - Return the worst case padding that could result from /// unknown offset bits. This does not include alignment padding caused by /// known offset bits. @@ -487,8 +491,18 @@ MachineBasicBlock *BB = MF.CreateMachineBasicBlock(); MF.push_back(BB); - // Mark the basic block as 4-byte aligned as required by the const-pool. - BB->setAlignment(2); + // MachineConstantPool measures alignment in bytes. We measure in log2(bytes). + unsigned MaxAlign = Log2_32(MF.getConstantPool()->getConstantPoolAlignment()); + + // Mark the basic block as required by the const-pool. + // If AlignConstantIslands isn't set, use 4-byte alignment for everything. + BB->setAlignment(AlignConstantIslands ? MaxAlign : 2); + + // Order the entries in BB by descending alignment. That ensures correct + // alignment of all entries as long as BB is sufficiently aligned. Keep + // track of the insertion point for each alignment. We are going to bucket + // sort the entries as they are created. + SmallVector InsPoint(MaxAlign + 1, BB->end()); // Add all of the constants from the constant pool to the end block, use an // identity mapping of CPI's to CPE's. @@ -498,23 +512,35 @@ const TargetData &TD = *MF.getTarget().getTargetData(); for (unsigned i = 0, e = CPs.size(); i != e; ++i) { unsigned Size = TD.getTypeAllocSize(CPs[i].getType()); - // Verify that all constant pool entries are a multiple of 4 bytes. If not, - // we would have to pad them out or something so that instructions stay - // aligned. - assert((Size & 3) == 0 && "CP Entry not multiple of 4 bytes!"); + assert(Size >= 4 && "Too small constant pool entry"); + unsigned Align = CPs[i].getAlignment(); + assert(isPowerOf2_32(Align) && "Invalid alignment"); + // Verify that all constant pool entries are a multiple of their alignment. + // If not, we would have to pad them out so that instructions stay aligned. + assert((Size % Align) == 0 && "CP Entry not multiple of 4 bytes!"); + + // Insert CONSTPOOL_ENTRY before entries with a smaller alignment. + unsigned LogAlign = Log2_32(Align); + MachineBasicBlock::iterator InsAt = InsPoint[LogAlign]; MachineInstr *CPEMI = - BuildMI(BB, DebugLoc(), TII->get(ARM::CONSTPOOL_ENTRY)) + BuildMI(*BB, InsAt, DebugLoc(), TII->get(ARM::CONSTPOOL_ENTRY)) .addImm(i).addConstantPoolIndex(i).addImm(Size); CPEMIs.push_back(CPEMI); + // Ensure that future entries with higher alignment get inserted before + // CPEMI. This is bucket sort with iterators. + for (unsigned a = LogAlign + 1; a < MaxAlign; ++a) + if (InsPoint[a] == InsAt) + InsPoint[a] = CPEMI; + // Add a new CPEntry, but no corresponding CPUser yet. std::vector CPEs; CPEs.push_back(CPEntry(CPEMI, i)); CPEntries.push_back(CPEs); ++NumCPEs; - DEBUG(dbgs() << "Moved CPI#" << i << " to end of function as #" << i - << "\n"); + DEBUG(dbgs() << "Moved CPI#" << i << " to end of function\n"); } + DEBUG(BB->dump()); } /// BBHasFallthrough - Return true if the specified basic block can fallthrough From daniel at zuster.org Mon Dec 12 11:31:18 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 12 Dec 2011 09:31:18 -0800 Subject: [llvm-commits] Fix llvm-config In-Reply-To: <6AE1604EE3EC5F4296C096518C6B77EE1AA4D18698@mail.accesssoftek.com> References: <6AE1604EE3EC5F4296C096518C6B77EE1AA4D18698@mail.accesssoftek.com> Message-ID: Hi Danil, I don't understand why this is necessary yet. If you are doing a cross compilation, then your llvm-config should be in a development tree, and the first if() branch in that set should be followed, which already handles the BuildTools case. Can you give me more information about the failure, what tool is being run, and the exact command line? Thanks, - Daniel On Fri, Dec 9, 2011 at 2:41 PM, Danil Malyshev wrote: > Hello everyone, > > > > LLVM cross-compilation stops when it tries linking tools with an error > message that the library needed to link not found. > > The attached patch fixed it. > > > > Regards, > > Danil > > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From rdivacky at freebsd.org Mon Dec 12 11:34:04 2011 From: rdivacky at freebsd.org (Roman Divacky) Date: Mon, 12 Dec 2011 17:34:04 -0000 Subject: [llvm-commits] [llvm] r146377 - in /llvm/trunk: include/llvm/Support/ELF.h lib/MC/MCELF.cpp lib/MC/MCELFStreamer.cpp lib/MC/MCParser/ELFAsmParser.cpp test/MC/ELF/type.s Message-ID: <20111212173405.083FC1BE003@llvm.org> Author: rdivacky Date: Mon Dec 12 11:34:04 2011 New Revision: 146377 URL: http://llvm.org/viewvc/llvm-project?rev=146377&view=rev Log: Add support for gnu_indirect_function. Modified: llvm/trunk/include/llvm/Support/ELF.h llvm/trunk/lib/MC/MCELF.cpp llvm/trunk/lib/MC/MCELFStreamer.cpp llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp llvm/trunk/test/MC/ELF/type.s Modified: llvm/trunk/include/llvm/Support/ELF.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ELF.h?rev=146377&r1=146376&r2=146377&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/ELF.h (original) +++ llvm/trunk/include/llvm/Support/ELF.h Mon Dec 12 11:34:04 2011 @@ -888,6 +888,7 @@ STT_TLS = 6, // Thread local data object STT_LOOS = 7, // Lowest operating system-specific symbol type STT_HIOS = 8, // Highest operating system-specific symbol type + STT_GNU_IFUNC = 10, // GNU indirect function STT_LOPROC = 13, // Lowest processor-specific symbol type STT_HIPROC = 15 // Highest processor-specific symbol type }; Modified: llvm/trunk/lib/MC/MCELF.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELF.cpp?rev=146377&r1=146376&r2=146377&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCELF.cpp (original) +++ llvm/trunk/lib/MC/MCELF.cpp Mon Dec 12 11:34:04 2011 @@ -37,7 +37,7 @@ assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT || Type == ELF::STT_FUNC || Type == ELF::STT_SECTION || Type == ELF::STT_FILE || Type == ELF::STT_COMMON || - Type == ELF::STT_TLS); + Type == ELF::STT_TLS || Type == ELF::STT_GNU_IFUNC); uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift); SD.setFlags(OtherFlags | (Type << ELF_STT_Shift)); @@ -48,7 +48,7 @@ assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT || Type == ELF::STT_FUNC || Type == ELF::STT_SECTION || Type == ELF::STT_FILE || Type == ELF::STT_COMMON || - Type == ELF::STT_TLS); + Type == ELF::STT_TLS || Type == ELF::STT_GNU_IFUNC); return Type; } Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=146377&r1=146376&r2=146377&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCELFStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCELFStreamer.cpp Mon Dec 12 11:34:04 2011 @@ -130,7 +130,6 @@ case MCSA_WeakDefinition: case MCSA_WeakDefAutoPrivate: case MCSA_Invalid: - case MCSA_ELF_TypeIndFunction: case MCSA_IndirectSymbol: assert(0 && "Invalid symbol attribute for ELF!"); break; @@ -162,6 +161,10 @@ MCELF::SetType(SD, ELF::STT_FUNC); break; + case MCSA_ELF_TypeIndFunction: + MCELF::SetType(SD, ELF::STT_GNU_IFUNC); + break; + case MCSA_ELF_TypeObject: MCELF::SetType(SD, ELF::STT_OBJECT); break; Modified: llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp?rev=146377&r1=146376&r2=146377&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp Mon Dec 12 11:34:04 2011 @@ -476,6 +476,7 @@ .Case("common", MCSA_ELF_TypeCommon) .Case("notype", MCSA_ELF_TypeNoType) .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) + .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction) .Default(MCSA_Invalid); if (Attr == MCSA_Invalid) Modified: llvm/trunk/test/MC/ELF/type.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/type.s?rev=146377&r1=146376&r2=146377&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/type.s (original) +++ llvm/trunk/test/MC/ELF/type.s Mon Dec 12 11:34:04 2011 @@ -12,6 +12,10 @@ // Test that gnu_unique_object is accepted. .type zed, at gnu_unique_object +ifunc: + .global ifunc + .type ifunc, at gnu_indirect_function + // CHECK: # Symbol 4 // CHECK-NEXT: (('st_name', 0x00000005) # 'bar' // CHECK-NEXT: ('st_bind', 0x1) @@ -30,3 +34,13 @@ // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), +// CHECK-NEXT: # Symbol 6 +// CHECK-NEXT: (('st_name', 0x00000009) # 'ifunc' +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0xa) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) +// CHECK-NEXT: ), + From jan_sjodin at yahoo.com Mon Dec 12 11:47:17 2011 From: jan_sjodin at yahoo.com (Jan Sjodin) Date: Mon, 12 Dec 2011 09:47:17 -0800 (PST) Subject: [llvm-commits] XOP encoding patch References: <1323377350.13027.YahooMailNeo@web161504.mail.bf1.yahoo.com> <1323444076.34577.YahooMailNeo@web161505.mail.bf1.yahoo.com> Message-ID: <1323712037.54818.YahooMailNeo@web161501.mail.bf1.yahoo.com> I create a new patch which has all the XOP instructions. - Jan ----- Original Message ----- > From: Jan Sjodin > To: Bruno Cardoso Lopes ; Eli Friedman > Cc: "llvm-commits at cs.uiuc.edu" > Sent: Friday, December 9, 2011 10:21 AM > Subject: Re: [llvm-commits] XOP encoding patch > > Here is an updated patch with XOP8 and XOP9. It looks cleaner. Let me know what > you think. > > - Jan > > > > ----- Original Message ----- >>? From: Bruno Cardoso Lopes >>? To: Eli Friedman >>? Cc: Jan Sjodin ; > "llvm-commits at cs.uiuc.edu" >>? Sent: Thursday, December 8, 2011 8:50 PM >>? Subject: Re: [llvm-commits] XOP encoding patch >> >>? Hi, >> >>? On Thu, Dec 8, 2011 at 7:06 PM, Eli Friedman > >>? wrote: >>> ? On Thu, Dec 8, 2011 at 12:49 PM, Jan Sjodin > >>? wrote: >>>> ? This patch handles the encoding of XOP instructions. I included > one >>>> ? instruction for each kind including a test. >>> >>> ? +multiclass xop4opimm opc, string OpcodeStr> { >>> ? + ?def ri : IXOPi8>> ? + ? ? ? ? ? (ins VR128:$src1, VR128:$src2, i32i8imm:$src3), >>> >>> ? As discussed on IRC, you want i8imm here, not i32i8imm. >>> >>> ? + ? ? ?// If there is an additional 5th operand it must be an > immediate, >>? which >>> ? + ? ? ?// is encoded in bits[3:0] >>> ? + ? ? ?if(CurOp != NumOps) { >>> ? + ? ? ? const MCOperand &MIMM = MI.getOperand(CurOp++); >>> ? + ? ? ? if(MIMM.isImm()) { >>> ? + ? ? ? ? unsigned Val = MIMM.getImm(); >>> ? + ? ? ? ? assert(Val < 16 && "Immediate operand value > out >>? of range"); >>> ? + ? ? ? ? RegNum |= Val; >>> ? + ? ? ? } >>> ? + ? ? ?} >>> >>> ? No tabs, please. >>> >>> ? This patch doesn't include disassembler support; are you planning > to >>? add that? >>> >>> ? Someone more familiar with the x86 instruction patterns should >>> ? probably review this in addition. >> >>? Regarding the MC code emitter, my suggestion here is to factor out >>? common code from EmitVEXOpcodePrefix, and have a new >>? EmitXOPOpcodePrefix method which reuses the common part. IMO adding >>? several tricky conditions to get around the differences between them >>? isn't the way to go (and compromisses the code readability). That >>? means whenever one of the VEX prefixes has a slightly different >>? meaning in XOP, there should be a new TSFlags for it. >> >>? -- >>? Bruno Cardoso Lopes >>? http://www.brunocardoso.cc >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: 0059_xop_encoding_complete.patch Type: application/octet-stream Size: 40407 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20111212/d4298ec2/attachment.obj From mcrosier at apple.com Mon Dec 12 11:58:31 2011 From: mcrosier at apple.com (Chad Rosier) Date: Mon, 12 Dec 2011 17:58:31 -0000 Subject: [llvm-commits] [llvm] r146378 - in /llvm/trunk: include/llvm/Support/FileSystem.h lib/Support/Unix/PathV2.inc lib/Support/Windows/PathV2.inc lib/Support/Windows/Windows.h unittests/Support/Path.cpp Message-ID: <20111212175831.9DDC31BE003@llvm.org> Author: mcrosier Date: Mon Dec 12 11:58:31 2011 New Revision: 146378 URL: http://llvm.org/viewvc/llvm-project?rev=146378&view=rev Log: Revert r146363 to allow buildbots to make forward progress. Original commit message: Support/FileSystem: Implement canonicalize. Modified: llvm/trunk/include/llvm/Support/FileSystem.h llvm/trunk/lib/Support/Unix/PathV2.inc llvm/trunk/lib/Support/Windows/PathV2.inc llvm/trunk/lib/Support/Windows/Windows.h llvm/trunk/unittests/Support/Path.cpp Modified: llvm/trunk/include/llvm/Support/FileSystem.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/FileSystem.h?rev=146378&r1=146377&r2=146378&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/FileSystem.h (original) +++ llvm/trunk/include/llvm/Support/FileSystem.h Mon Dec 12 11:58:31 2011 @@ -389,12 +389,8 @@ /// @brief Canonicalize path. /// -/// Sets result to the file system's idea of what path is. Path must be -/// absolute. The result has the same case as the file system. -/// -/// Example: Give a file system with "C:\a\b\c\file.txt". -/// -/// C:\A\b\C\fIlE.TxT => C:\a\b\c\file.txt +/// Sets result to the file system's idea of what path is. The result is always +/// absolute and has the same capitalization as the file system. /// /// @param path Input path. /// @param result Set to the canonicalized version of \a path. Modified: llvm/trunk/lib/Support/Unix/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/PathV2.inc?rev=146378&r1=146377&r2=146378&view=diff ============================================================================== --- llvm/trunk/lib/Support/Unix/PathV2.inc (original) +++ llvm/trunk/lib/Support/Unix/PathV2.inc Mon Dec 12 11:58:31 2011 @@ -431,13 +431,6 @@ return success; } -error_code canonicalize(const Twine &path, SmallVectorImpl &result) { - // Paths are already canonicalized on posix systems. - assert(path::is_absolute(path) && "path must be absolute!"); - path.toVector(result); - return success; -} - error_code detail::directory_iterator_construct(detail::DirIterState &it, StringRef path){ SmallString<128> path_null(path); Modified: llvm/trunk/lib/Support/Windows/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/PathV2.inc?rev=146378&r1=146377&r2=146378&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/PathV2.inc (original) +++ llvm/trunk/lib/Support/Windows/PathV2.inc Mon Dec 12 11:58:31 2011 @@ -614,44 +614,6 @@ return success; } -error_code canonicalize(const Twine &path, SmallVectorImpl &result) { - assert(path::is_absolute(path) && "path must be absolute!"); - SmallString<128> path_storage; - StringRef p = path.toStringRef(path_storage); - SmallVector path_utf16; - result.set_size(0); - - // Convert path to UTF-16. - if (error_code ec = UTF8ToUTF16(p, path_utf16)) - return ec; - - DWORD size = ::GetShortPathNameW(c_str(path_utf16), NULL, 0); - SmallVector short_path; - short_path.reserve(size + 1); - size = ::GetShortPathNameW( c_str(path_utf16) - , short_path.data() - , short_path.capacity()); - if (!size) - return windows_error(::GetLastError()); - - short_path.set_size(size); - - size = ::GetLongPathNameW(c_str(short_path), NULL, 0); - path_utf16.reserve(size + 1); - size = ::GetLongPathNameW( c_str(short_path) - , path_utf16.data() - , path_utf16.capacity()); - if (!size) - return windows_error(::GetLastError()); - - path_utf16.set_size(size); - - if (error_code ec = UTF16ToUTF8(path_utf16.data(), path_utf16.size(), result)) - return ec; - - return success; -} - error_code get_magic(const Twine &path, uint32_t len, SmallVectorImpl &result) { SmallString<128> path_storage; Modified: llvm/trunk/lib/Support/Windows/Windows.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Windows.h?rev=146378&r1=146377&r2=146378&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/Windows.h (original) +++ llvm/trunk/lib/Support/Windows/Windows.h Mon Dec 12 11:58:31 2011 @@ -128,24 +128,6 @@ } }; -struct FileMappingHandleTraits : CommonHandleTraits { - static handle_type GetInvalid() { - return 0; - } -}; - -struct MappedViewOfFileHandleTraits : CommonHandleTraits { - typedef LPVOID handle_type; - - static handle_type GetInvalid() { - return 0; - } - - static void Close(handle_type h) { - ::UnmapViewOfFile(h); - } -}; - struct FileHandleTraits : CommonHandleTraits {}; typedef ScopedHandle ScopedCommonHandle; @@ -153,8 +135,6 @@ typedef ScopedHandle ScopedCryptContext; typedef ScopedHandle ScopedFindHandle; typedef ScopedHandle ScopedJobHandle; -typedef ScopedHandle ScopedFileMappingHandle; -typedef ScopedHandle ScopedMappedViewOfFileHandle; namespace llvm { template Modified: llvm/trunk/unittests/Support/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Path.cpp?rev=146378&r1=146377&r2=146378&view=diff ============================================================================== --- llvm/trunk/unittests/Support/Path.cpp (original) +++ llvm/trunk/unittests/Support/Path.cpp Mon Dec 12 11:58:31 2011 @@ -312,32 +312,4 @@ } } -TEST_F(FileSystemTest, Canonicalize) { - SmallString<128> file_pathname(TestDirectory); - path::append(file_pathname, "canonicalize", "a0", "aa1"); - - bool existed; - ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) - + "/canonicalize/a0/aa1", existed)); - - { - path::append(file_pathname, "file.txt"); - std::string ErrMsg; - raw_fd_ostream file(file_pathname.c_str(), ErrMsg); - file << "hello\n"; - } - - SmallString<0> res; - ASSERT_NO_ERROR(fs::canonicalize(Twine(TestDirectory) - + "/cAnOnIcAlIzE/A0/aA1/fIlE.TxT", res)); - // Only check if we actually found the file. As we won't find it on case - // sensitive file systems. - if (fs::exists(res.str())) { - ASSERT_TRUE(res.str().find("canonicalize") != StringRef::npos); - ASSERT_TRUE(res.str().find("a0") != StringRef::npos); - ASSERT_TRUE(res.str().find("aa1") != StringRef::npos); - ASSERT_TRUE(res.str().find("file.txt") != StringRef::npos); - } -} - } // anonymous namespace From mcrosier at apple.com Mon Dec 12 12:03:12 2011 From: mcrosier at apple.com (Chad Rosier) Date: Mon, 12 Dec 2011 10:03:12 -0800 Subject: [llvm-commits] [llvm] r146363 - in /llvm/trunk: include/llvm/Support/FileSystem.h lib/Support/Unix/PathV2.inc lib/Support/Windows/PathV2.inc lib/Support/Windows/Windows.h unittests/Support/Path.cpp In-Reply-To: <330FD7CC-BCF7-4532-9262-AB3A355A4D19@2pi.dk> References: <20111212060402.62D332A6C12C@llvm.org> <330FD7CC-BCF7-4532-9262-AB3A355A4D19@2pi.dk> Message-ID: Hi Michael, I reverted this in r146378 to allow the buildbots to make forward progress. Please recommit once you've fixed this issue. Thanks, Chad On Dec 12, 2011, at 8:41 AM, Jakob Stoklund Olesen wrote: > > On Dec 11, 2011, at 10:04 PM, Michael J. Spencer wrote: > >> Author: mspencer >> Date: Mon Dec 12 00:04:01 2011 >> New Revision: 146363 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=146363&view=rev >> Log: >> Support/FileSystem: Implement canonicalize. >> >> Modified: >> llvm/trunk/include/llvm/Support/FileSystem.h >> llvm/trunk/lib/Support/Unix/PathV2.inc >> llvm/trunk/lib/Support/Windows/PathV2.inc >> llvm/trunk/lib/Support/Windows/Windows.h >> llvm/trunk/unittests/Support/Path.cpp > > This is failing on OS X Lion: > > ******************** TEST 'LLVM-Unit :: Support/Release+Asserts/SupportTests/FileSystemTest.Canonicalize' FAILED ******************** > Note: Google Test filter = FileSystemTest.Canonicalize > [==========] Running 1 test from 1 test case. > [----------] Global test environment set-up. > [----------] 1 test from FileSystemTest > [ RUN ] FileSystemTest.Canonicalize > /Volumes/Krask/g/llvm/unittests/Support/Path.cpp:336: Failure > Value of: res.str().find("canonicalize") != StringRef::npos > Actual: false > Expected: true > [ FAILED ] FileSystemTest.Canonicalize (5 ms) > [----------] 1 test from FileSystemTest (5 ms total) > > [----------] Global test environment tear-down > [==========] 1 test from 1 test case ran. (6 ms total) > [ PASSED ] 0 tests. > [ FAILED ] 1 test, listed below: > [ FAILED ] FileSystemTest.Canonicalize > > 1 FAILED TEST > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From kcc at google.com Mon Dec 12 12:01:47 2011 From: kcc at google.com (Kostya Serebryany) Date: Mon, 12 Dec 2011 18:01:47 -0000 Subject: [llvm-commits] [llvm] r146379 - /llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Message-ID: <20111212180147.32C831BE003@llvm.org> Author: kcc Date: Mon Dec 12 12:01:46 2011 New Revision: 146379 URL: http://llvm.org/viewvc/llvm-project?rev=146379&view=rev Log: [asan] use .preinit_array only on linux Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=146379&r1=146378&r2=146379&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original) +++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Mon Dec 12 12:01:46 2011 @@ -567,7 +567,6 @@ // .preinit_array is something that hapens before all other inits. // On systems where .preinit_array is honored, we will call __asan_init early. -// On other systems this will make no effect. void AddressSanitizer::appendToPreinitArray(Module &M, Function *F) { IRBuilder<> IRB(M.getContext()); GlobalVariable *Var = @@ -647,7 +646,9 @@ } appendToGlobalCtors(M, AsanCtorFunction, 1 /*high priority*/); - appendToPreinitArray(M, AsanInitFunction); + + if (M.getTargetTriple().find("linux") != std::string::npos) + appendToPreinitArray(M, AsanInitFunction); return Res; } From kcc at google.com Mon Dec 12 12:05:25 2011 From: kcc at google.com (Kostya Serebryany) Date: Mon, 12 Dec 2011 10:05:25 -0800 Subject: [llvm-commits] [llvm] r146284 - /llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp In-Reply-To: References: <20111209220933.4FEFC1BE003@llvm.org> Message-ID: On Mon, Dec 12, 2011 at 12:07 AM, Alexander Potapenko wrote: > > > > appendToGlobalCtors(M, AsanCtorFunction, 1 /*high priority*/); > > + appendToPreinitArray(M, AsanInitFunction); > > > > I see this function is called on Mac as well as on Linux. Have you fixed > this? > Just did, thanks. r146379. --kcc -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20111212/4111c8e7/attachment.html From gohman at apple.com Mon Dec 12 12:13:53 2011 From: gohman at apple.com (Dan Gohman) Date: Mon, 12 Dec 2011 18:13:53 -0000 Subject: [llvm-commits] [llvm] r146380 - /llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Message-ID: <20111212181353.A8FFA1BE003@llvm.org> Author: djg Date: Mon Dec 12 12:13:53 2011 New Revision: 146380 URL: http://llvm.org/viewvc/llvm-project?rev=146380&view=rev Log: Fix omitted break statements in a switch. Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp?rev=146380&r1=146379&r2=146380&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Mon Dec 12 12:13:53 2011 @@ -2255,6 +2255,7 @@ // guards against loops in the middle of a sequence. if (SomeSuccHasSame && !AllSuccsHaveSame) S.ClearSequenceProgress(); + break; } case S_CanRelease: { const Value *Arg = I->first; @@ -2289,6 +2290,7 @@ // guards against loops in the middle of a sequence. if (SomeSuccHasSame && !AllSuccsHaveSame) S.ClearSequenceProgress(); + break; } } } From stoklund at 2pi.dk Mon Dec 12 12:16:53 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 12 Dec 2011 18:16:53 -0000 Subject: [llvm-commits] [llvm] r146382 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Message-ID: <20111212181653.C6D7E1BE003@llvm.org> Author: stoklund Date: Mon Dec 12 12:16:53 2011 New Revision: 146382 URL: http://llvm.org/viewvc/llvm-project?rev=146382&view=rev Log: Make MF a class member instead of passing it around everywhere. Also add an MCP member pointing to the machine constant pool. No functional change intended. Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=146382&r1=146381&r2=146382&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Dec 12 12:16:53 2011 @@ -249,6 +249,8 @@ /// the branch fix up pass. bool HasFarJump; + MachineFunction *MF; + MachineConstantPool *MCP; const ARMInstrInfo *TII; const ARMSubtarget *STI; ARMFunctionInfo *AFI; @@ -266,12 +268,10 @@ } private: - void DoInitialPlacement(MachineFunction &MF, - std::vector &CPEMIs); + void DoInitialPlacement(std::vector &CPEMIs); CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI); - void JumpTableFunctionScan(MachineFunction &MF); - void InitialFunctionScan(MachineFunction &MF, - const std::vector &CPEMIs); + void JumpTableFunctionScan(); + void InitialFunctionScan(const std::vector &CPEMIs); MachineBasicBlock *SplitBlockBeforeInstr(MachineInstr *MI); void UpdateForInsertedWaterBlock(MachineBasicBlock *NewBB); void AdjustBBOffsetsAfter(MachineBasicBlock *BB); @@ -280,7 +280,7 @@ bool LookForWater(CPUser&U, unsigned UserOffset, water_iterator &WaterIter); void CreateNewWater(unsigned CPUserIndex, unsigned UserOffset, MachineBasicBlock *&NewMBB); - bool HandleConstantPoolUser(MachineFunction &MF, unsigned CPUserIndex); + bool HandleConstantPoolUser(unsigned CPUserIndex); void RemoveDeadCPEMI(MachineInstr *CPEMI); bool RemoveUnusedCPEntries(); bool CPEIsInRange(MachineInstr *MI, unsigned UserOffset, @@ -289,21 +289,21 @@ bool WaterIsInRange(unsigned UserOffset, MachineBasicBlock *Water, CPUser &U); bool BBIsInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp); - bool FixUpImmediateBr(MachineFunction &MF, ImmBranch &Br); - bool FixUpConditionalBr(MachineFunction &MF, ImmBranch &Br); - bool FixUpUnconditionalBr(MachineFunction &MF, ImmBranch &Br); + bool FixUpImmediateBr(ImmBranch &Br); + bool FixUpConditionalBr(ImmBranch &Br); + bool FixUpUnconditionalBr(ImmBranch &Br); bool UndoLRSpillRestore(); - bool OptimizeThumb2Instructions(MachineFunction &MF); - bool OptimizeThumb2Branches(MachineFunction &MF); - bool ReorderThumb2JumpTables(MachineFunction &MF); - bool OptimizeThumb2JumpTables(MachineFunction &MF); + bool OptimizeThumb2Instructions(); + bool OptimizeThumb2Branches(); + bool ReorderThumb2JumpTables(); + bool OptimizeThumb2JumpTables(); MachineBasicBlock *AdjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock *JTBB); void ComputeBlockSize(MachineBasicBlock *MBB); unsigned GetOffsetOf(MachineInstr *MI) const; void dumpBBs(); - void verify(MachineFunction &MF); + void verify(); bool OffsetIsInRange(unsigned UserOffset, unsigned TrialOffset, unsigned Disp, bool NegativeOK, bool IsSoImm = false); @@ -317,9 +317,9 @@ } /// verify - check BBOffsets, BBSizes, alignment of islands -void ARMConstantIslands::verify(MachineFunction &MF) { +void ARMConstantIslands::verify() { #ifndef NDEBUG - for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end(); + for (MachineFunction::iterator MBBI = MF->begin(), E = MF->end(); MBBI != E; ++MBBI) { MachineBasicBlock *MBB = MBBI; unsigned Align = MBB->getAlignment(); @@ -358,16 +358,17 @@ return new ARMConstantIslands(); } -bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) { - MachineConstantPool &MCP = *MF.getConstantPool(); +bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) { + MF = &mf; + MCP = mf.getConstantPool(); DEBUG(dbgs() << "***** ARMConstantIslands: " - << MCP.getConstants().size() << " CP entries, aligned to " - << MCP.getConstantPoolAlignment() << " bytes *****\n"); + << MCP->getConstants().size() << " CP entries, aligned to " + << MCP->getConstantPoolAlignment() << " bytes *****\n"); - TII = (const ARMInstrInfo*)MF.getTarget().getInstrInfo(); - AFI = MF.getInfo(); - STI = &MF.getTarget().getSubtarget(); + TII = (const ARMInstrInfo*)MF->getTarget().getInstrInfo(); + AFI = MF->getInfo(); + STI = &MF->getTarget().getSubtarget(); isThumb = AFI->isThumbFunction(); isThumb1 = AFI->isThumb1OnlyFunction(); @@ -377,18 +378,18 @@ // Renumber all of the machine basic blocks in the function, guaranteeing that // the numbers agree with the position of the block in the function. - MF.RenumberBlocks(); + MF->RenumberBlocks(); // Try to reorder and otherwise adjust the block layout to make good use // of the TB[BH] instructions. bool MadeChange = false; if (isThumb2 && AdjustJumpTableBlocks) { - JumpTableFunctionScan(MF); - MadeChange |= ReorderThumb2JumpTables(MF); + JumpTableFunctionScan(); + MadeChange |= ReorderThumb2JumpTables(); // Data is out of date, so clear it. It'll be re-computed later. T2JumpTables.clear(); // Blocks may have shifted around. Keep the numbering up to date. - MF.RenumberBlocks(); + MF->RenumberBlocks(); } // Thumb1 functions containing constant pools get 4-byte alignment. @@ -396,15 +397,15 @@ // ARM and Thumb2 functions need to be 4-byte aligned. if (!isThumb1) - MF.EnsureAlignment(2); // 2 = log2(4) + MF->EnsureAlignment(2); // 2 = log2(4) // Perform the initial placement of the constant pool entries. To start with, // we put them all at the end of the function. std::vector CPEMIs; - if (!MCP.isEmpty()) { - DoInitialPlacement(MF, CPEMIs); + if (!MCP->isEmpty()) { + DoInitialPlacement(CPEMIs); if (isThumb1) - MF.EnsureAlignment(2); // 2 = log2(4) + MF->EnsureAlignment(2); // 2 = log2(4) } /// The next UID to take is the first unused one. @@ -413,7 +414,7 @@ // Do the initial scan of the function, building up information about the // sizes of each block, the location of all the water, and finding all of the // constant pool users. - InitialFunctionScan(MF, CPEMIs); + InitialFunctionScan(CPEMIs); CPEMIs.clear(); DEBUG(dumpBBs()); @@ -428,7 +429,7 @@ DEBUG(dbgs() << "Beginning CP iteration #" << NoCPIters << '\n'); bool CPChange = false; for (unsigned i = 0, e = CPUsers.size(); i != e; ++i) - CPChange |= HandleConstantPoolUser(MF, i); + CPChange |= HandleConstantPoolUser(i); if (CPChange && ++NoCPIters > 30) llvm_unreachable("Constant Island pass failed to converge!"); DEBUG(dumpBBs()); @@ -440,7 +441,7 @@ DEBUG(dbgs() << "Beginning BR iteration #" << NoBRIters << '\n'); bool BRChange = false; for (unsigned i = 0, e = ImmBranches.size(); i != e; ++i) - BRChange |= FixUpImmediateBr(MF, ImmBranches[i]); + BRChange |= FixUpImmediateBr(ImmBranches[i]); if (BRChange && ++NoBRIters > 30) llvm_unreachable("Branch Fix Up pass failed to converge!"); DEBUG(dumpBBs()); @@ -452,10 +453,10 @@ // Shrink 32-bit Thumb2 branch, load, and store instructions. if (isThumb2 && !STI->prefers32BitThumb()) - MadeChange |= OptimizeThumb2Instructions(MF); + MadeChange |= OptimizeThumb2Instructions(); // After a while, this might be made debug-only, but it is not expensive. - verify(MF); + verify(); // If LR has been forced spilled and no far jump (i.e. BL) has been issued, // undo the spill / restore of LR if possible. @@ -485,14 +486,14 @@ /// DoInitialPlacement - Perform the initial placement of the constant pool /// entries. To start with, we put them all at the end of the function. -void ARMConstantIslands::DoInitialPlacement(MachineFunction &MF, - std::vector &CPEMIs) { +void +ARMConstantIslands::DoInitialPlacement(std::vector &CPEMIs) { // Create the basic block to hold the CPE's. - MachineBasicBlock *BB = MF.CreateMachineBasicBlock(); - MF.push_back(BB); + MachineBasicBlock *BB = MF->CreateMachineBasicBlock(); + MF->push_back(BB); // MachineConstantPool measures alignment in bytes. We measure in log2(bytes). - unsigned MaxAlign = Log2_32(MF.getConstantPool()->getConstantPoolAlignment()); + unsigned MaxAlign = Log2_32(MF->getConstantPool()->getConstantPoolAlignment()); // Mark the basic block as required by the const-pool. // If AlignConstantIslands isn't set, use 4-byte alignment for everything. @@ -507,9 +508,9 @@ // Add all of the constants from the constant pool to the end block, use an // identity mapping of CPI's to CPE's. const std::vector &CPs = - MF.getConstantPool()->getConstants(); + MF->getConstantPool()->getConstants(); - const TargetData &TD = *MF.getTarget().getTargetData(); + const TargetData &TD = *MF->getTarget().getTargetData(); for (unsigned i = 0, e = CPs.size(); i != e; ++i) { unsigned Size = TD.getTypeAllocSize(CPs[i].getType()); assert(Size >= 4 && "Too small constant pool entry"); @@ -579,8 +580,8 @@ /// JumpTableFunctionScan - Do a scan of the function, building up /// information about the sizes of each block and the locations of all /// the jump tables. -void ARMConstantIslands::JumpTableFunctionScan(MachineFunction &MF) { - for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end(); +void ARMConstantIslands::JumpTableFunctionScan() { + for (MachineFunction::iterator MBBI = MF->begin(), E = MF->end(); MBBI != E; ++MBBI) { MachineBasicBlock &MBB = *MBBI; @@ -594,27 +595,27 @@ /// InitialFunctionScan - Do the initial scan of the function, building up /// information about the sizes of each block, the location of all the water, /// and finding all of the constant pool users. -void ARMConstantIslands::InitialFunctionScan(MachineFunction &MF, - const std::vector &CPEMIs) { +void ARMConstantIslands:: +InitialFunctionScan(const std::vector &CPEMIs) { BBInfo.clear(); - BBInfo.resize(MF.getNumBlockIDs()); + BBInfo.resize(MF->getNumBlockIDs()); // First thing, compute the size of all basic blocks, and see if the function // has any inline assembly in it. If so, we have to be conservative about // alignment assumptions, as we don't know for sure the size of any // instructions in the inline assembly. - for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) + for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) ComputeBlockSize(I); // The known bits of the entry block offset are determined by the function // alignment. - BBInfo.front().KnownBits = MF.getAlignment(); + BBInfo.front().KnownBits = MF->getAlignment(); // Compute block offsets and known bits. - AdjustBBOffsetsAfter(MF.begin()); + AdjustBBOffsetsAfter(MF->begin()); // Now go back through the instructions and build up our data structures. - for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end(); + for (MachineFunction::iterator MBBI = MF->begin(), E = MF->end(); MBBI != E; ++MBBI) { MachineBasicBlock &MBB = *MBBI; @@ -832,13 +833,12 @@ /// account for this change and returns the newly created block. MachineBasicBlock *ARMConstantIslands::SplitBlockBeforeInstr(MachineInstr *MI) { MachineBasicBlock *OrigBB = MI->getParent(); - MachineFunction &MF = *OrigBB->getParent(); // Create a new MBB for the code after the OrigBB. MachineBasicBlock *NewBB = - MF.CreateMachineBasicBlock(OrigBB->getBasicBlock()); + MF->CreateMachineBasicBlock(OrigBB->getBasicBlock()); MachineFunction::iterator MBBI = OrigBB; ++MBBI; - MF.insert(MBBI, NewBB); + MF->insert(MBBI, NewBB); // Splice the instructions starting with MI over to NewBB. NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end()); @@ -864,7 +864,7 @@ // Update internal data structures to account for the newly inserted MBB. // This is almost the same as UpdateForInsertedWaterBlock, except that // the Water goes after OrigBB, not NewBB. - MF.RenumberBlocks(NewBB); + MF->RenumberBlocks(NewBB); // Insert an entry into BBInfo to align it properly with the (newly // renumbered) block numbers. @@ -1000,7 +1000,6 @@ #endif // NDEBUG void ARMConstantIslands::AdjustBBOffsetsAfter(MachineBasicBlock *BB) { - MachineFunction *MF = BB->getParent(); for(unsigned i = BB->getNumber() + 1, e = MF->getNumBlockIDs(); i < e; ++i) { // Get the offset and known bits at the end of the layout predecessor. unsigned Offset = BBInfo[i - 1].postOffset(); @@ -1287,8 +1286,7 @@ /// is out-of-range. If so, pick up the constant pool value and move it some /// place in-range. Return true if we changed any addresses (thus must run /// another pass of branch lengthening), false otherwise. -bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &MF, - unsigned CPUserIndex) { +bool ARMConstantIslands::HandleConstantPoolUser(unsigned CPUserIndex) { CPUser &U = CPUsers[CPUserIndex]; MachineInstr *UserMI = U.MI; MachineInstr *CPEMI = U.CPEMI; @@ -1309,7 +1307,7 @@ unsigned ID = AFI->createPICLabelUId(); // Look for water where we can place this CPE. - MachineBasicBlock *NewIsland = MF.CreateMachineBasicBlock(); + MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock(); MachineBasicBlock *NewMBB; water_iterator IP; if (LookForWater(U, UserOffset, IP)) { @@ -1353,7 +1351,7 @@ WaterList.erase(IP); // Okay, we know we can put an island before NewMBB now, do it! - MF.insert(NewMBB, NewIsland); + MF->insert(NewMBB, NewIsland); // Update internal data structures to account for the newly inserted MBB. UpdateForInsertedWaterBlock(NewIsland); @@ -1462,7 +1460,7 @@ /// FixUpImmediateBr - Fix up an immediate branch whose destination is too far /// away to fit in its displacement field. -bool ARMConstantIslands::FixUpImmediateBr(MachineFunction &MF, ImmBranch &Br) { +bool ARMConstantIslands::FixUpImmediateBr(ImmBranch &Br) { MachineInstr *MI = Br.MI; MachineBasicBlock *DestBB = MI->getOperand(0).getMBB(); @@ -1471,8 +1469,8 @@ return false; if (!Br.isCond) - return FixUpUnconditionalBr(MF, Br); - return FixUpConditionalBr(MF, Br); + return FixUpUnconditionalBr(Br); + return FixUpConditionalBr(Br); } /// FixUpUnconditionalBr - Fix up an unconditional branch whose destination is @@ -1480,7 +1478,7 @@ /// spilled in the epilogue, then we can use BL to implement a far jump. /// Otherwise, add an intermediate branch instruction to a branch. bool -ARMConstantIslands::FixUpUnconditionalBr(MachineFunction &MF, ImmBranch &Br) { +ARMConstantIslands::FixUpUnconditionalBr(ImmBranch &Br) { MachineInstr *MI = Br.MI; MachineBasicBlock *MBB = MI->getParent(); if (!isThumb1) @@ -1503,7 +1501,7 @@ /// far away to fit in its displacement field. It is converted to an inverse /// conditional branch + an unconditional branch to the destination. bool -ARMConstantIslands::FixUpConditionalBr(MachineFunction &MF, ImmBranch &Br) { +ARMConstantIslands::FixUpConditionalBr(ImmBranch &Br) { MachineInstr *MI = Br.MI; MachineBasicBlock *DestBB = MI->getOperand(0).getMBB(); @@ -1607,7 +1605,7 @@ return MadeChange; } -bool ARMConstantIslands::OptimizeThumb2Instructions(MachineFunction &MF) { +bool ARMConstantIslands::OptimizeThumb2Instructions() { bool MadeChange = false; // Shrink ADR and LDR from constantpool. @@ -1651,12 +1649,12 @@ } } - MadeChange |= OptimizeThumb2Branches(MF); - MadeChange |= OptimizeThumb2JumpTables(MF); + MadeChange |= OptimizeThumb2Branches(); + MadeChange |= OptimizeThumb2JumpTables(); return MadeChange; } -bool ARMConstantIslands::OptimizeThumb2Branches(MachineFunction &MF) { +bool ARMConstantIslands::OptimizeThumb2Branches() { bool MadeChange = false; for (unsigned i = 0, e = ImmBranches.size(); i != e; ++i) { @@ -1742,12 +1740,12 @@ /// OptimizeThumb2JumpTables - Use tbb / tbh instructions to generate smaller /// jumptables when it's possible. -bool ARMConstantIslands::OptimizeThumb2JumpTables(MachineFunction &MF) { +bool ARMConstantIslands::OptimizeThumb2JumpTables() { bool MadeChange = false; // FIXME: After the tables are shrunk, can we get rid some of the // constantpool tables? - MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); + MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); if (MJTI == 0) return false; const std::vector &JT = MJTI->getJumpTables(); @@ -1867,10 +1865,10 @@ /// ReorderThumb2JumpTables - Adjust the function's block layout to ensure that /// jump tables always branch forwards, since that's what tbb and tbh need. -bool ARMConstantIslands::ReorderThumb2JumpTables(MachineFunction &MF) { +bool ARMConstantIslands::ReorderThumb2JumpTables() { bool MadeChange = false; - MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); + MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); if (MJTI == 0) return false; const std::vector &JT = MJTI->getJumpTables(); @@ -1910,8 +1908,6 @@ MachineBasicBlock *ARMConstantIslands:: AdjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock *JTBB) { - MachineFunction &MF = *BB->getParent(); - // If the destination block is terminated by an unconditional branch, // try to move it; otherwise, create a new block following the jump // table that branches back to the actual target. This is a very simple @@ -1928,22 +1924,22 @@ // If the block ends in an unconditional branch, move it. The prior block // has to have an analyzable terminator for us to move this one. Be paranoid // and make sure we're not trying to move the entry block of the function. - if (!B && Cond.empty() && BB != MF.begin() && + if (!B && Cond.empty() && BB != MF->begin() && !TII->AnalyzeBranch(*OldPrior, TBB, FBB, CondPrior)) { BB->moveAfter(JTBB); OldPrior->updateTerminator(); BB->updateTerminator(); // Update numbering to account for the block being moved. - MF.RenumberBlocks(); + MF->RenumberBlocks(); ++NumJTMoved; return NULL; } // Create a new MBB for the code after the jump BB. MachineBasicBlock *NewBB = - MF.CreateMachineBasicBlock(JTBB->getBasicBlock()); + MF->CreateMachineBasicBlock(JTBB->getBasicBlock()); MachineFunction::iterator MBBI = JTBB; ++MBBI; - MF.insert(MBBI, NewBB); + MF->insert(MBBI, NewBB); // Add an unconditional branch from NewBB to BB. // There doesn't seem to be meaningful DebugInfo available; this doesn't @@ -1953,7 +1949,7 @@ .addImm(ARMCC::AL).addReg(0); // Update internal data structures to account for the newly inserted MBB. - MF.RenumberBlocks(NewBB); + MF->RenumberBlocks(NewBB); // Update the CFG. NewBB->addSuccessor(BB); From gohman at apple.com Mon Dec 12 12:16:56 2011 From: gohman at apple.com (Dan Gohman) Date: Mon, 12 Dec 2011 18:16:56 -0000 Subject: [llvm-commits] [llvm] r146383 - /llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Message-ID: <20111212181656.5FCB41BE003@llvm.org> Author: djg Date: Mon Dec 12 12:16:56 2011 New Revision: 146383 URL: http://llvm.org/viewvc/llvm-project?rev=146383&view=rev Log: Inline SetSeqToRelease into its only caller, since it's more clear that way. Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp?rev=146383&r1=146382&r2=146383&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Mon Dec 12 12:16:56 2011 @@ -1251,16 +1251,6 @@ Seq = NewSeq; } - void SetSeqToRelease(MDNode *M) { - if (Seq == S_None || Seq == S_Use) { - Seq = M ? S_MovableRelease : S_Release; - RRI.ReleaseMetadata = M; - } else if (Seq != S_MovableRelease || RRI.ReleaseMetadata != M) { - Seq = S_Release; - RRI.ReleaseMetadata = 0; - } - } - Sequence GetSeq() const { return Seq; } @@ -2352,8 +2342,11 @@ if (S.GetSeq() == S_Release || S.GetSeq() == S_MovableRelease) NestingDetected = true; - S.SetSeqToRelease(Inst->getMetadata(ImpreciseReleaseMDKind)); S.RRI.clear(); + + MDNode *ReleaseMetadata = Inst->getMetadata(ImpreciseReleaseMDKind); + S.SetSeq(ReleaseMetadata ? S_MovableRelease : S_Release); + S.RRI.ReleaseMetadata = ReleaseMetadata; S.RRI.KnownSafe = S.IsKnownNested() || S.IsKnownIncremented(); S.RRI.IsTailCallRelease = cast(Inst)->isTailCall(); S.RRI.Calls.insert(Inst); From gohman at apple.com Mon Dec 12 12:19:12 2011 From: gohman at apple.com (Dan Gohman) Date: Mon, 12 Dec 2011 18:19:12 -0000 Subject: [llvm-commits] [llvm] r146384 - /llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Message-ID: <20111212181913.0738E1BE003@llvm.org> Author: djg Date: Mon Dec 12 12:19:12 2011 New Revision: 146384 URL: http://llvm.org/viewvc/llvm-project?rev=146384&view=rev Log: Use getArgOperand instead of getOperand on a call. Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp?rev=146384&r1=146383&r2=146384&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Mon Dec 12 12:19:12 2011 @@ -3134,7 +3134,7 @@ UE = Alloca->use_end(); UI != UE; ) { CallInst *UserInst = cast(*UI++); if (!UserInst->use_empty()) - UserInst->replaceAllUsesWith(UserInst->getOperand(1)); + UserInst->replaceAllUsesWith(UserInst->getArgOperand(0)); UserInst->eraseFromParent(); } Alloca->eraseFromParent(); From gohman at apple.com Mon Dec 12 12:20:00 2011 From: gohman at apple.com (Dan Gohman) Date: Mon, 12 Dec 2011 18:20:00 -0000 Subject: [llvm-commits] [llvm] r146385 - /llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Message-ID: <20111212182000.431961BE003@llvm.org> Author: djg Date: Mon Dec 12 12:20:00 2011 New Revision: 146385 URL: http://llvm.org/viewvc/llvm-project?rev=146385&view=rev Log: Fix a copy+pasto in a comment. Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp?rev=146385&r1=146384&r2=146385&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Mon Dec 12 12:20:00 2011 @@ -1478,7 +1478,7 @@ /// metadata. unsigned ImpreciseReleaseMDKind; - /// CopyOnEscape - The Metadata Kind for clang.arc.copy_on_escape + /// CopyOnEscapeMDKind - The Metadata Kind for clang.arc.copy_on_escape /// metadata. unsigned CopyOnEscapeMDKind; From daniel at zuster.org Mon Dec 12 12:22:04 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 12 Dec 2011 18:22:04 -0000 Subject: [llvm-commits] [llvm] r146388 - /llvm/trunk/tools/llvm-config/llvm-config.cpp Message-ID: <20111212182204.7AE0D1BE003@llvm.org> Author: ddunbar Date: Mon Dec 12 12:22:04 2011 New Revision: 146388 URL: http://llvm.org/viewvc/llvm-project?rev=146388&view=rev Log: llvm-config: Default to "all" if no components are specified. - Fixes PR11530. Modified: llvm/trunk/tools/llvm-config/llvm-config.cpp Modified: llvm/trunk/tools/llvm-config/llvm-config.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-config/llvm-config.cpp?rev=146388&r1=146387&r2=146388&view=diff ============================================================================== --- llvm/trunk/tools/llvm-config/llvm-config.cpp (original) +++ llvm/trunk/tools/llvm-config/llvm-config.cpp Mon Dec 12 12:22:04 2011 @@ -300,6 +300,10 @@ usage(); if (PrintLibs || PrintLibNames || PrintLibFiles) { + // If no components were specified, default to "all". + if (Components.empty()) + Components.push_back("all"); + // Construct the list of all the required libraries. std::vector RequiredLibs; ComputeLibsForComponents(Components, RequiredLibs); From bruno.cardoso at gmail.com Mon Dec 12 12:28:53 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Mon, 12 Dec 2011 16:28:53 -0200 Subject: [llvm-commits] XOP encoding patch In-Reply-To: <1323712037.54818.YahooMailNeo@web161501.mail.bf1.yahoo.com> References: <1323377350.13027.YahooMailNeo@web161504.mail.bf1.yahoo.com> <1323444076.34577.YahooMailNeo@web161505.mail.bf1.yahoo.com> <1323712037.54818.YahooMailNeo@web161501.mail.bf1.yahoo.com> Message-ID: Hi, On Mon, Dec 12, 2011 at 3:47 PM, Jan Sjodin wrote: > I create a new patch which has all the XOP instructions. Ok, the XOP8, XOP9 seems fair enough for now. Like Eli said, your patch again use tabs: + // If there is an additional 5th operand it must be an immediate, which + // is encoded in bits[3:0] + if(CurOp != NumOps) { + const MCOperand &MIMM = MI.getOperand(CurOp++); + if(MIMM.isImm()) { + unsigned Val = MIMM.getImm(); + assert(Val < 16 && "Immediate operand value out of range"); + RegNum |= Val; + } + } Also, you're using 4 spaces instead of 2 in only a few places: +let isAsmParserOnly = 1 in { + defm VPROTW : xop3opimm<0xC1, "vprotw">; + defm VPROTQ : xop3opimm<0xC3, "vprotq">; + defm VPROTD : xop3opimm<0xC2, "vprotd">; + defm VPROTB : xop3opimm<0xC0, "vprotb">; +} Fix this and the others and commit. One last thing: commit the encoding bits and the encoder logic in a different commit from the instructions, to make it easy to track the encoding changes in the future if someone needs to search for it. -- Bruno Cardoso Lopes http://www.brunocardoso.cc From gohman at apple.com Mon Dec 12 12:30:26 2011 From: gohman at apple.com (Dan Gohman) Date: Mon, 12 Dec 2011 18:30:26 -0000 Subject: [llvm-commits] [llvm] r146389 - /llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Message-ID: <20111212183026.8FC181BE003@llvm.org> Author: djg Date: Mon Dec 12 12:30:26 2011 New Revision: 146389 URL: http://llvm.org/viewvc/llvm-project?rev=146389&view=rev Log: Add a TODO comment. Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp?rev=146389&r1=146388&r2=146389&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Mon Dec 12 12:30:26 2011 @@ -1165,6 +1165,7 @@ /// Partial - True of we've seen an opportunity for partial RR elimination, /// such as pushing calls into a CFG triangle or into one side of a /// CFG diamond. + /// TODO: Consider moving this to PtrState. bool Partial; /// ReleaseMetadata - If the Calls are objc_release calls and they all have From jan_sjodin at yahoo.com Mon Dec 12 12:41:21 2011 From: jan_sjodin at yahoo.com (Jan Sjodin) Date: Mon, 12 Dec 2011 10:41:21 -0800 (PST) Subject: [llvm-commits] XOP encoding patch In-Reply-To: References: <1323377350.13027.YahooMailNeo@web161504.mail.bf1.yahoo.com> <1323444076.34577.YahooMailNeo@web161505.mail.bf1.yahoo.com> <1323712037.54818.YahooMailNeo@web161501.mail.bf1.yahoo.com> Message-ID: <1323715281.52606.YahooMailNeo@web161505.mail.bf1.yahoo.com> > > Ok, the XOP8, XOP9 seems fair enough for now. > Like Eli said, your patch again use tabs: Thought I had told emacs not to do that anymore. Will fix! > +? ? ? // If there is an additional 5th operand it must be an immediate, which > +? ? ? // is encoded in bits[3:0] > +? ? ? if(CurOp != NumOps) { > +? ? ? ? const MCOperand &MIMM = MI.getOperand(CurOp++); > +? ? ? ? if(MIMM.isImm()) { > +? ? ? ? ? unsigned Val = MIMM.getImm(); > +??? ? assert(Val < 16 && "Immediate operand value out of > range"); > +??? ? RegNum |= Val; > +??? } > +? ? ? } > Also, you're using 4 spaces instead of 2 in only a few places: Ok will fix. > +let isAsmParserOnly = 1 in { > +? ? defm VPROTW : xop3opimm<0xC1, "vprotw">; > +? ? defm VPROTQ : xop3opimm<0xC3, "vprotq">; > +? ? defm VPROTD : xop3opimm<0xC2, "vprotd">; > +? ? defm VPROTB : xop3opimm<0xC0, "vprotb">; > +} > > Fix this and the others and commit. > > One last thing: commit the encoding bits and the encoder logic in a > different commit from the instructions, to make it easy to track the > encoding changes in the future if someone needs to search for it. > Okay, I will split into two commits. > -- > Bruno Cardoso Lopes > http://www.brunocardoso.cc > Thanks! - Jan From stoklund at 2pi.dk Mon Dec 12 12:45:45 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 12 Dec 2011 18:45:45 -0000 Subject: [llvm-commits] [llvm] r146391 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Message-ID: <20111212184545.A5C191BE003@llvm.org> Author: stoklund Date: Mon Dec 12 12:45:45 2011 New Revision: 146391 URL: http://llvm.org/viewvc/llvm-project?rev=146391&view=rev Log: Also set the proper alignment on inner islands and the function itself. Downgrade the alignment of the initial constant island when constant pool entries are moved elsewhere. This is all gated by -arm-align-constant-islands. Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=146391&r1=146390&r2=146391&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Dec 12 12:45:45 2011 @@ -270,6 +270,7 @@ private: void DoInitialPlacement(std::vector &CPEMIs); CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI); + unsigned getCPELogAlign(const MachineInstr *CPEMI); void JumpTableFunctionScan(); void InitialFunctionScan(const std::vector &CPEMIs); MachineBasicBlock *SplitBlockBeforeInstr(MachineInstr *MI); @@ -402,11 +403,8 @@ // Perform the initial placement of the constant pool entries. To start with, // we put them all at the end of the function. std::vector CPEMIs; - if (!MCP->isEmpty()) { + if (!MCP->isEmpty()) DoInitialPlacement(CPEMIs); - if (isThumb1) - MF->EnsureAlignment(2); // 2 = log2(4) - } /// The next UID to take is the first unused one. AFI->initPICLabelUId(CPEMIs.size()); @@ -499,6 +497,10 @@ // If AlignConstantIslands isn't set, use 4-byte alignment for everything. BB->setAlignment(AlignConstantIslands ? MaxAlign : 2); + // The function needs to be as aligned as the basic blocks. The linker may + // move functions around based on their alignment. + MF->EnsureAlignment(BB->getAlignment()); + // Order the entries in BB by descending alignment. That ensures correct // alignment of all entries as long as BB is sufficiently aligned. Keep // track of the insertion point for each alignment. We are going to bucket @@ -577,6 +579,22 @@ return NULL; } +/// getCPELogAlign - Returns the required alignment of the constant pool entry +/// represented by CPEMI. ALignment is measured in log2(bytes) units. +unsigned ARMConstantIslands::getCPELogAlign(const MachineInstr *CPEMI) { + assert(CPEMI && CPEMI->getOpcode() == ARM::CONSTPOOL_ENTRY); + + // Everything is 4-byte aligned unless AlignConstantIslands is set. + if (!AlignConstantIslands) + return 2; + + unsigned CPI = CPEMI->getOperand(1).getIndex(); + assert(CPI < MCP->getConstants().size() && "Invalid constant pool index."); + unsigned Align = MCP->getConstants()[CPI].getAlignment(); + assert(isPowerOf2_32(Align) && "Invalid CPE alignment"); + return Log2_32(Align); +} + /// JumpTableFunctionScan - Do a scan of the function, building up /// information about the sizes of each block and the locations of all /// the jump tables. @@ -1367,8 +1385,8 @@ CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1)); ++NumCPEs; - // Mark the basic block as 4-byte aligned as required by the const-pool entry. - NewIsland->setAlignment(2); + // Mark the basic block as aligned as required by the const-pool entry. + NewIsland->setAlignment(getCPELogAlign(U.CPEMI)); // Increase the size of the island block to account for the new entry. BBInfo[NewIsland->getNumber()].Size += Size; @@ -1396,18 +1414,14 @@ BBInfo[CPEBB->getNumber()].Size -= Size; // All succeeding offsets have the current size value added in, fix this. if (CPEBB->empty()) { - // In thumb1 mode, the size of island may be padded by two to compensate for - // the alignment requirement. Then it will now be 2 when the block is - // empty, so fix this. - // All succeeding offsets have the current size value added in, fix this. - if (BBInfo[CPEBB->getNumber()].Size != 0) { - Size += BBInfo[CPEBB->getNumber()].Size; - BBInfo[CPEBB->getNumber()].Size = 0; - } + BBInfo[CPEBB->getNumber()].Size = 0; // This block no longer needs to be aligned. . CPEBB->setAlignment(0); - } + } else + // Entries are sorted by descending alignment, so realign from the front. + CPEBB->setAlignment(getCPELogAlign(CPEBB->begin())); + AdjustBBOffsetsAfter(CPEBB); // An island has only one predecessor BB and one successor BB. Check if // this BB's predecessor jumps directly to this BB's successor. This From bob.wilson at apple.com Mon Dec 12 13:23:29 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 12 Dec 2011 19:23:29 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r146399 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <20111212192330.0B4B91BE003@llvm.org> Author: bwilson Date: Mon Dec 12 13:23:29 2011 New Revision: 146399 URL: http://llvm.org/viewvc/llvm-project?rev=146399&view=rev Log: Fix up llvm-gcc to work with the ctlz and cttz changes in llvm svn r146357. I know llvm-gcc is dead but my llvm-gcc nightly testers keep finding real problems that are not exposed by clang (for whatever reason), so I'm motivated to make easy fixes like this to keep it working. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=146399&r1=146398&r2=146399&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Dec 12 13:23:29 2011 @@ -5510,7 +5510,9 @@ case BUILT_IN_CLZL: case BUILT_IN_CLZLL: { Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); - EmitBuiltinUnaryOp(Amt, Result, Intrinsic::ctlz); + Function *F = + Intrinsic::getDeclaration(TheModule, Intrinsic::ctlz, Amt->getType()); + Result = Builder.CreateCall2(F, Amt, Builder.getTrue()); Type *DestTy = ConvertType(TREE_TYPE(exp)); Result = Builder.CreateIntCast(Result, DestTy, !TYPE_UNSIGNED(TREE_TYPE(exp)), @@ -5521,7 +5523,9 @@ case BUILT_IN_CTZL: case BUILT_IN_CTZLL: { Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); - EmitBuiltinUnaryOp(Amt, Result, Intrinsic::cttz); + Function *F = + Intrinsic::getDeclaration(TheModule, Intrinsic::cttz, Amt->getType()); + Result = Builder.CreateCall2(F, Amt, Builder.getTrue()); Type *DestTy = ConvertType(TREE_TYPE(exp)); Result = Builder.CreateIntCast(Result, DestTy, !TYPE_UNSIGNED(TREE_TYPE(exp)), @@ -5645,7 +5649,9 @@ // The argument and return type of cttz should match the argument type of // the ffs, but should ignore the return type of ffs. Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); - EmitBuiltinUnaryOp(Amt, Result, Intrinsic::cttz); + Function *F = + Intrinsic::getDeclaration(TheModule, Intrinsic::cttz, Amt->getType()); + Result = Builder.CreateCall2(F, Amt, Builder.getTrue()); Result = Builder.CreateAdd(Result, ConstantInt::get(Result->getType(), 1)); Result = CastToUIntType(Result, ConvertType(TREE_TYPE(exp))); From stoklund at 2pi.dk Mon Dec 12 13:25:54 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 12 Dec 2011 19:25:54 -0000 Subject: [llvm-commits] [llvm] r146401 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Message-ID: <20111212192554.790721BE004@llvm.org> Author: stoklund Date: Mon Dec 12 13:25:54 2011 New Revision: 146401 URL: http://llvm.org/viewvc/llvm-project?rev=146401&view=rev Log: Add a postOffset() alignment argument. This computes the offset of the layout sucessor block, considering its alignment as well. Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=146401&r1=146400&r2=146401&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Dec 12 13:25:54 2011 @@ -142,21 +142,26 @@ return Unalign ? Unalign : KnownBits; } - /// Compute the offset immediately following this block. - unsigned postOffset() const { + /// Compute the offset immediately following this block. If LogAlign is + /// specified, return the offset the successor block will get if it has + /// this alignment. + unsigned postOffset(unsigned LogAlign = 0) const { unsigned PO = Offset + Size; - if (!PostAlign) + unsigned LA = std::max(unsigned(PostAlign), LogAlign); + if (!LA) return PO; // Add alignment padding from the terminator. - return WorstCaseAlign(PO, PostAlign, internalKnownBits()); + return WorstCaseAlign(PO, LA, internalKnownBits()); } /// Compute the number of known low bits of postOffset. If this block /// contains inline asm, the number of known bits drops to the /// instruction alignment. An aligned terminator may increase the number /// of know bits. - unsigned postKnownBits() const { - return std::max(unsigned(PostAlign), internalKnownBits()); + /// If LogAlign is given, also consider the alignment of the next block. + unsigned postKnownBits(unsigned LogAlign = 0) const { + return std::max(std::max(unsigned(PostAlign), LogAlign), + internalKnownBits()); } }; @@ -1020,14 +1025,10 @@ void ARMConstantIslands::AdjustBBOffsetsAfter(MachineBasicBlock *BB) { for(unsigned i = BB->getNumber() + 1, e = MF->getNumBlockIDs(); i < e; ++i) { // Get the offset and known bits at the end of the layout predecessor. - unsigned Offset = BBInfo[i - 1].postOffset(); - unsigned KnownBits = BBInfo[i - 1].postKnownBits(); - - // Add padding before an aligned block. This may teach us more bits. - if (unsigned Align = MF->getBlockNumbered(i)->getAlignment()) { - Offset = WorstCaseAlign(Offset, Align, KnownBits); - KnownBits = std::max(KnownBits, Align); - } + // Include the alignment of the current block. + unsigned LogAlign = MF->getBlockNumbered(i)->getAlignment(); + unsigned Offset = BBInfo[i - 1].postOffset(LogAlign); + unsigned KnownBits = BBInfo[i - 1].postKnownBits(LogAlign); // This is where block i begins. BBInfo[i].Offset = Offset; From stoklund at 2pi.dk Mon Dec 12 13:25:51 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 12 Dec 2011 19:25:51 -0000 Subject: [llvm-commits] [llvm] r146400 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Message-ID: <20111212192551.9E94E1BE003@llvm.org> Author: stoklund Date: Mon Dec 12 13:25:51 2011 New Revision: 146400 URL: http://llvm.org/viewvc/llvm-project?rev=146400&view=rev Log: Fix typo. Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=146400&r1=146399&r2=146400&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Dec 12 13:25:51 2011 @@ -580,7 +580,7 @@ } /// getCPELogAlign - Returns the required alignment of the constant pool entry -/// represented by CPEMI. ALignment is measured in log2(bytes) units. +/// represented by CPEMI. Alignment is measured in log2(bytes) units. unsigned ARMConstantIslands::getCPELogAlign(const MachineInstr *CPEMI) { assert(CPEMI && CPEMI->getOpcode() == ARM::CONSTPOOL_ENTRY); From daniel at zuster.org Mon Dec 12 13:31:23 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 12 Dec 2011 19:31:23 -0000 Subject: [llvm-commits] [zorg] r146402 - in /zorg/trunk/lnt/lnt/viewer: app.py publisher.py root.ptl simple.ptl zview/__init__.py zview/zviewui.ptl Message-ID: <20111212193124.072F51BE003@llvm.org> Author: ddunbar Date: Mon Dec 12 13:31:23 2011 New Revision: 146402 URL: http://llvm.org/viewvc/llvm-project?rev=146402&view=rev Log: lnt.viewer: Start ripping out Quixote based UI. Removed: zorg/trunk/lnt/lnt/viewer/app.py zorg/trunk/lnt/lnt/viewer/publisher.py zorg/trunk/lnt/lnt/viewer/root.ptl zorg/trunk/lnt/lnt/viewer/simple.ptl zorg/trunk/lnt/lnt/viewer/zview/__init__.py zorg/trunk/lnt/lnt/viewer/zview/zviewui.ptl Removed: zorg/trunk/lnt/lnt/viewer/app.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/app.py?rev=146401&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/app.py (original) +++ zorg/trunk/lnt/lnt/viewer/app.py (removed) @@ -1,22 +0,0 @@ -import os -import sys - -def create_publisher(configPath): - import warnings - warnings.simplefilter("ignore", category=DeprecationWarning) - - configData = {} - exec open(configPath) in configData - - # Optionally enable auto-restart. - if configData.get('wsgi_restart', False): - from lnt.viewer import wsgi_restart - wsgi_restart.track(configPath) - wsgi_restart.start() - - from lnt.viewer import publisher - return publisher.create_publisher(configPath, configData, threaded=True) - -def create_app(cfg_path=None): - import quixote.wsgi - return quixote.wsgi.QWIP(create_publisher(cfg_path)) Removed: zorg/trunk/lnt/lnt/viewer/publisher.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/publisher.py?rev=146401&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/publisher.py (original) +++ zorg/trunk/lnt/lnt/viewer/publisher.py (removed) @@ -1,48 +0,0 @@ -import time -from quixote.publish import Publisher - -# FIXME: This is a bit of a hack. -class ExtPublisher(Publisher): - def __init__(self, *args, **kwargs): - Publisher.__init__(self, *args, **kwargs) - self.create_time = time.time() - - def process_request(self, request): - request.start_time = time.time() - return Publisher.process_request(self, request) - -class ThreadedPublisher(ExtPublisher): - is_thread_safe = True - - def __init__ (self, root_namespace, *args, **kwargs): - ExtPublisher.__init__(self, root_namespace, *args, **kwargs) - self._request_dict = {} - - def _set_request(self, request): - import thread - self._request_dict[thread.get_ident()] = request - - def _clear_request(self): - import thread - try: - del self._request_dict[thread.get_ident()] - except KeyError: - pass - - def get_request(self): - import thread - return self._request_dict.get(thread.get_ident()) - -def create_publisher(configPath, configData, threaded=False): - import Config - config = Config.Config.fromData(configPath, configData) - - from quixote import enable_ptl - enable_ptl() - - from root import RootDirectory - if threaded: - publisher_class = ThreadedPublisher - else: - publisher_class = ExtPublisher - return publisher_class(RootDirectory(config), display_exceptions='plain') Removed: zorg/trunk/lnt/lnt/viewer/root.ptl URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/root.ptl?rev=146401&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/root.ptl (original) +++ zorg/trunk/lnt/lnt/viewer/root.ptl (removed) @@ -1,418 +0,0 @@ -# -*- python -*- - -""" -Root LNT webapp UI. -""" - -import os -import re -import time - -import quixote -import quixote.form -import quixote.form.css -import quixote.errors -from quixote import get_response -from quixote.directory import Directory, Resolving -from quixote.util import StaticDirectory - -import lnt -from lnt.db import perfdbsummary -from lnt.util import json -from lnt.db import perfdb -from lnt.viewer import Util -from lnt.db.perfdb import Machine, Run - -class RootDirectory(Resolving, Directory): - _q_exports = ["", "resources", "js", "machines", "runs", "tests", - "browse", "submitRun", "nightlytest", "simple", "zview", - - # Redirections. - "select_db", - - ("favicon.ico", "favicon_ico")] - - def __init__(self, config, dbName='default', dbInfo=None, pathToRoot="./"): - self.config = config - self.dbName = dbName - self.dbInfo = dbInfo - if self.dbInfo is None: - self.dbInfo = config.databases[dbName] - self.pathToRoot = pathToRoot - self.db_summary = None - - def getDB(self): - db = perfdb.PerfDB(self.dbInfo.path) - - # Enable SQL logging with db_log. - # - # FIXME: Conditionalize on an is_production variable. - request = quixote.get_request() - if request.form.get('db_log'): - import logging, StringIO - request.db_log = StringIO.StringIO() - logger = logging.getLogger("sqlalchemy") - logger.addHandler(logging.StreamHandler(request.db_log)) - db.engine.echo = True - - return db - - def getHeader [html] (self, title, pathToRoot, components=None, - addSorttableJS=True, - addFormCSS=False, - addPopupJS=False, - addGraphJS=False, - addJSScript=None, - onload=None): - pathToRoot = os.path.join(self.pathToRoot, - pathToRoot) - - """ - - - """ - if addSorttableJS: - """ - - """ % (pathToRoot,) - if addPopupJS: - """ - - """ % (pathToRoot,) - if addGraphJS: - """ - - """ % pathToRoot - if addJSScript: - """\ - -""" % (addJSScript,) - - if components: - component_title = ' : %s' %( - ' : '.join(short_name for short_name,_ in components)) - else: - component_title = '' - """ - - """ % (pathToRoot,) - if addFormCSS: - """ - - """ % (pathToRoot,) - """ - - %s%s - %s - - """ % (pathToRoot, self.config.name, component_title, title) - - """\ - """ % (onload,) - else: - """>""" - - # Database selection header. - """\ -
-
- - - - - -
- - [%s] - - - Database: - - -
-
-
- """ - - if components is not None: - """

%s""" % (pathToRoot, self.config.name) - for short_name,path in components: - """ : %s""" % (pathToRoot,self.dbName, - path,short_name) - """ - %s

""" % title - - def getFooter [html] (self): - db_log = getattr(quixote.get_request(), str('db_log'), None) - if db_log: - """

SQL Log

%s
""" % db_log.getvalue() - - current = time.time() - """ -
- LNT Version: %s
- Server Started: %s
- Generated: %s
- Render Time: %.2fs
- - - """ % (lnt.__version__, - time.strftime(str('%Y-%m-%dT%H:%M:%Sz'), - time.localtime(quixote.get_publisher().create_time)), - time.strftime(str('%Y-%m-%dT%H:%M:%Sz'), - time.localtime(current)), - current - quixote.get_request().start_time) - - def get_db_summary(self, db): - if not self.db_summary or not self.db_summary.is_up_to_date(db): - self.db_summary = perfdbsummary.PerfDBSummary.fromdb(db) - return self.db_summary - - def _q_index [html] (self): - # Get a DB connection. - db = self.getDB() - - self.getHeader("Overview", ".", - components=(),) - - # Display available test result suites. - summary = self.get_db_summary(db) - """ -

Test Results

""" - for suite in summary.suites: - """ - %s
""" % (os.path.join(*suite.path), suite.name) - - if self.dbInfo.showGeneral: - """ -
- -

General Database Access

-

Browse DB -

Submit Run - """ - - self.getFooter() - - def browse [html] (self): - # Get a DB connection. - db = self.getDB() - - self.getHeader("Database Browser", ".", components=(), - addSorttableJS=False) - - # List machines. - """ -

Machines

- - - - - - - """ - for m in db.machines(): - """ - - - - """ % (m.id, m.name, m.number) - """ -
Name
%s:%d
- """ - - # List runs. - """ -

Run List

- - - - - - - - - - """ - for r,m in db.session.query(Run,Machine).join(Machine): - """ - - - - - - - """ % (r.id, r.id, - r.machine_id, m.name, m.number, - r.start_time, r.end_time) - """ -
IDMachineStart TimeEnd Time
%d%s:%d%s%s
- """ - - - # List tests. - """ -

Test List

- - - - - - - - """ - for t in db.tests(): - """ - - - - - """ % (t.id, t.id, t.name) - """ -
IDTest
%d%s
- """ - - self.getFooter() - - def submitRun(self): - form = quixote.form.Form(enctype="multipart/form-data") - form.add(quixote.form.FileWidget, "file", - title="Input File (plist)") - form.add(quixote.form.TextWidget, "input_data", - title="Input Data (plist)") - form.add(quixote.form.SingleSelectWidget, "commit", - title="Commit", value="0", - options=["0", "1"], required=True) - form.add_submit("submit", "Submit") - - def render [html] (): - self.getHeader("Submit Run", ".", components=(), addFormCSS=1) - form.render() - self.getFooter() - - if not form.is_submitted() or form.has_errors(): - return render() - - import plistlib - import tempfile - from lnt.util import ImportData - from StringIO import StringIO - - commit = int(form.get_widget('commit').parse()) - - # Get the input data. - input_file = form.get_widget('file') - file_value = input_file.parse() - - input_data = form.get_widget('input_data') - data_value = input_data.parse() - - if ((file_value is None and data_value is None) or - (file_value is not None and data_value is not None)): - raise quixote.errors.QueryError( - "Must supply either an input file or input text data") - - if file_value is not None: - data_value = file_value.fp.read() - file_value.fp.close() - - # Stash a copy of the raw submission. - prefix = time.strftime("data-%Y-%m-%d_%H-%M-%S") - fd,path = tempfile.mkstemp(prefix=prefix, - suffix='.plist', - dir=self.config.tempDir) - os.write(fd, data_value) - os.close(fd) - - # Get a DB connection. - db = self.getDB() - - # Import the data. - # - # FIXME: Gracefully handle formats failures and DOS attempts. We - # should at least reject overly large inputs. - result = ImportData.import_and_report( - self.config, self.dbName, db, path, '', commit) - - return json.dumps(result) - - def favicon_ico(self): - response = get_response() - response.set_content_type("image/x-icon") - response.set_expires(days=1) - return FAVICON - - def _q_resolve(self, component): - if component == 'machines': - import machines - return machines.MachinesDirectory(self) - if component == 'runs': - import runs - return runs.RunsDirectory(self) - if component == 'tests': - import tests - return tests.TestsDirectory(self) - if component == 'nightlytest': - import nightlytest - return nightlytest.NightlyTestDirectory(self) - if component == 'simple': - import simple - return simple.RootDirectory(self) - if component == 'zview': - from zview import zviewui - return zviewui.ZViewUI(self) - - def _q_lookup(self, component): - if component.startswith('db_'): - dbName = component[3:] - dbInfo = self.config.databases.get(dbName) - if dbInfo: - return RootDirectory(self.config, dbName, dbInfo, "../") - - def select_db(self): - request = quixote.get_request() - dbName = request.form.get('db') - return quixote.redirect("db_%s/" % (dbName,)) - - resources = StaticDirectory(os.path.join(os.path.dirname(__file__), - 'resources'), - list_directory=True) - js = StaticDirectory(os.path.join(os.path.dirname(__file__), 'js'), - list_directory=True) - -FAVICON = """\ -AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEA -AAAAAAD///8AAAD/ALOz/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgEAAAAAAAAAAAAAAAAAAgECAQIAAAAAAAAAAAAAAAEA -AAIBAQIAAAACAQIAAAECAAAAAAIBAQICAQIBAgECAAAAAAAAAAIBAQIAAAECAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=""".decode('base64') Removed: zorg/trunk/lnt/lnt/viewer/simple.ptl URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/simple.ptl?rev=146401&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/simple.ptl (original) +++ zorg/trunk/lnt/lnt/viewer/simple.ptl (removed) @@ -1,953 +0,0 @@ -# -*- python -*- - -""" -Nightly Test UI instance for actual nightly test data. -""" - -import sys -import time - -import quixote -from quixote.directory import Directory -from quixote.errors import TraversalError -from quixote.html import htmltext - -from lnt.db import runinfo -from lnt.db import perfdbsummary -from lnt.util import stats -from lnt.util import NTEmailReport -from lnt.viewer import GraphUtil - -import Util -from Util import safediv -from NTUtil import * - -from lnt.db.perfdb import Machine, Run, RunInfo, Test - -class SimpleRunUI(Directory): - _q_exports = ["", "graph", "report", "text_report"] - - def __init__(self, root, tag, idstr): - self.root = root - self.tag = tag - try: - self.id = int(idstr) - except ValueError, exc: - raise TraversalError(str(exc)) - self.popupDepth = 0 - - def renderPopupBegin [html] (self, id, title, hidden): - self.popupDepth += 1 - """\ -

- (%s) %s -

- """ % (id, id, ("+","-")[hidden], title, id, ("","none")[hidden], - self.popupDepth) - - def renderPopupEnd [html] (self): - """ -
""" - self.popupDepth -= 1 - - def getInfo(self, db): - request = quixote.get_request() - - compareToID = request.form.get('compare', '') - compareTo = None - if compareToID: - try: - compareTo = db.getRun(int(compareToID)) - except: - pass - - run = db.getRun(self.id) - - # Get the run summary which has run ordering information. - run_summary = perfdbsummary.SimpleSuiteRunSummary.get_summary(db, - self.tag) - - # Find previous run to compare to. - if compareTo is None: - id = run_summary.get_previous_run_on_machine(run.id) - if id is not None: - compareTo = db.getRun(id) - - return run, run_summary, compareTo - - def show_run_page [html] (self, db, run, run_summary, compare_to, - contents_fn): - machine = run.machine - - """ -
- - - - - - - - - - """ % (machine.name, machine.number, run.start_time, - run.info['run_order'].value) - if compare_to: - """ - - - - - """ % (compare_to.start_time, compare_to.info['run_order'].value) - """ -
Machine:%s:%d
Run:%s (%s)
Compare To:%s (%s)
-
-

- """ - - """ - - - - - -
- Homepage -

Machine:

- %s:%d -

Runs:

-
    - """ % (machine.id, machine.name, machine.number) - - # Show a small number of neighboring runs. - cur_id = run.id - for i in range(3): - id = run_summary.get_next_run_on_machine(cur_id) - if not id: - break - cur_id = id - for i in range(6): - r = db.getRun(cur_id) - if r == run: - """
  • %s

    """ % (r.id, - r.start_time) - else: - """
  • %s """ % (r.id, r.start_time) - cur_id = run_summary.get_previous_run_on_machine(cur_id) - if cur_id is None: - break - - """ -
-
- - - - - - - - - -
Nickname %s
Machine ID %d
""" % (machine.name, machine.id) - - self.renderPopupBegin('machine_info', 'Machine Info', True) - """ - """ - info = machine.info.values() - info.sort(key = lambda i: i.key) - for mi in info: - """ - - - - - """ % (mi.key, mi.value) - """ -
%s %s
""" - self.renderPopupEnd() - - self.renderPopupBegin('run_info', 'Run Info', True) - """ - """ - info = run.info.values() - info.sort(key = lambda i: i.key) - for ri in info: - """ - - - - - """ % (ri.key, ri.value) - """ -
%s %s
""" - self.renderPopupEnd() - - contents_fn() - - """ -
- """ - - self.root.getFooter() - - def _q_index [html] (self): - # Get a DB connection. - db = self.root.getDB() - - run,run_summary,compare_to = self.getInfo(db) - machine = run.machine - - # Add JS to run the init_report function, if embedded. - init = """\ - function init() { - if (init_report) { - init_report(); - } - } - """ - self.root.getHeader('Run Results', "../../..", - components=((self.tag, - '%s/%s' % ('simple',self.tag)), - ('machine', - 'simple/%s/machines/%d'%(self.tag, - machine.id))), - addPopupJS=True, addFormCSS=True, addGraphJS=True, - addJSScript=init, - onload="init()") - - self.show_run_page(db, run, run_summary, compare_to, - lambda: self._q_index_body(db, run, run_summary, - compare_to)) - - def graph [html] (self): - def init_form(form): - # Add default fields, Quixote doesn't like missing values if the - # form data exists. - form['show_mad'] = form.get('show_mad') or '1' - form['show_stddev'] = form.get('show_stddev') or '0' - form['show_linear_regression'] = form.get( - 'show_linear_regression') or '1' - - request = quixote.get_request() - init_form(request.form) - - # Get the view options form. - form = quixote.form.Form(method=str("get")) - form.add(quixote.form.IntWidget, "show_mad", title="Show MAD") - form.add(quixote.form.IntWidget, "show_stddev", - title="Show Standard Deviation") - form.add(quixote.form.IntWidget, "show_linear_regression", - title="Show Linear Regression Line") - - # Add all the hidden fields. - for name,value in request.form.items(): - if (name.startswith(str('test.')) or name.startswith(str('pset.'))): - form.add(quixote.form.HiddenWidget, name, value) - - form.add_submit("submit", "Update") - - # Get the form values. - - # Get a DB connection. - db = self.root.getDB() - - run,run_summary,compare_to = self.getInfo(db) - machine = run.machine - - # Load the test suite summary. - ts_summary = perfdbsummary.get_simple_suite_summary(db, self.tag) - - # Load the form data. - show_mad = form.get('show_mad') - show_stddev = form.get('show_stddev') - show_linear_regression = form.get('show_linear_regression') - graph_tests = [] - graph_psets = [] - for name,value in request.form.items(): - if name.startswith(str('test.')): - graph_tests.append(name[5:]) - elif name.startswith(str('pset.')): - graph_psets.append(ts_summary.parameter_sets[int(name[5:])]) - - # Get the test ids we want data for. - test_ids = [ts_summary.test_id_map[(name,pset)] - for name in graph_tests - for pset in graph_psets] - - # Build the graph data - pset_id_map = dict([(pset,i) - for i,pset in enumerate(ts_summary.parameter_sets)]) - legend = [] - num_points = 0 - plot_points = [] - plots = "" - plots_iter = GraphUtil.get_test_plots( - db, machine, test_ids, run_summary, ts_summary, - show_mad_error = show_mad, show_stddev = show_stddev, - show_linear_regression = show_linear_regression, show_points = True) - for test_id, plot_js, col, points, ext_points in plots_iter: - test = db.getTest(test_id) - name = test.name - pset = test.get_parameter_set() - - num_points += len(points) - legend.append(("%s : P%d" % (name, pset_id_map[pset]), col)) - plots += plot_js - plot_points.append(ext_points) - - def graph_body [html] (): - # Show the view options form. - self.renderPopupBegin('view_options', 'View Options', True) - form.render() - self.renderPopupEnd() - - """ -

Graph

- - - - - -
- - - - - """ - for name,col in legend: - """ - - """ % (255*col[0], 255*col[1], 255*col[2], name) - """ -
Test
 %s
-
- - Shift-Left Mouse: Pan
- Alt/Meta-Left Mouse: Zoom
- Wheel: Zoom (Shift Slows)
-
-
-

- Plots: %d
- Num Points: %d
- """ % (len(test_ids), num_points) - - """ -

Deltas

""" - - resample_list = set() - new_sample_list = [] - for (name,col),points in zip(legend,plot_points): - """ -

%s

""" % name - """ - - - - - - - - - - - - - - - - - - - - - - """ - points.sort() - deltas = [(Util.safediv(p1[1], p0[1]), p0, p1) - for p0,p1 in Util.pairs(points)] - deltas.sort() - deltas.reverse() - for (pct,(r0,t0,mad0,med0),(r1,t1,mad1,med1)) in deltas[:20]: - """ - - - - %s - - - - - - - """ % (r1, r1, r0, r0, Util.PctCell(pct, delta=True).render(), - t1, t0, r1 - r0, mad1, mad0, med1-t1, med0-t0) - - # Find the best next revision to sample, unless we have - # sampled to the limit. To conserve resources, we try to - # align to the largest "nice" revision boundary that we can, - # so that we tend to sample the same revisions, even as we - # drill down. - assert r0 < r1 and r0 != r1 - if r0 + 1 != r1: - for align in [scale * boundary - for scale in (100000,10000,1000,100,10,1) - for boundary in (5, 1)]: - r = r0 + 1 + (r1 - r0)//2 - r = (r // align) * align - if r0 < r < r1: - new_sample_list.append(r) - break - - resample_list.add(r0) - resample_list.add(r1) - """ -
Revision ValueMADMed - Min
CurrentPreviousDelta (%)CurrentPrevious# Revs CurrentPreviousCurrentPrevious
%d%d%.4f%.4f%d %.4f%.4f%.4f%.4f
""" - - """ -

Revisions to Sample

- %s -

-

Revisions to Resample

- %s -

""" % (' '.join(map(str, new_sample_list)), - ' '.join(map(str, Util.sorted(resample_list)))) - - # FIXME: Allow run_order to define this. - xAxis_format = 'graph.xAxis.formats.normal' - graph_init = """\ - function init() { - graph = new Graph2D("graph"); - graph.clearColor = [1, 1, 1]; - %s - graph.xAxis.format = %s; - graph.draw(); - } - """ % (plots,xAxis_format) - self.root.getHeader('Run Results', "../../..", - components=((self.tag, - '%s/%s' % ('simple',self.tag)), - ('machine', - 'simple/%s/machines/%d' %(self.tag, - machine.id)), - ('run', 'simple/%s/%d' % (self.tag, - run.id))), - addPopupJS=True, addGraphJS=True, - addJSScript=graph_init, - onload="init()") - - self.show_run_page(db, run, run_summary, compare_to, graph_body) - - def report(self): - db = self.root.getDB() - - request = quixote.get_request() - show_graphs = bool(request.form.get('show_graphs')) - run,run_summary,compare_to = self.getInfo(db) - - _, _, html_report = NTEmailReport.getSimpleReport(None, - db, run, str("%s/db_%s/") % (self.root.config.zorgURL, - self.root.dbName), - True, True, show_graphs = show_graphs) - - return htmltext(html_report) - - def text_report(self): - db = self.root.getDB() - - run,run_summary,compare_to = self.getInfo(db) - - _, text_report, _ = NTEmailReport.getSimpleReport(None, - db, run, str("%s/db_%s/") % (self.root.config.zorgURL, - self.root.dbName), - True, True) - - response = quixote.get_response() - response.set_content_type('text/plain') - - return text_report - - def _q_index_body [html] (self, db, run, run_summary, compare_to): - # Get the test status style used in each run. - run_status_kind = run_summary.get_run_status_kind(db, run.id) - if compare_to: - compare_to_status_kind = run_summary.get_run_status_kind( - db, compare_to.id) - else: - compare_to_status_kind = None - - # Load the test suite summary. - ts_summary = perfdbsummary.get_simple_suite_summary(db, self.tag) - sri = runinfo.SimpleRunInfo(db, ts_summary) - - # Get the view options form. - form = quixote.form.Form(method=str("get")) - form.add(quixote.form.CheckboxWidget, "show_delta", - title="Show Delta") - form.add(quixote.form.CheckboxWidget, "show_stddev", - title="Show Standard Deviation") - form.add(quixote.form.CheckboxWidget, "show_mad", - title="Show Median Absolute Deviation") - form.add(quixote.form.CheckboxWidget, "show_all", - title="Show All Values") - form.add(quixote.form.CheckboxWidget, "show_all_samples", - title="Show All Samples") - form.add(quixote.form.CheckboxWidget, "show_sample_counts", - title="Show Sample Counts") - form.add(quixote.form.IntWidget, "num_comparison_runs", - title="Number of Comparison Runs") - form.add(quixote.form.CheckboxWidget, "show_graphs", - title="Show Report Graphs") - form.add_submit("submit", "Update") - - request = quixote.get_request() - show_graphs = bool(form['show_graphs']) - show_delta = bool(form['show_delta']) - show_stddev = bool(form['show_stddev']) - show_mad = bool(form['show_mad']) - show_all = bool(form['show_all']) - show_all_samples = bool(form['show_all_samples']) - show_sample_counts = bool(form['show_sample_counts']) - show_graphs = bool(form['show_graphs']) - try: - num_comparison_runs = int(form['num_comparison_runs']) - except: - num_comparison_runs = 10 - - self.renderPopupBegin('view_options', 'View Options', True) - form.render() - self.renderPopupEnd() - - _, text_report, html_report = NTEmailReport.getSimpleReport( - None, db, run, str("%s/db_%s/") % (self.root.config.zorgURL, - self.root.dbName), - True, True, only_html_body = True, show_graphs = show_graphs, - num_comparison_runs = num_comparison_runs) - self.renderPopupBegin('text_report', 'Report (Text)', True) - """ -

%s
""" % (text_report,) - self.renderPopupEnd() - - self.renderPopupBegin('html_report', 'Report (HTML)', False) - htmltext(html_report) - self.renderPopupEnd() - - # Get the list of tests we are interested in. - interesting_runs = [run.id] - if compare_to: - interesting_runs.append(compare_to.id) - test_names = ts_summary.get_test_names_in_runs(db, interesting_runs) - - # Gather the runs to use for statistical data, if enabled. - cur_id = run.id - comparison_window = [] - for i in range(num_comparison_runs): - cur_id = run_summary.get_previous_run_on_machine(cur_id) - if not cur_id: - break - comparison_window.append(cur_id) - - # Render the page. - def get_cell_value [html] (cr): - test_status = cr.get_test_status() - value_status = cr.get_value_status() - - run_cell_value = "-" - if cr.current is not None: - run_cell_value = "%.4f" % cr.current - - cell_color = None - if test_status == runinfo.REGRESSED: - cell_color = (233,128,128) - elif test_status == runinfo.IMPROVED: - cell_color = (143,223,95) - elif test_status == runinfo.UNCHANGED_FAIL: - cell_color = (255,195,67) - - if cell_color: - """ - %s""" % ( - cell_color[0], cell_color[1], cell_color[2], run_cell_value) - else: - """ - %s""" % (run_cell_value,) - - if show_all or value_status in (runinfo.REGRESSED, - runinfo.IMPROVED): - Util.PctCell(cr.pct_delta).render() - else: - """-""" - - if show_delta: - if cr.delta is not None: - """%.4f""" % cr.delta - else: - """-""" - if show_stddev: - if cr.stddev is not None: - """%.4f""" % cr.stddev - else: - """-""" - if show_mad: - if cr.MAD is not None: - """%.4f""" % cr.MAD - else: - """-""" - - if show_all_samples: - """[%s]""" % (", ".join("%.4f" % v - for v in cr.get_samples()),) - - if show_sample_counts: - """%d""" % len(cr.get_samples()) - - - """ -

Parameter Sets

- - - - - """ % len(ts_summary.parameter_sets) - for key in ts_summary.parameter_keys: - """ - """ % key - """ - """ - for (i,pset) in enumerate(ts_summary.parameter_sets): - """ - - """ % (i,) - pmap = dict(pset) - for key in ts_summary.parameter_keys: - item = pmap.get(key) - if item is None: - item = "-" - """ - """ % item - """ - """ - """ -
NameParameters
%s
P%s%s
""" - - """ -

Tests

""" - - pset_cols = (2 + show_delta + show_stddev + show_mad + - show_all_samples + show_sample_counts) - """ -
- - - - """ - for i in range(len(ts_summary.parameter_sets)): - """ - """ % (pset_cols, i) - """ - """ - for i in range(len(ts_summary.parameter_sets)): - """ - - """ % i - if show_delta: - """ - """ - if show_stddev: - """ - """ - if show_mad: - """ - """ - if show_all_samples: - """ - """ - if show_sample_counts: - """ - """ - """ - - """ - for name in test_names: - """ - - - """ % (name, name) - for pset in ts_summary.parameter_sets: - cr = sri.get_run_comparison_result( - run, run_status_kind, compare_to, compare_to_status_kind, - name, pset, comparison_window) - get_cell_value(cr) - """ - """ - """ -
NameP%d
%%ΔσMADSamplesN
%s
- -
""" - -class MachineUI(Directory): - _q_exports = [""] - - def __init__(self, root, parent, idstr): - self.root = root - self.parent = parent - try: - self.id = int(idstr) - except ValueError, exc: - raise TraversalError(str(exc)) - self.popupDepth = 0 - - def renderPopupBegin [html] (self, id, title, hidden): - self.popupDepth += 1 - """\ -

- (%s) %s -

- """ % (id, id, ("+","-")[hidden], title, id, ("","none")[hidden], - self.popupDepth) - - def renderPopupEnd [html] (self): - """ -
""" - self.popupDepth -= 1 - - def _q_index [html] (self): - # Get a DB connection. - db = self.root.getDB() - - machine = db.getMachine(self.id) - - self.root.getHeader("Machine: %s:%d" % (machine.name,machine.number), - "%s/../.." % self.parent.root_path, - components=self.parent.components, - addPopupJS=True) - - # Get the run summary which has run ordering information. - run_summary = perfdbsummary.SimpleSuiteRunSummary.get_summary( - db, self.parent.tag) - - """ - - - - - -
- Homepage -

Relatives:

-
    - """ - # List all machines with this name. - for m in db.machines(name=machine.name): - """
  • %s:%d
  • """ % (m.id, m.name, m.number) - """ -
-
- - - - - - - - - -
Nickname %s
Machine ID %d
""" % (machine.name, machine.id) - self.renderPopupBegin('machine_info', 'Machine Info', True) - """ - """ - info = machine.info.values() - info.sort(key = lambda i: i.key) - for mi in info: - """ - - - - """ % (mi.key, mi.value) - """ -
%s %s
""" - self.renderPopupEnd() - - # List associated runs. - run_info = db.session.query(Run.id, Run.start_time, Run.end_time).\ - filter(Run.machine_id == machine.id).\ - filter(Run.id.in_(run_summary.runs_in_order)).all() - run_info_map = dict((id,(start_time,end_time)) - for id,start_time,end_time in run_info) - """ -

- - - - - - - - - - """ - for order in run_summary.run_orders: - run_ids = [id for id in run_summary.runs_by_order[order] - if id in run_info_map] - if not run_ids: - continue - - """ - - """ % (len(run_ids), order) - for run_id in run_ids: - start_time,end_time = run_info_map[run_id] - if run_id != run_ids[0]: - """""" - """ - - - - """ % (start_time, end_time, run_id) - """ -
Run OrderStart TimeEnd Time 
%s
%s%sView Results
""" - - """ -

""" - - self.root.getFooter() - -class MachinesDirectory(Directory): - _q_exports = [""] - - def __init__(self, parent): - Directory.__init__(self) - self.parent = parent - - def _q_index [plain] (self): - """ - machine access - """ - - def _q_lookup(self, component): - return MachineUI(self.parent.root, self.parent, component) - - -class TagRootDirectory(Directory): - _q_exports = [""] - - def __init__(self, root, tag): - Directory.__init__(self) - self.tag = tag - self.root = root - self.root_path = '../..' - self.components = ((self.tag, '%s/%s' % ('simple',self.tag)),) - - def getTags(self): - return (self.tag,) - - def _q_index [plain] (self): - # Get a DB connection - db = self.root.getDB() - - self.root.getHeader('Overview', self.root_path, self.components) - - # Find recent runs. - """ -

Submission Overview

- - - - - -
-
-

Test Machines

- - - - - - - - - """ - - # Show the most recent entry for each machine. - q = db.session.query(Machine.name).distinct().order_by(Machine.name) - for name, in q: - # Get the most recent run for this machine name. - q = db.session.query(Run).join(Machine).filter(Machine.name == name) - r = q.order_by(Run.start_time.desc()).first() - - # Limit by matching tags. - if 'tag' in r.info: - tag = r.info['tag'].value - else: - tag = None - if tag not in self.getTags(): - continue - - """ - - - - - - """ % (r.start_time, r.machine.id, r.machine.name, - r.machine.number, r.id) - - """ -
Latest SubmissionMachineResults
%s%s:%dView Results
-
-
-
-

Recent Submissions

- - - - - - - - - - - """ - - # Show the 20 most recent submissions, ordered by time. - for r in db.session.query(Run).order_by(Run.start_time.desc())[:20]: - # Limit by matching tags. - if 'tag' not in r.info or 'run_order' not in r.info: - continue - if tag not in self.getTags(): - continue - - m = r.machine - """ - - - - - - - - """ % (r.info['run_order'].value, r.start_time, r.end_time, m.id, - m.name, m.number, r.id) - - """ -
Run OrderStart TimeEnd TimeMachineResults
%s%s%s%s:%dView Results
-
-
- """ - - self.root.getFooter() - - def _q_lookup(self, component): - if component == 'machines': - return MachinesDirectory(self) - return SimpleRunUI(self.root, self.tag, component) - -class RootDirectory(Directory): - def __init__(self, root): - Directory.__init__(self) - self.root = root - - def _q_lookup(self, component): - return TagRootDirectory(self.root, component) Removed: zorg/trunk/lnt/lnt/viewer/zview/__init__.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/zview/__init__.py?rev=146401&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/zview/__init__.py (original) +++ zorg/trunk/lnt/lnt/viewer/zview/__init__.py (removed) @@ -1 +0,0 @@ -__all__ = [] Removed: zorg/trunk/lnt/lnt/viewer/zview/zviewui.ptl URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/zview/zviewui.ptl?rev=146401&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/zview/zviewui.ptl (original) +++ zorg/trunk/lnt/lnt/viewer/zview/zviewui.ptl (removed) @@ -1,217 +0,0 @@ -# -*- python -*- - -""" -Playground for AJAXy interface to nightly test data. -""" - -from quixote.directory import Directory -from quixote.html import htmltext - -from lnt.db.perfdb import Machine, Run, Sample, Test -from lnt.viewer import NTUtil - -from sqlalchemy import func - -try: - import json -except ImportError: - import simplejson as json - -class ZViewUI(Directory): - _q_exports = ["", "get_machines", "get_tests", "get_test_data", - "get_test_names"] - - def __init__(self, root): - self.root = root - - def get_machines(self): - db = self.root.getDB() - q = db.session.query(Machine.name.distinct()) - q = q.order_by(Machine.name) - return json.dumps(q.all()) - - def get_tests(self): - db = self.root.getDB() - q = db.session.query(Test.id, Test.name) - q = q.order_by([Test.name]) - return json.dumps(q.all()) - - def get_test_data(self): - import quixote, time - from sqlalchemy import orm - - request = quixote.get_request() - machine_name = str(request.form.get('machine_name')) - test_name = str(request.form.get('test_name')) - component = str(request.form.get('component')) - - full_test_name = 'nightlytest.' + test_name + '.' + component - - # FIXME: Return data about machine crossings. - db = self.root.getDB() - q = db.session.query(Test.id).filter(Test.name == full_test_name) - q = db.session.query(Run.start_time, Sample.value) - q = q.join(Sample).join(Test) - q = q.filter(Test.name == full_test_name) - q = q.join(Machine) - q = q.filter(Machine.name == machine_name) - q = q.order_by(Run.start_time.desc()) - return json.dumps([(time.mktime(run_time.timetuple()), value) - for run_time,value in q]) - - def get_test_names(self): - # FIXME: We should fix the DB to be able to do this directly. - left = NTUtil.kPrefix + '.' - right = '.' + NTUtil.kSentinelKeyName - f = func.substr(Test.name, len(left) + 1, - func.length(Test.name) - len(left) - len(right)) - - db = self.root.getDB() - q = db.session.query(f) - q = q.filter(Test.name.startswith(left)) - q = q.filter(Test.name.endswith(right)) - q = q.order_by(Test.name.desc()) - return json.dumps(q.all()) - - def _q_index [html] (self): - db = self.root.getDB() - - script = """ -machines = null; -tests = null; -graph = null; -active_test_data = null; - -function update_machine_list(data, text) { - machines = data; - - var elt = $('test_select_form_machine'); - elt.length = data.length; - for (var i = 0; i != data.length; ++i) { - elt[i].value = data[i]; - elt[i].text = data[i]; - } - - handle_test_change(); -} - -function update_test_list(data, text) { - tests = data; - - var elt = $('test_select_form_test'); - elt.length = data.length; - for (var i = 0; i != data.length; ++i) { - elt[i].value = data[i]; - elt[i].text = data[i]; - } - - handle_test_change(); -} - -function update_graph() { - update_selected_status(); - - graph.clearPlots(); - if (active_test_data && active_test_data.length) { - graph.clearColor = [1, 1, 1]; - graph.addPlot(active_test_data, new Graph2D_LinePlotStyle(1, [0,0,0])); - } else { - graph.clearColor = [1, .8, .8]; - } - graph.draw(); -} - -function update_selected_status() { - var machine_elt = $('test_select_form_machine'); - var test_elt = $('test_select_form_test'); - var machine = machines && machines[machine_elt.selectedIndex]; - var test = tests && tests[test_elt.selectedIndex]; - var numPts = active_test_data && active_test_data.length; - $('log').innerHTML = "Machine: " + machine + "
" + - "Test: " + test + "
" + - "Num Points: " + numPts; -} - -function handle_test_change() { - if (machines === null || tests === null) - return; - - var machine_elt = $('test_select_form_machine'); - var test_elt = $('test_select_form_test'); - var machine = machines[machine_elt.selectedIndex]; - var test = tests[test_elt.selectedIndex]; - var component = $('test_select_form_component').value; - - new Request.JSON({ - url: 'get_test_data', - method: 'get', - onSuccess: function(data, text) { - active_test_data = data; - update_graph(); - }, - data: "machine_name=" + encodeURIComponent(machine) + "&" + - "test_name=" + encodeURIComponent(test) + "&" + - "component=" + component, - }).send(); -} - -function init() { - // Initialize the graph object. - graph = new Graph2D("graph"); - graph.xAxis.format = graph.xAxis.formats.day; - update_graph(); - - // Load the machine lists. - new Request.JSON({ - url: 'get_machines', - onSuccess: update_machine_list, - }).send(); - - // Load the test list. - new Request.JSON({ - url: 'get_test_names', - onSuccess: update_test_list, - }).send(); -} -""" % locals() - - self.root.getHeader("ZView", "..", components=(), - addGraphJS=True, addJSScript=script, - onload='init()') - - """ -

Test Selection

-
-

Machine:

- -

Test:

- -

Component:

-
- -

Selected Test

-
-

Waiting...

-
- -

Graph

-
- -
- """ - - self.root.getFooter() From daniel at zuster.org Mon Dec 12 13:31:28 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 12 Dec 2011 19:31:28 -0000 Subject: [llvm-commits] [zorg] r146403 - in /zorg/trunk/lnt/lnt: lnttool/import_data.py server/config.py server/ui/app.py viewer/Config.py Message-ID: <20111212193128.7E1121BE004@llvm.org> Author: ddunbar Date: Mon Dec 12 13:31:28 2011 New Revision: 146403 URL: http://llvm.org/viewvc/llvm-project?rev=146403&view=rev Log: lnt: Move Config module into server package. Added: zorg/trunk/lnt/lnt/server/config.py - copied, changed from r146402, zorg/trunk/lnt/lnt/viewer/Config.py Removed: zorg/trunk/lnt/lnt/viewer/Config.py Modified: zorg/trunk/lnt/lnt/lnttool/import_data.py zorg/trunk/lnt/lnt/server/ui/app.py Modified: zorg/trunk/lnt/lnt/lnttool/import_data.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/lnttool/import_data.py?rev=146403&r1=146402&r2=146403&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/lnttool/import_data.py (original) +++ zorg/trunk/lnt/lnt/lnttool/import_data.py Mon Dec 12 13:31:28 2011 @@ -2,7 +2,7 @@ import lnt.db.perfdb from lnt import formats -from lnt.viewer import Config +import lnt.server.config from lnt.util import ImportData def action_import(name, args): @@ -45,7 +45,7 @@ # Load the config file. config_data = {} exec open(config) in config_data - config = Config.Config.fromData(config, config_data) + config = lnt.server.config.Config.fromData(config, config_data) # Get the database entry to use. db_entry = config.databases.get(opts.database) Copied: zorg/trunk/lnt/lnt/server/config.py (from r146402, zorg/trunk/lnt/lnt/viewer/Config.py) URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/config.py?p2=zorg/trunk/lnt/lnt/server/config.py&p1=zorg/trunk/lnt/lnt/viewer/Config.py&r1=146402&r2=146403&rev=146403&view=diff ============================================================================== (empty) Modified: zorg/trunk/lnt/lnt/server/ui/app.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/app.py?rev=146403&r1=146402&r2=146403&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/server/ui/app.py (original) +++ zorg/trunk/lnt/lnt/server/ui/app.py Mon Dec 12 13:31:28 2011 @@ -9,11 +9,10 @@ from flask import url_for import lnt +import lnt.server.config import lnt.server.ui.filters import lnt.server.ui.views -# FIXME: Redesign this. -import lnt.viewer.Config from lnt.db import perfdbsummary from lnt.db import perfdb @@ -101,7 +100,7 @@ config_data = {} exec open(config_path) in config_data - self.old_config = lnt.viewer.Config.Config.fromData( + self.old_config = lnt.server.config.Config.fromData( config_path, config_data) self.jinja_env.globals.update( Removed: zorg/trunk/lnt/lnt/viewer/Config.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/Config.py?rev=146402&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/Config.py (original) +++ zorg/trunk/lnt/lnt/viewer/Config.py (removed) @@ -1,94 +0,0 @@ -""" -LNT Config object for tracking user-configurable installation parameters. -""" - -import os -import re - -class EmailConfig: - @staticmethod - def fromData(data): - # The email to field can either be a string, or a list of tuples of - # the form [(accept-regexp-pattern, to-address)]. - to_address = data.get('to') - if not isinstance(to_address, str): - to_address = [(str(a),str(b)) for a,b in to_address] - return EmailConfig(bool(data.get('enabled')), str(data.get('host')), - str(data.get('from')), to_address) - - def __init__(self, enabled, host, from_address, to_address): - self.enabled = enabled - self.host = host - self.from_address = from_address - self.to_address = to_address - - def get_to_address(self, machine_name): - # The email to_address field can either be a string, or a list of tuples - # of the form [(accept-regexp-pattern, to-address)]. - if isinstance(self.to_address, str): - return self.to_address - - for pattern,addr in self.to_address: - if re.match(pattern, machine_name): - return addr - -class DBInfo: - @staticmethod - def fromData(baseDir, dict, default_email_config): - dbPath = dict.get('path') - if '://' not in dbPath: - dbPath = os.path.join(baseDir, dbPath) - - # Support per-database email configurations. - email_config = default_email_config - if 'emailer' in dict: - email_config = EmailConfig.fromData(dict['emailer']) - - return DBInfo(dbPath, - bool(dict.get('showNightlytest')), - bool(dict.get('showGeneral')), - bool(dict.get('showSimple')), - email_config) - - def __init__(self, path, showNightlytest, showGeneral, showSimple, - email_config): - self.path = path - self.showGeneral = showGeneral - self.showNightlytest = showNightlytest - self.showSimple = showSimple - self.email_config = email_config - -class Config: - @staticmethod - def fromData(path, data): - # Paths are resolved relative to the absolute real path of the - # config file. - baseDir = os.path.dirname(os.path.abspath(path)) - - # Get the default email config. - emailer = data.get('nt_emailer') - if emailer: - default_email_config = EmailConfig.fromData(emailer) - else: - default_email_config = EmailConfig(False, '', '', []) - - dbDir = data.get('db_dir', '.') - dbDirPath = os.path.join(baseDir, dbDir) - - # FIXME: Remove this default. - tempDir = data.get('tmp_dir', 'viewer/resources/graphs') - - return Config(data.get('name', 'LNT'), data['zorgURL'], - dbDir, os.path.join(baseDir, tempDir), - dict([(k,DBInfo.fromData(dbDirPath, v, - default_email_config)) - for k,v in data['databases'].items()])) - - def __init__(self, name, zorgURL, dbDir, tempDir, databases): - self.name = name - self.zorgURL = zorgURL - self.dbDir = dbDir - self.tempDir = tempDir - while self.zorgURL.endswith('/'): - self.zorgURL = zorgURL[:-1] - self.databases = databases From daniel at zuster.org Mon Dec 12 13:31:32 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 12 Dec 2011 19:31:32 -0000 Subject: [llvm-commits] [zorg] r146404 - in /zorg/trunk/lnt/lnt: util/wsgi_restart.py viewer/wsgi_restart.py Message-ID: <20111212193132.252D11BE003@llvm.org> Author: ddunbar Date: Mon Dec 12 13:31:31 2011 New Revision: 146404 URL: http://llvm.org/viewvc/llvm-project?rev=146404&view=rev Log: lnt: Move wsgi_restart into util. Added: zorg/trunk/lnt/lnt/util/wsgi_restart.py - copied, changed from r146403, zorg/trunk/lnt/lnt/viewer/wsgi_restart.py Removed: zorg/trunk/lnt/lnt/viewer/wsgi_restart.py Copied: zorg/trunk/lnt/lnt/util/wsgi_restart.py (from r146403, zorg/trunk/lnt/lnt/viewer/wsgi_restart.py) URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/util/wsgi_restart.py?p2=zorg/trunk/lnt/lnt/util/wsgi_restart.py&p1=zorg/trunk/lnt/lnt/viewer/wsgi_restart.py&r1=146403&r2=146404&rev=146404&view=diff ============================================================================== (empty) Removed: zorg/trunk/lnt/lnt/viewer/wsgi_restart.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/wsgi_restart.py?rev=146403&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/wsgi_restart.py (original) +++ zorg/trunk/lnt/lnt/viewer/wsgi_restart.py (removed) @@ -1,115 +0,0 @@ -# This code lifted from the mod_wsgi docs. - -import os -import sys -import time -import signal -import threading -import atexit -import Queue - -_interval = 1.0 -_times = {} -_files = [] - -_running = False -_queue = Queue.Queue() -_lock = threading.Lock() - -def _restart(path): - _queue.put(True) - prefix = 'monitor (pid=%d):' % os.getpid() - print >> sys.stderr, '%s Change detected to \'%s\'.' % (prefix, path) - print >> sys.stderr, '%s Triggering process restart.' % prefix - os.kill(os.getpid(), signal.SIGINT) - -def _modified(path): - try: - # If path doesn't denote a file and were previously - # tracking it, then it has been removed or the file type - # has changed so force a restart. If not previously - # tracking the file then we can ignore it as probably - # pseudo reference such as when file extracted from a - # collection of modules contained in a zip file. - - if not os.path.isfile(path): - return path in _times - - # Check for when file last modified. - - mtime = os.stat(path).st_mtime - if path not in _times: - _times[path] = mtime - - # Force restart when modification time has changed, even - # if time now older, as that could indicate older file - # has been restored. - - if mtime != _times[path]: - return True - except: - # If any exception occured, likely that file has been - # been removed just before stat(), so force a restart. - - return True - - return False - -def _monitor(): - while 1: - # Check modification times on all files in sys.modules. - - for module in sys.modules.values(): - if not hasattr(module, '__file__'): - continue - path = getattr(module, '__file__') - if not path: - continue - if os.path.splitext(path)[1] in ['.pyc', '.pyo', '.pyd']: - path = path[:-1] - - if _modified(path): - return _restart(path) - - # Check modification times on files which have - # specifically been registered for monitoring. - - for path in _files: - if _modified(path): - return _restart(path) - - # Go to sleep for specified interval. - - try: - return _queue.get(timeout=_interval) - except: - pass - -_thread = threading.Thread(target=_monitor) -_thread.setDaemon(True) - -def _exiting(): - try: - _queue.put(True) - except: - pass - _thread.join() - -atexit.register(_exiting) - -def track(path): - if not path in _files: - _files.append(path) - -def start(interval=1.0): - global _interval - if interval < _interval: - _interval = interval - - global _running - _lock.acquire() - if not _running: - prefix = 'monitor (pid=%d):' % os.getpid() - print >> sys.stderr, '%s Starting change monitor.' % prefix - _running = True - _thread.start() From daniel at zuster.org Mon Dec 12 13:31:40 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 12 Dec 2011 19:31:40 -0000 Subject: [llvm-commits] [zorg] r146405 - in /zorg/trunk/lnt/lnt: db/ server/ui/ server/ui/static/ util/ viewer/ viewer/js/ viewer/resources/ Message-ID: <20111212193141.2F4F71BE003@llvm.org> Author: ddunbar Date: Mon Dec 12 13:31:40 2011 New Revision: 146405 URL: http://llvm.org/viewvc/llvm-project?rev=146405&view=rev Log: lnt.viewer: Continue removing Quixote based UI. - Move viewer.{GraphUtil,Util} into server.ui. Added: zorg/trunk/lnt/lnt/server/ui/graphutil.py - copied, changed from r146404, zorg/trunk/lnt/lnt/viewer/GraphUtil.py zorg/trunk/lnt/lnt/server/ui/static/View2DTest.html - copied, changed from r146404, zorg/trunk/lnt/lnt/viewer/js/View2DTest.html zorg/trunk/lnt/lnt/server/ui/util.py - copied, changed from r146404, zorg/trunk/lnt/lnt/viewer/Util.py zorg/trunk/lnt/lnt/util/NTUtil.py - copied, changed from r146404, zorg/trunk/lnt/lnt/viewer/NTUtil.py Removed: zorg/trunk/lnt/lnt/viewer/GraphUtil.py zorg/trunk/lnt/lnt/viewer/NTStyleBrowser.ptl zorg/trunk/lnt/lnt/viewer/NTUtil.py zorg/trunk/lnt/lnt/viewer/Util.py zorg/trunk/lnt/lnt/viewer/__init__.py zorg/trunk/lnt/lnt/viewer/js/View2D.js zorg/trunk/lnt/lnt/viewer/js/View2DTest.html zorg/trunk/lnt/lnt/viewer/machines.ptl zorg/trunk/lnt/lnt/viewer/nightlytest.ptl zorg/trunk/lnt/lnt/viewer/resources/form.css zorg/trunk/lnt/lnt/viewer/resources/popup.js zorg/trunk/lnt/lnt/viewer/resources/sorttable.js zorg/trunk/lnt/lnt/viewer/resources/style.css zorg/trunk/lnt/lnt/viewer/runs.ptl zorg/trunk/lnt/lnt/viewer/tests.ptl Modified: zorg/trunk/lnt/lnt/db/runinfo.py zorg/trunk/lnt/lnt/server/ui/filters.py zorg/trunk/lnt/lnt/server/ui/views.py zorg/trunk/lnt/lnt/util/NTEmailReport.py Modified: zorg/trunk/lnt/lnt/db/runinfo.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/db/runinfo.py?rev=146405&r1=146404&r2=146405&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/db/runinfo.py (original) +++ zorg/trunk/lnt/lnt/db/runinfo.py Mon Dec 12 13:31:40 2011 @@ -1,5 +1,5 @@ from lnt.util import stats -from lnt.viewer import Util +from lnt.server.ui import util from lnt.db.perfdb import Sample from lnt.testing import PASS, FAIL, XFAIL @@ -90,7 +90,7 @@ self.db = db self.test_suite_summary = test_suite_summary - self.sample_map = Util.multidict() + self.sample_map = util.multidict() self.loaded_samples = set() def get_test_status_in_run(self, run_id, status_kind, test_name, pset): Modified: zorg/trunk/lnt/lnt/server/ui/filters.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/filters.py?rev=146405&r1=146404&r2=146405&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/server/ui/filters.py (original) +++ zorg/trunk/lnt/lnt/server/ui/filters.py Mon Dec 12 13:31:40 2011 @@ -1,5 +1,5 @@ import datetime -from lnt.viewer.Util import PctCell +from lnt.server.ui import util def filter_asusertime(time): # FIXME: Support alternate timezones? @@ -7,7 +7,7 @@ return ts.strftime('%Y-%m-%d %H:%M:%S %Z PST') def filter_aspctcell(value, *args, **kwargs): - cell = PctCell(value, *args, **kwargs) + cell = util.PctCell(value, *args, **kwargs) return cell.render() def register(app): Copied: zorg/trunk/lnt/lnt/server/ui/graphutil.py (from r146404, zorg/trunk/lnt/lnt/viewer/GraphUtil.py) URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/graphutil.py?p2=zorg/trunk/lnt/lnt/server/ui/graphutil.py&p1=zorg/trunk/lnt/lnt/viewer/GraphUtil.py&r1=146404&r2=146405&rev=146405&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/viewer/GraphUtil.py (original) +++ zorg/trunk/lnt/lnt/server/ui/graphutil.py Mon Dec 12 13:31:40 2011 @@ -2,8 +2,7 @@ Helper functions for graphing test results. """ -import Util - +from lnt.server.ui import util from lnt.util import stats from lnt.external.stats import stats as ext_stats @@ -27,7 +26,7 @@ for run_id,test_id,value in samples: d = samples_by_test_id.get(test_id) if d is None: - d = samples_by_test_id[test_id] = Util.multidict() + d = samples_by_test_id[test_id] = util.multidict() run_key = run_summary.get_run_order(run_id) if run_key is None: continue @@ -76,7 +75,7 @@ plot_js = "" # Determine the base plot color. - col = list(Util.makeDarkColor(float(index) / num_plots)) + col = list(util.makeDarkColor(float(index) / num_plots)) # Add regression line, if requested. if show_linear_regression: Copied: zorg/trunk/lnt/lnt/server/ui/static/View2DTest.html (from r146404, zorg/trunk/lnt/lnt/viewer/js/View2DTest.html) URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/static/View2DTest.html?p2=zorg/trunk/lnt/lnt/server/ui/static/View2DTest.html&p1=zorg/trunk/lnt/lnt/viewer/js/View2DTest.html&r1=146404&r2=146405&rev=146405&view=diff ============================================================================== (empty) Copied: zorg/trunk/lnt/lnt/server/ui/util.py (from r146404, zorg/trunk/lnt/lnt/viewer/Util.py) URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/util.py?p2=zorg/trunk/lnt/lnt/server/ui/util.py&p1=zorg/trunk/lnt/lnt/viewer/Util.py&r1=146404&r2=146405&rev=146405&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/viewer/Util.py (original) +++ zorg/trunk/lnt/lnt/server/ui/util.py Mon Dec 12 13:31:40 2011 @@ -198,19 +198,10 @@ return '%.*f%%' % (self.precision, self.value*100) def render(self): - import quixote.html r,g,b = [clamp(int(v*255), 0, 255) for v in self.getColor()] res = '%s' % (r,g,b, self.getValue()) - return quixote.html.htmltext(res) - - -def addOtherFormValues(form): - import quixote - request = quixote.get_request() - for name,value in request.form.items(): - if form.get_widget(name) is None: - form.add(quixote.form.HiddenWidget, name, value=value) + return res def sorted(l, *args, **kwargs): l = list(l) Modified: zorg/trunk/lnt/lnt/server/ui/views.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/views.py?rev=146405&r1=146404&r2=146405&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/server/ui/views.py (original) +++ zorg/trunk/lnt/lnt/server/ui/views.py Mon Dec 12 13:31:40 2011 @@ -189,8 +189,8 @@ run_summary = perfdbsummary.SimpleSuiteRunSummary.get_summary(db, tag) # Compute the list of associated runs, grouped by order. - from lnt.viewer import Util - grouped_runs = Util.multidict( + from lnt.server.ui import util + grouped_runs = util.multidict( (run_summary.get_run_order(run_id), run_id) for run_id in run_summary.get_runs_on_machine(id)) @@ -341,8 +341,8 @@ @db_route("/simple///graph") def simple_graph(tag, id): - from lnt.viewer import GraphUtil - from lnt.viewer import Util + from lnt.server.ui import graphutil + from lnt.server.ui import util db, run, run_summary, compare_to = get_simple_run_info(tag, id) @@ -391,7 +391,7 @@ num_points = 0 plot_points = [] plots = "" - plots_iter = GraphUtil.get_test_plots( + plots_iter = graphutil.get_test_plots( db, run.machine, test_ids, run_summary, ts_summary, show_mad_error = show_mad, show_stddev = show_stddev, show_linear_regression = show_linear_regression, show_points = True) @@ -411,8 +411,8 @@ plot_deltas = [] for (name,col),points in zip(legend,plot_points): points.sort() - deltas = [(Util.safediv(p1[1], p0[1]), p0, p1) - for p0,p1 in Util.pairs(points)] + deltas = [(util.safediv(p1[1], p0[1]), p0, p1) + for p0,p1 in util.pairs(points)] deltas.sort() deltas.reverse() plot_deltas.append(deltas[:20]) @@ -448,7 +448,7 @@ @db_route("/simple//order_aggregate_report") def simple_order_aggregate_report(tag): - from lnt.viewer import Util + from lnt.server.ui import util db = request.get_db() @@ -465,7 +465,7 @@ # Collect the runs, aggregated by order and machine. runs_to_summarize = [] - runs_by_machine_and_order = Util.multidict() + runs_by_machine_and_order = util.multidict() available_machine_ids = set() for order in orders_to_aggregate: for id in run_summary.runs_by_order["%7s" % order]: @@ -486,7 +486,7 @@ r.id for r in runs_to_summarize)) # Create test subsets, by name. - test_subsets = Util.multidict() + test_subsets = util.multidict() for test_name in test_names: if '.' in test_name: subset = test_name.rsplit('.', 1)[1] @@ -510,7 +510,7 @@ all_samples = list(all_samples) # Aggregate samples for easy lookup. - aggregate_samples = Util.multidict() + aggregate_samples = util.multidict() for run_id, test_id, value in all_samples: aggregate_samples[(run_id, test_id)] = value Modified: zorg/trunk/lnt/lnt/util/NTEmailReport.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/util/NTEmailReport.py?rev=146405&r1=146404&r2=146405&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/util/NTEmailReport.py (original) +++ zorg/trunk/lnt/lnt/util/NTEmailReport.py Mon Dec 12 13:31:40 2011 @@ -12,13 +12,12 @@ import urllib import StringIO -from lnt import viewer from lnt.db import runinfo from lnt.db import perfdbsummary -from lnt.viewer import GraphUtil -from lnt.viewer import Util +from lnt.server.ui import graphutil +from lnt.server.ui import util from lnt.db import perfdb -from lnt.viewer.NTUtil import * +from lnt.util.NTUtil import * from lnt.db.perfdb import Run, Sample @@ -140,14 +139,14 @@ test_names = ts_summary.get_test_names_in_runs(db, interesting_runs) # Gather the changes to report, mapped by parameter set. - new_failures = Util.multidict() - new_passes = Util.multidict() - perf_regressions = Util.multidict() - perf_improvements = Util.multidict() - added_tests = Util.multidict() - removed_tests = Util.multidict() - existing_failures = Util.multidict() - unchanged_tests = Util.multidict() + new_failures = util.multidict() + new_passes = util.multidict() + perf_regressions = util.multidict() + perf_improvements = util.multidict() + added_tests = util.multidict() + removed_tests = util.multidict() + existing_failures = util.multidict() + unchanged_tests = util.multidict() num_total_tests = len(test_names) * len(ts_summary.parameter_sets) for name in test_names: for pset in ts_summary.parameter_sets: @@ -328,11 +327,11 @@ if '.' in name: return name.rsplit('.', 1)[1] return '' - grouped = Util.multidict( + grouped = util.multidict( (get_last_component(t), t) for t in tests) - for group,grouped_tests in Util.sorted(grouped.items()): + for group,grouped_tests in util.sorted(grouped.items()): group_name = { "" : "(ungrouped)", "exec" : "Execution", @@ -384,7 +383,7 @@ os.path.join(report_url, "graph"), form_data, name) - pct_value = Util.PctCell(cr.pct_delta).render() + pct_value = util.PctCell(cr.pct_delta).render() if cr.stddev is not None: print >>html_report, """ %s%s%s%.4f%.4f%.4f""" %( @@ -408,7 +407,7 @@ test_ids = [ts_summary.test_id_map[(name,pset)] for _,name,pset in graphs] - plots_iter = GraphUtil.get_test_plots(db, machine, test_ids, + plots_iter = graphutil.get_test_plots(db, machine, test_ids, run_summary, ts_summary, show_mad_error = True, show_points = True) @@ -433,16 +432,16 @@ if not only_html_body: # We embed the additional resources, so that the message is self # contained. - viewer_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), - "viewer") - style_css = open(os.path.join(viewer_path, "resources", + static_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), + "server", "ui", "static") + style_css = open(os.path.join(static_path, "style.css")).read() header = """ """ % style_css if graphs: - view2d_js = open(os.path.join(viewer_path, "js", + view2d_js = open(os.path.join(static_path, "View2D.js")).read() header += """ - - - - -
- - - - - -
- Shift-Left Mouse: Pan
- Alt/Meta-Left Mouse: Zoom
- Wheel: Zoom (Shift Slows)
- - Removed: zorg/trunk/lnt/lnt/viewer/machines.ptl URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/machines.ptl?rev=146404&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/machines.ptl (original) +++ zorg/trunk/lnt/lnt/viewer/machines.ptl (removed) @@ -1,90 +0,0 @@ -# -*- python -*- - -""" -Generic machine browsing UI. -""" - -import sys -from quixote import get_response, redirect -from quixote.directory import Directory -from quixote.errors import TraversalError - -class MachineUI(Directory): - _q_exports = [""] - - def __init__(self, root, idstr): - self.root = root - try: - self.id = int(idstr) - except ValueError, exc: - raise TraversalError(str(exc)) - - - def _q_index [html] (self): - # Get a DB connection. - db = self.root.getDB() - - m = db.getMachine(self.id) - - self.root.getHeader("Machine: %s:%d" % (m.name,m.number), '../..', - components=(('browse','browse'),)) - - # Show the machine info dictionary. - """ - - - - - - - """ - for mi in m.info.values(): - """ - - - - """ % (mi.key, mi.value) - """ -
KeyValue
%s%s
- """ - - # List associated runs. - """ -

Associated Runs

- - - - - - - - - """ - for r in db.runs(machine=m): - """ - - - - - - """ % (r.id, r.id, r.start_time, r.end_time) - """ -
Run IDStart TimeEnd Time
%d%s%s
- """ - - self.root.getFooter() - -class MachinesDirectory(Directory): - _q_exports = [""] - - def __init__(self, root): - Directory.__init__(self) - self.root = root - - def _q_index [plain] (self): - """ - machine access - """ - - def _q_lookup(self, component): - return MachineUI(self.root, component) Removed: zorg/trunk/lnt/lnt/viewer/nightlytest.ptl URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/nightlytest.ptl?rev=146404&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/nightlytest.ptl (original) +++ zorg/trunk/lnt/lnt/viewer/nightlytest.ptl (removed) @@ -1,650 +0,0 @@ -# -*- python -*- - -""" -Nightly Test UI instance for actual nightly test data. -""" - -# FIXME: The NTStyleBrowser abstraction is no longer useful. We should kill it. - -import sys -import time - -import quixote -from quixote.directory import Directory -from quixote.errors import TraversalError - -import Util, NTStyleBrowser -from Util import safediv -from NTUtil import * - -from lnt.db.perfdb import Machine, Run - -class NightlyTestRunUI(NTStyleBrowser.TestRunUI): - _q_exports = ["", "graphSingle"] - - def __init__(self, *args, **kwargs): - NTStyleBrowser.TestRunUI.__init__(self, *args, **kwargs) - self.popupDepth = 0 - - def getParameters(self): - return () - - def renderFullContents [html] (self, db, run, compareTo, summary): - """

""" - self.getAllResults(db, run, compareTo, summary) - - def renderBriefContents [html] (self, db, run, compareTo, summary): - if compareTo: - self.getComparisonPopups(db, run, compareTo, summary) - - def renderCommonContents [html] (self, db, run, compareTo, summary): - # Test suite failure information. - - failures = self.getFailuresForRun(db, run, summary) - - if compareTo is not None: - prevFailures = self.getFailuresForRun(db, compareTo, summary) - newFailures = [(name, list(set(items) - - set(prevFailures.get(name,[])))) - for name,items in failures.items()] - newFailures = dict([(name, items) - for name,items in newFailures - if items]) - - if newFailures: - newFailures = sorted(newFailures.items()) - self.renderTestSuiteFailures('newTSFailures', - 'New Test Suite Failures', - newFailures) - - failures = sorted(failures.items()) - self.renderTestSuiteFailures('tsFailures', - 'Test Suite Failures', failures) - - def renderTestSuiteFailures [html] (self, id, title, failures): - numFailures = sum([len(items) for _,items in failures]) - title = '%d %s (All)' % (numFailures, title) - - self.renderPopupBegin(id, title, True) - self.renderPopupBegin(id+'.all', 'All', True) - for name,items in failures: - """ - %s [%s]
- """ % (name, ', '.join(items)) - self.renderPopupEnd() - - # Also show failure by type. - byType = Util.multidict([(item,name) - for name,items in failures - for item in items]) - byType = sorted(byType.items()) - - for i,(item,names) in enumerate(byType): - title = '%d %s' % (len(names), item) - self.renderPopupBegin(id+'.%d' % i, title, True) - for name in names: - """ - %s
""" % name - self.renderPopupEnd() - - self.renderPopupEnd() - - def renderPopupBegin [html] (self, id, title, hidden): - self.popupDepth += 1 - """\ -

- (%s) %s -

- """ % (id, id, ("+","-")[hidden], title, id, ("","none")[hidden], - self.popupDepth) - def renderPopupEnd [html] (self): - """ -
""" - self.popupDepth -= 1 - - def getFailuresForRun(self, db, run, summary): - failures = Util.multidict() - for keyname,title in kTSKeys.items(): - for testname in summary.testNames: - fullname = 'nightlytest.' + testname + '.' + keyname +'.success' - t = summary.testMap.get(str(fullname)) - if t is None: - continue - samples = summary.getRunSamples(run).get(t.id) - if not samples or samples[0]: - continue - failures[testname] = title - return failures - - def getAllResults [html] (self, db, run, compareTo, summary): - columns = [('GCCAS', 'gcc.compile.time', None, ()), - ('Bitcode','bc.compile.size', None, ()), - ('LLC
compile','llc.compile.time', None, - ('bc.compile.size',)), - ('LLC-BETA
compile','llc-beta.compile.time', None, - ('bc.compile.size',)), - ('JIT
codegen','jit.compile.time', None, - ('bc.compile.size',)), - ('GCC','gcc.exec.time', None, ('gcc.compile.time',)), - ('CBE','cbe.exec.time', None, ('bc.compile.size',)), - ('LLC','llc.exec.time', None, ('llc.compile.time',)), - ('LLC-BETA','llc-beta.exec.time', None, - ('llc-beta.compile.time',)), - ('JIT','jit.exec.time', None, ('jit.compile.time',)), - ('GCC/CBE','gcc.exec.time','cbe.exec.time', ()), - ('GCC/LLC','gcc.exec.time','llc.exec.time', ()), - ('GCC/LLC-BETA','gcc.exec.time','llc-beta.exec.time',()), - ('LLC/LLC-BETA','llc.exec.time','llc-beta.exec.time',())] - - # Add interface to hiding columns by test or column type. - keyIndices = Util.multidict() - ratioIndices = [] - pctIndices = [] - - idx = 1 - for info in columns: - isCmp = info[2] is not None - key = str(info[1]).split(str('.'))[0] - if not isCmp: - keyIndices[key] = idx - keyIndices[key] = idx + 1 - pctIndices.append(idx + 1) - idx += 2 - else: - keyIndices[key] = idx - ratioIndices.append(idx) - idx += 1 - """ -
- - - - - - - - - - - - - - - - - - - - - - - -
Column VisibilityGCCLLCCBEJITLLC-BETAPercentagesRatios
Enabled
-
- """ % (', '.join(map(str, keyIndices['gcc'])), - ', '.join(map(str, keyIndices['llc'])), - ', '.join(map(str, keyIndices['cbe'])), - ', '.join(map(str, keyIndices['jit'])), - ', '.join(map(str, keyIndices['llc-beta'])), - ', '.join(map(str, pctIndices)), - ', '.join(map(str, ratioIndices))) - - # The main table. - """ - - - - - """ - for name,key,cmp,dependsOn in columns: - if cmp is None: - """ - - - """ % (name, name) - else: - """""" % name - """ - - - """ - - runSamples = summary.getRunSamples(run) - prevSamples = summary.getRunSamples(compareTo) - testNames = list(summary.testNames) - testNames.sort(key = lambda x: x.lower()) - for testName in testNames: - # FIXME: We need some id for the "program". The dotted name system - # solves this... - fullname = str('nightlytest.' + testName + '.' + - 'gcc.compile.success') - t = summary.testMap.get(fullname) - assert t - """ - - - """ % (t.id, testName,) - - for name,key,cmp,dependsOn in columns: - if cmp is None: - fullname = str('nightlytest.' + testName + '.' + key) - t = summary.testMap.get(fullname) - if t is None: - current = prev = None - else: - current = runSamples.get(t.id) - prev = prevSamples.get(t.id) - if current: - value = current[0] - if key.endswith('size'): - """""" % int(value) - else: - """""" % value - if prev: - pct = safediv(value, prev[0], - '
nan
') - else: - pct = 'N/A' - else: - # Only mark failure if nothing we depend on failed. - failed = True - for d in dependsOn: - t = summary.testMap.get(str('nightlytest.' + testName + '.' + d)) - if not t or not runSamples.get(t.id): - failed = False - break - if failed: - """""" - else: - """""" - pct = 'N/A' - Util.PctCell(pct, delta=True).render() - else: - tNum = summary.testMap.get(str('nightlytest.' + testName + '.' + key)) - tDen = summary.testMap.get(str('nightlytest.' + testName + '.' + cmp)) - if tNum is None or tDen is None: - num = den = None - else: - num = runSamples.get(tNum.id) - den = runSamples.get(tDen.id) - if num and den: - pct = safediv(num[0], den[0]) - if pct is None: - """""" - else: - """""" % (pct,) - else: - """""" - """ - - """ - """ -
Program%s%%
change
in
%s
%s
%s%d%.4f*N/AN/A%.2fN/A
- """ - - def getComparisonPopups [html] (self, db, run, compareTo, summary): - runSamples = summary.getRunSamples(run) - prevSamples = summary.getRunSamples(compareTo) - - for i,(name,key) in enumerate(kComparisonKinds): - if not key: - # FIXME: File Size - deltas = [] - else: - deltas = [] - for testName in summary.testNames: - fullname = str('nightlytest.' + testName + '.' + key) - t = summary.testMap.get(fullname) - if not t: - continue - current = runSamples.get(t.id) - prev = prevSamples.get(t.id) - if not current or not prev: - continue - current = current[0] - prev = prev[0] - pct = safediv(current, prev) - if pct is None: - continue - pctDelta = pct - 1. - if abs(pctDelta) < .05: - continue - if min(prev,current) <= .2: - continue - deltas.append( (t.id, testName, current, prev, pctDelta) ) - - hidden = len(deltas) == 0 - """ -

- (%s) %d %s Significant Changes -

- """ % (name, name, ("+","-")[hidden], len(deltas), name, name, ("","none")[hidden]) - if deltas: - # Redirect or something so we don't have to specify - # run here; that is silly. - """ -
- - - - - - - - - - - - - - """ % (run.id, i, i,) - for id, name, current, prev, pctDelta in deltas: - """ - - - - %s - - - - """ % (id, i, id, name, - Util.PctCell(pctDelta).render(), prev, current) - """ -
Program%% ChangePrevious ValueCurrent Value
%s%s%s
- -
- """ - - """ -
- """ - - def graphSingle [html] (self): - request = quixote.get_request() - full = request.form.get('full', '') - allResults = not not full - - # Get a DB connection. - db = self.root.getDB() - - run = self.getActiveRun(db) - runs = db.runs(run.machine).order_by(Run.start_time.desc()).all() - machine = run.machine - - request = quixote.get_request() - kindStr = request.form.get('kind') - kind = None - try: - kind = kComparisonKinds[int(kindStr)] - except: - pass - tests = [] - for name,value in request.form.items(): - if name.startswith(str('cb.')): - testIDStr = name[3:] - try: - testID = int(str(testIDStr)) - tests.append(db.getTest(testID)) - except: - pass - - # Collect samples by test and machine, then bin into runs. - samplesByTest = {} - for t in tests: - samples = samplesByTest[t.id] = samplesByTest.get(t.id,{}) - - q = db.session.query(Sample.run_id, - Sample.value).join(Run) - q = q.filter(Run.machine_id == machine.id) - q = q.filter(Sample.test_id == t.id) - for s_run_id,s_value in q: - samples[s_run_id] = s_value - - legend = [] - plots = "" - for i,test in enumerate(tests): - data = [] - for run in runs: - value = samplesByTest.get(test.id,{}).get(run.id) - if value is not None: - timeval = time.mktime(run.start_time.timetuple()) - data.append((timeval, value)) - data.sort() - - col = list(Util.makeDarkColor(float(i) / len(tests))) - pts = ','.join(['[%f,%f]' % (t,v) for t,v in data]) - style = "new Graph2D_LinePlotStyle(1, %r)" % col - plots += " graph.addPlot([%s], %s);\n" % (pts,style) - - legend.append((test.name.split(str('.'),1)[1], col)) - graph_init = """\ - function init() { - graph = new Graph2D("graph"); - graph.clearColor = [1, 1, 1]; - %s - graph.xAxis.format = graph.xAxis.formats.day; - graph.draw(); - } - """ % (plots,) - - self.root.getHeader("Results Graph", "../..", - components=(('nightlytest','nightlytest'), - ('machine', - 'nightlytest/machines/%d'%machine.id), - ('run', 'nightlytest/%d' % run.id)), - addPopupJS=True, addGraphJS=True, - addJSScript=graph_init, - onload='init()') - - # Graph2D based graph. - """ -

Graph

- - - - - -
- - - - - """ - for name,col in legend: - """""" % ( - 255*col[0], 255*col[1], 255*col[2], name) - """ -
Test
 %s
-
- - Shift-Left Mouse: Pan
- Alt/Meta-Left Mouse: Zoom
- Wheel: Zoom (Shift Slows)
-
-
- """ - - """

Values

- (-) Graph Values - - """ - - self.root.getFooter() - -class NightlyTestProgramUI(Directory): - _q_exports = [""] - - def __init__(self, root, testIDStr): - self.root = root - try: - self.testID = int(testIDStr) - except ValueError, exc: - raise TraversalError(str(exc)) - - def _q_index [html] (self): - # Get a DB connection. - db = self.root.getDB() - - # Get the test we use to derive the name. - t = db.getTest(id = self.testID) - programName = t.name.split(str('.'), 3)[1] - - self.root.getHeader("Program: %s" % programName, "../../..", - components=(('nightlytest','nightlytest'),), - addPopupJS=True) - - # Collect runs within the last 48 hours of the most recent report. - import datetime - runs = [] - most_recent, = db.session.query(Run.start_time).\ - order_by(Run.start_time.desc()).first() - cutoff = most_recent - datetime.timedelta(days=2) - runs = db.session.query(Run).\ - filter(Run.start_time >= cutoff).\ - order_by(Run.start_time.desc()).all() - - self.getAllResults(db, programName, runs) - - self.root.getFooter() - - def getAllResults [html] (self, db, testName, runs): - columns = [('GCCAS', 'gcc.compile.time', ()), - ('Bitcode','bc.compile.size', ()), - ('LLC
compile','llc.compile.time', ('bc.compile.size',)), - ('LLC-BETA
compile','llc-beta.compile.time', - ('bc.compile.size',)), - ('JIT
codegen','jit.compile.time', ('bc.compile.size',)), - ('GCC','gcc.exec.time', ('gcc.compile.time',)), - ('CBE','cbe.exec.time', ('bc.compile.size',)), - ('LLC','llc.exec.time', ('llc.compile.time',)), - ('LLC-BETA','llc-beta.exec.time', ('llc-beta.compile.time',)), - ('JIT','jit.exec.time', ('jit.compile.time',))] - - # Add interface to hiding columns by test or column type. - keyIndices = Util.multidict() - for idx,info in enumerate(columns): - key = str(info[1]).split(str('.'))[0] - keyIndices[key] = idx + 2 - """ -
- - - - - - - - - - - - - - - - - - - -
Column VisibilityGCCLLCCBEJITLLC-BETA
Enabled
-
- """ % (', '.join(map(str, keyIndices['gcc'])), - ', '.join(map(str, keyIndices['llc'])), - ', '.join(map(str, keyIndices['cbe'])), - ', '.join(map(str, keyIndices['jit'])), - ', '.join(map(str, keyIndices['llc-beta']))) - - # The main table. - """ - - - - - - """ - for name,key,dependsOn in columns: - """""" % (name, ) - """ - - - """ - - for run in runs: - """ - - - - """ % (run.machine.id, run.machine.name, run.machine.number, - run.id, run.start_time) - - for name,key,dependsOn in columns: - fullname = str('nightlytest.' + testName + '.' + key) - # FIXME: Make fast. - current = getTestNameValueInRun(db, run, fullname) - if current is not None: - if key.endswith('size'): - """""" % int(current) - else: - """""" % current - else: - # Only mark failure if nothing we depend on failed. - failed = True - for d in dependsOn: - # FIXME: Make fast. - t = getTestNameValueInRun(db, run, - str('nightlytest.' + testName - + '.' + d)) - if t is None: - failed = False - break - if failed: - """""" - else: - """""" - """ - - """ - """ -
MachineRun Start%s
%s:%d%s%d%.4f*N/A
- """ - -class NightlyTestDirectory(NTStyleBrowser.RecentMachineDirectory): - _q_exports = [""] - - def getTags(self): - return (None, 'nightlytest') - - def getTestRunUI(self, component): - return NightlyTestRunUI(self.root, component) - - def getProgramUI(self, component): - return NightlyTestProgramUI(self.root, component) Removed: zorg/trunk/lnt/lnt/viewer/resources/form.css URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/resources/form.css?rev=146404&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/resources/form.css (original) +++ zorg/trunk/lnt/lnt/viewer/resources/form.css (removed) @@ -1,75 +0,0 @@ -/* Derived from Quixote's BASIC_FORM_CSS */ - -form.quixote div.title { - font-weight: bold; -} - -form.quixote br.submit, -form.quixote br.widget, -br.quixoteform { - clear: left; -} - -form.quixote div.submit br.widget { - display: none; -} - -form.quixote div.widget { - float: left; - padding: 4px; - padding-right: 1em; - margin-bottom: 6px; -} - -/* pretty forms (attribute selector hides from broken browsers (e.g. IE) */ -form.quixote[action] { - float: left; -} - -form.quixote[action] > div.widget { - float: none; -} - -form.quixote[action] > br.widget { - display: none; -} - -form.quixote div.widget div.widget { - padding: 0; - margin-bottom: 0; -} - -form.quixote div.SubmitWidget { - float: left -} - -form.quixote div.content { - margin-left: 0.6em; /* indent content */ -} - -form.quixote div.content div.content { - margin-left: 0; /* indent content only for top-level widgets */ -} - -form.quixote div.error { - color: #c00; - font-size: small; - margin-top: .1em; -} - -form.quixote div.hint { - font-size: small; - font-style: italic; - margin-top: .1em; -} - -form.quixote div.errornotice { - color: #c00; - padding: 0.5em; - margin: 0.5em; -} - -form.quixote div.FormTokenWidget, -form.quixote.div.HiddenWidget { - display: none; -} Removed: zorg/trunk/lnt/lnt/viewer/resources/popup.js URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/resources/popup.js?rev=146404&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/resources/popup.js (original) +++ zorg/trunk/lnt/lnt/viewer/resources/popup.js (removed) @@ -1,155 +0,0 @@ -function ShowPop(id) -{ - if (document.getElementById) - { - document.getElementById(id).style.visibility = " visible"; - } - else if (document.all) - { - document.all[id].style.visibility = " visible"; - } - else if (document.layers) - { - document.layers[id].style.visibility = " visible"; - } -} - - - - - - -function HidePop(id) -{ - if (document.getElementById) - { - document.getElementById(id).style.visibility = " hidden"; - } - /*else if (document.all) - { - document.all[id].style.visibility = " hidden"; - } - else if (document.layers) - { - document.layers[id].style.visibility = " hidden"; - }*/ -} - - - -function TogglePop(id) -{ - if (document.getElementById) - { - if(document.getElementById(id).style.visibility == "visible"){ - document.getElementById(id).style.visibility = "hidden"; - } - else{ - document.getElementById(id).style.visibility = "visible"; - } - } - else if (document.all) - { - if(document.all[id].style.visibility == "visible"){ - document.all[id].style.visibility = "hidden"; - } - else{ - document.all[id].style.visibility = "visible"; - } - } - else if (document.layers) - { - if(document.layers[id].style.visibility == "visible"){ - document.layers[id].style.visibility = "hidden"; - } - else{ - document.layers[id].style.visibility = "visible"; - } - } -} - - -function toggleLayer(whichLayer) -{ - if (document.getElementById) - { - // this is the way the standards work - var style2 = document.getElementById(whichLayer).style; - style2.display = style2.display? "":"none"; - var link = document.getElementById(whichLayer+"_").innerHTML; - if(link.indexOf("(+)") >= 0){ - document.getElementById(whichLayer+"_").innerHTML="(-)"+link.substring(3,link.length); - } - else{ - document.getElementById(whichLayer+"_").innerHTML="(+)"+link.substring(3,link.length); - } - }//end if - else if (document.all) - { - // this is the way old msie versions work - var style2 = document.all[whichLayer].style; - style2.display = style2.display? "":"none"; - var link = document.all[wwhichLayer+"_"].innerHTML; - if(link.indexOf("(+)") >= 0){ - document.all[whichLayer+"_"].innerHTML="(-)"+link.substring(3,link.length); - } - else{ - document.all[whichLayer+"_"].innerHTML="(+)"+link.substring(3,link.length); - } - } - else if (document.layers) - { - // this is the way nn4 works - var style2 = document.layers[whichLayer].style; - style2.display = style2.display? "":"none"; - var link = document.layers[whichLayer+"_"].innerHTML; - if(link.indexOf("(+)") >= 0){ - document.layers[whichLayer+"_"].innerHTML="(-)"+link.substring(3,link.length); - } - else{ - document.layers[whichLayer+"_"].innerHTML="(+)"+link.substring(3,link.length); - } - } -}//end function - -var checkflag="false"; -function check(field) { - if (checkflag == "false") { - for (i = 0; i < field.length; i++) { - field[i].checked = true; - } - checkflag = "true"; - return "Uncheck all"; - } - else { - for (i = 0; i < field.length; i++) { - if(field[i].type == 'checkbox'){ - field[i].checked = false; - } - } - checkflag = "false"; - return "Check all"; - } -} - -function show_hide_column(tableName, columns) { - // Let's be clear hear, I have no idea how to write portable - // JavaScript. This works in Safari, yo. - var event = window.event; - var cb = event.target; - - var style = cb.checked ? "table-cell" : "none"; - - var tbl = document.getElementById(tableName); - var rows = tbl.getElementsByTagName('tr'); - - for (var row = 0; row < rows.length; ++row) { - var cells = rows[row].getElementsByTagName('td'); - - if (cells.length == 0) - cells = rows[row].getElementsByTagName('th'); - - for (var i = 0; i < columns.length; ++i) - cells[columns[i]].style.display = style; - } -} Removed: zorg/trunk/lnt/lnt/viewer/resources/sorttable.js URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/resources/sorttable.js?rev=146404&view=auto ============================================================================== --- zorg/trunk/lnt/lnt/viewer/resources/sorttable.js (original) +++ zorg/trunk/lnt/lnt/viewer/resources/sorttable.js (removed) @@ -1,500 +0,0 @@ -/* - SortTable - version 2 - 7th April 2007 - Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ - - Instructions: - Download this file - Add to your HTML - Add class="sortable" to any table you'd like to make sortable - Click on the headers to sort - - Thanks to many, many people for contributions and suggestions. - Licenced as X11: http://www.kryogenix.org/code/browser/licence.html - This basically means: do what you want with it. -*/ - - -var stIsIE = /*@cc_on!@*/false; - -sorttable = { - init: function() { - // quit if this function has already been called - if (arguments.callee.done) return; - // flag this function so we don't do the same thing twice - arguments.callee.done = true; - // kill the timer - if (_timer) clearInterval(_timer); - - if (!document.createElement || !document.getElementsByTagName) return; - - sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; - - forEach(document.getElementsByTagName('table'), function(table) { - if (table.className.search(/\bsortable\b/) != -1) { - sorttable.makeSortable(table); - } - }); - - }, - - makeSortable: function(table) { - if (table.getElementsByTagName('thead').length == 0) { - // table doesn't have a tHead. Since it should have, create one and - // put the first table row in it. - the = document.createElement('thead'); - the.appendChild(table.rows[0]); - table.insertBefore(the,table.firstChild); - } - // Safari doesn't support table.tHead, sigh - if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; - - //DWD: if (table.tHead.rows.length != 1) return; // can't cope with two header rows - - - // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as - // "total" rows, for example). This is B&R, since what you're supposed - // to do is put them in a tfoot. So, if there are sortbottom rows, - // for backwards compatibility, move them to tfoot (creating it if needed). - sortbottomrows = []; - for (var i=0; i5' : ' ▴'; - this.appendChild(sortrevind); - return; - } - if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { - // if we're already sorted by this column in reverse, just - // re-reverse the table, which is quicker - sorttable.reverse(this.sorttable_tbody); - this.className = this.className.replace('sorttable_sorted_reverse', - 'sorttable_sorted'); - this.removeChild(document.getElementById('sorttable_sortrevind')); - sortfwdind = document.createElement('span'); - sortfwdind.id = "sorttable_sortfwdind"; - sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; - this.appendChild(sortfwdind); - return; - } - - // remove sorttable_sorted classes - forEach(table.tHead.rows, function(row) { - forEach(row.childNodes, function(cell) { - if (cell.nodeType == 1) { // an element - cell.className = cell.className.replace('sorttable_sorted_reverse',''); - cell.className = cell.className.replace('sorttable_sorted',''); - } - })}); - sortfwdind = document.getElementById('sorttable_sortfwdind'); - if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } - sortrevind = document.getElementById('sorttable_sortrevind'); - if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } - - this.className += ' sorttable_sorted'; - sortfwdind = document.createElement('span'); - sortfwdind.id = "sorttable_sortfwdind"; - sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; - this.appendChild(sortfwdind); - - // build an array to sort. This is a Schwartzian transform thing, - // i.e., we "decorate" each row with the actual sort key, - // sort based on the sort keys, and then put the rows back in order - // which is a lot faster because you only do getInnerText once per row - row_array = []; - col = this.sorttable_columnindex; - rows = this.sorttable_tbody.rows; - for (var j=0; j 12) { - // definitely dd/mm - return sorttable.sort_ddmm; - } else if (second > 12) { - return sorttable.sort_mmdd; - } else { - // looks like a date, but we can't tell which, so assume - // that it's dd/mm (English imperialism!) and keep looking - sortfn = sorttable.sort_ddmm; - } - } - } - } - return sortfn; - }, - - getInnerText: function(node) { - // gets the text we want to use for sorting for a cell. - // strips leading and trailing whitespace. - // this is *not* a generic getInnerText function; it's special to sorttable. - // for example, you can override the cell text with a customkey attribute. - // it also gets .value for fields. - - hasInputs = (typeof node.getElementsByTagName == 'function') && - node.getElementsByTagName('input').length; - - if (node.getAttribute("sorttable_customkey") != null) { - return node.getAttribute("sorttable_customkey"); - } - else if (typeof node.textContent != 'undefined' && !hasInputs) { - return node.textContent.replace(/^\s+|\s+$/g, ''); - } - else if (typeof node.innerText != 'undefined' && !hasInputs) { - return node.innerText.replace(/^\s+|\s+$/g, ''); - } - else if (typeof node.text != 'undefined' && !hasInputs) { - return node.text.replace(/^\s+|\s+$/g, ''); - } - else { - switch (node.nodeType) { - case 3: - if (node.nodeName.toLowerCase() == 'input') { - return node.value.replace(/^\s+|\s+$/g, ''); - } - case 4: - return node.nodeValue.replace(/^\s+|\s+$/g, ''); - break; - case 1: - case 11: - var innerText = ''; - for (var i = 0; i < node.childNodes.length; i++) { - innerText += sorttable.getInnerText(node.childNodes[i]); - } - return innerText.replace(/^\s+|\s+$/g, ''); - break; - default: - return ''; - } - } - }, - - reverse: function(tbody) { - // reverse the rows in a tbody - newrows = []; - for (var i=0; i=0; i--) { - tbody.appendChild(newrows[i]); - } - delete newrows; - }, - - /* sort functions - each sort function takes two parameters, a and b - you are comparing a[0] and b[0] */ - sort_numeric: function(a,b) { - aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); - if (isNaN(aa)) aa = 0; - bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); - if (isNaN(bb)) bb = 0; - return aa-bb; - }, - sort_alpha: function(a,b) { - if (a[0]==b[0]) return 0; - if (a[0] 0 ) { - var q = list[i]; list[i] = list[i+1]; list[i+1] = q; - swap = true; - } - } // for - t--; - - if (!swap) break; - - for(var i = t; i > b; --i) { - if ( comp_func(list[i], list[i-1]) < 0 ) { - var q = list[i]; list[i] = list[i-1]; list[i-1] = q; - swap = true; - } - } // for - b++; - - } // while(swap) - } -} - -/* ****************************************************************** - Supporting functions: bundled here to avoid depending on a library - ****************************************************************** */ - -// Dean Edwards/Matthias Miller/John Resig - -/* for Mozilla/Opera9 */ -if (document.addEventListener) { - document.addEventListener("DOMContentLoaded", sorttable.init, false); -} - -/* for Internet Explorer */ -/*@cc_on @*/ -/*@if (@_win32) - document.write(" to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + //DWD: if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backwards compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + forEach(table.tHead.rows, function(row) { + forEach(row.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + })}); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + + + @@ -24,6 +31,34 @@ vector instructions as well as dedicated accelerators.

+

+ +
WARNING: Polly started as a research project and larger parts of it are still open research projects. Even though we aim for a robust, production quality implementation, not all parts of Polly are there yet. We invite From grosser at fim.uni-passau.de Tue Dec 13 09:09:10 2011 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Tue, 13 Dec 2011 15:09:10 -0000 Subject: [llvm-commits] [polly] r146487 - in /polly/trunk/www: images/video-summit-2011.png video-js/ video-js/video-js.css video-js/video.js Message-ID: <20111213150910.1C4761BE003@llvm.org> Author: grosser Date: Tue Dec 13 09:09:09 2011 New Revision: 146487 URL: http://llvm.org/viewvc/llvm-project?rev=146487&view=rev Log: www: Add forgotten files Added: polly/trunk/www/images/video-summit-2011.png polly/trunk/www/video-js/ polly/trunk/www/video-js/video-js.css polly/trunk/www/video-js/video.js Added: polly/trunk/www/images/video-summit-2011.png URL: http://llvm.org/viewvc/llvm-project/polly/trunk/www/images/video-summit-2011.png?rev=146487&view=auto ============================================================================== Binary files polly/trunk/www/images/video-summit-2011.png (added) and polly/trunk/www/images/video-summit-2011.png Tue Dec 13 09:09:09 2011 differ Added: polly/trunk/www/video-js/video-js.css URL: http://llvm.org/viewvc/llvm-project/polly/trunk/www/video-js/video-js.css?rev=146487&view=auto ============================================================================== --- polly/trunk/www/video-js/video-js.css (added) +++ polly/trunk/www/video-js/video-js.css Tue Dec 13 09:09:09 2011 @@ -0,0 +1,242 @@ +/* +VideoJS Default Styles (http://videojs.com) +Version 2.0.2 + +REQUIRED STYLES (be careful overriding) +================================================================================ */ +/* Box containing video, controls, and download links. + Will be set to the width of the video element through JS + If you want to add some kind of frame or special positioning, use another containing element, not video-js-box. */ +.video-js-box { text-align: left; position: relative; line-height: 0 !important; margin: 0; padding: 0 !important; border: none !important; } + +/* Video Element */ +video.video-js { background-color: #000; position: relative; padding: 0; } + +.vjs-flash-fallback { display: block; } + +/* Poster Overlay Style */ +.video-js-box img.vjs-poster { display: block; position: absolute; left: 0; top: 0; width: 100%; height: 100%; margin: 0; padding: 0; cursor: pointer; } +/* Subtiles Style */ +.video-js-box .vjs-subtitles { color: #fff; font-size: 20px; text-align: center; position: absolute; bottom: 40px; left: 0; right: 0; } + +/* Fullscreen styles for main elements */ +.video-js-box.vjs-fullscreen { position: fixed; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: 1000; } +.video-js-box.vjs-fullscreen video.video-js, +.video-js-box.vjs-fullscreen .vjs-flash-fallback { position: relative; top: 0; left: 0; width: 100%; height: 100%; z-index: 1000; } +.video-js-box.vjs-fullscreen img.vjs-poster { z-index: 1001; } +.video-js-box.vjs-fullscreen .vjs-spinner { z-index: 1001; } +.video-js-box.vjs-fullscreen .vjs-controls { z-index: 1003; } +.video-js-box.vjs-fullscreen .vjs-big-play-button { z-index: 1004; } +.video-js-box.vjs-fullscreen .vjs-subtitles { z-index: 1004; } + +/* Styles Loaded Check */ +.vjs-styles-check { height: 5px; position: absolute; } +/* Controls Below Video */ +.video-js-box.vjs-controls-below .vjs-controls { position: relative; opacity: 1; background-color: #000; } +.video-js-box.vjs-controls-below .vjs-subtitles { bottom: 75px; } /* Account for height of controls below video */ + +/* DEFAULT SKIN (override in another file) +================================================================================ +Using all CSS to draw the controls. Images could be used if desired. +Instead of editing this file, I recommend creating your own skin CSS file to be included after this file, +so you can upgrade to newer versions easier. */ + +/* Controls Layout + Using absolute positioning to position controls */ +.video-js-box .vjs-controls { + position: absolute; margin: 0; opacity: 0.85; color: #fff; + display: none; /* Start hidden */ + left: 0; right: 0; /* 100% width of video-js-box */ + width: 100%; + bottom: 0px; /* Distance from the bottom of the box/video. Keep 0. Use height to add more bottom margin. */ + height: 35px; /* Including any margin you want above or below control items */ + padding: 0; /* Controls are absolutely position, so no padding necessary */ +} + +.video-js-box .vjs-controls > div { /* Direct div children of control bar */ + position: absolute; /* Use top, bottom, left, and right to specifically position the control. */ + text-align: center; margin: 0; padding: 0; + height: 25px; /* Default height of individual controls */ + top: 5px; /* Top margin to put space between video and controls when controls are below */ + + /* CSS Background Gradients + Using to give the aqua-ish look. */ + /* Default */ background-color: #0B151A; + /* Webkit */ background: #1F3744 -webkit-gradient(linear, left top, left bottom, from(#0B151A), to(#1F3744)) left 12px; + /* Firefox */ background: #1F3744 -moz-linear-gradient(top, #0B151A, #1F3744) left 12px; + + /* CSS Curved Corners */ + border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; + + /* CSS Shadows */ + box-shadow: 1px 1px 2px #000; -webkit-box-shadow: 1px 1px 2px #000; -moz-box-shadow: 1px 1px 2px #000; +} + +/* Placement of Control Items + - Left side of pogress bar, use left & width + - Rigth side of progress bar, use right & width + - Expand with the video (like progress bar) use left & right */ +.vjs-controls > div.vjs-play-control { left: 5px; width: 25px; } +.vjs-controls > div.vjs-progress-control { left: 35px; right: 165px; } /* Using left & right so it expands with the width of the video */ +.vjs-controls > div.vjs-time-control { width: 75px; right: 90px; } /* Time control and progress bar are combined to look like one */ +.vjs-controls > div.vjs-volume-control { width: 50px; right: 35px; } +.vjs-controls > div.vjs-fullscreen-control { width: 25px; right: 5px; } + +/* Removing curved corners on progress control and time control to join them. */ +.vjs-controls > div.vjs-progress-control { + border-top-right-radius: 0; -webkit-border-top-right-radius: 0; -moz-border-radius-topright: 0; + border-bottom-right-radius: 0; -webkit-border-bottom-right-radius: 0; -moz-border-radius-bottomright: 0; +} +.vjs-controls > div.vjs-time-control { + border-top-left-radius: 0; -webkit-border-top-left-radius: 0; -moz-border-radius-topleft: 0; + border-bottom-left-radius: 0; -webkit-border-bottom-left-radius: 0; -moz-border-radius-bottomleft: 0; +} + +/* Play/Pause +-------------------------------------------------------------------------------- */ +.vjs-play-control { cursor: pointer !important; } +/* Play Icon */ +.vjs-play-control span { display: block; font-size: 0; line-height: 0; } +.vjs-paused .vjs-play-control span { + width: 0; height: 0; margin: 8px 0 0 8px; + /* Drawing the play triangle with borders - http://www.infimum.dk/HTML/slantinfo.html */ + border-left: 10px solid #fff; /* Width & Color of play icon */ + /* Height of play icon is total top & bottom border widths. Color is transparent. */ + border-top: 5px solid rgba(0,0,0,0); border-bottom: 5px solid rgba(0,0,0,0); +} +.vjs-playing .vjs-play-control span { + width: 3px; height: 10px; margin: 8px auto 0; + /* Drawing the pause bars with borders */ + border-top: 0px; border-left: 3px solid #fff; border-bottom: 0px; border-right: 3px solid #fff; +} + +/* Progress +-------------------------------------------------------------------------------- */ +.vjs-progress-holder { /* Box containing play and load progresses */ + position: relative; padding: 0; overflow:hidden; cursor: pointer !important; + height: 9px; border: 1px solid #777; + margin: 7px 1px 0 5px; /* Placement within the progress control item */ + border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; +} +.vjs-progress-holder div { /* Progress Bars */ + position: absolute; display: block; width: 0; height: 9px; margin: 0; padding: 0; + border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; +} +.vjs-play-progress { + /* CSS Gradient */ + /* Default */ background: #fff; + /* Webkit */ background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#777)); + /* Firefox */ background: -moz-linear-gradient(top, #fff, #777); +} +.vjs-load-progress { + opacity: 0.8; + /* CSS Gradient */ + /* Default */ background-color: #555; + /* Webkit */ background: -webkit-gradient(linear, left top, left bottom, from(#555), to(#aaa)); + /* Firefox */ background: -moz-linear-gradient(top, #555, #aaa); +} + +/* Time Display +-------------------------------------------------------------------------------- */ +.vjs-controls .vjs-time-control { font-size: 10px; line-height: 1; font-weight: normal; font-family: Helvetica, Arial, sans-serif; } +.vjs-controls .vjs-time-control span { line-height: 25px; /* Centering vertically */ } + +/* Volume +-------------------------------------------------------------------------------- */ +.vjs-volume-control { cursor: pointer !important; } +.vjs-volume-control div { display: block; margin: 0 5px 0 5px; padding: 4px 0 0 0; } +/* Drawing the volume icon using 6 span elements */ +.vjs-volume-control div span { /* Individual volume bars */ + float: left; padding: 0; + margin: 0 2px 0 0; /* Space between */ + width: 5px; height: 0px; /* Total height is height + bottom border */ + border-bottom: 18px solid #555; /* Default (off) color and height of visible portion */ +} +.vjs-volume-control div span.vjs-volume-level-on { border-color: #fff; /* Volume on bar color */ } +/* Creating differnt bar heights through height (transparent) and bottom border (visible). */ +.vjs-volume-control div span:nth-child(1) { border-bottom-width: 2px; height: 16px; } +.vjs-volume-control div span:nth-child(2) { border-bottom-width: 4px; height: 14px; } +.vjs-volume-control div span:nth-child(3) { border-bottom-width: 7px; height: 11px; } +.vjs-volume-control div span:nth-child(4) { border-bottom-width: 10px; height: 8px; } +.vjs-volume-control div span:nth-child(5) { border-bottom-width: 14px; height: 4px; } +.vjs-volume-control div span:nth-child(6) { margin-right: 0; } + +/* Fullscreen +-------------------------------------------------------------------------------- */ +.vjs-fullscreen-control { cursor: pointer !important; } +.vjs-fullscreen-control div { + padding: 0; text-align: left; vertical-align: top; cursor: pointer !important; + margin: 5px 0 0 5px; /* Placement within the fullscreen control item */ + width: 20px; height: 20px; +} +/* Drawing the fullscreen icon using 4 span elements */ +.vjs-fullscreen-control div span { float: left; margin: 0; padding: 0; font-size: 0; line-height: 0; width: 0; text-align: left; vertical-align: top; } +.vjs-fullscreen-control div span:nth-child(1) { /* Top-left triangle */ + margin-right: 3px; /* Space between top-left and top-right */ + margin-bottom: 3px; /* Space between top-left and bottom-left */ + border-top: 6px solid #fff; /* Height and color */ + border-right: 6px solid rgba(0,0,0,0); /* Width */ +} +.vjs-fullscreen-control div span:nth-child(2) { border-top: 6px solid #fff; border-left: 6px solid rgba(0,0,0,0); } +.vjs-fullscreen-control div span:nth-child(3) { clear: both; margin: 0 3px 0 0; border-bottom: 6px solid #fff; border-right: 6px solid rgba(0,0,0,0); } +.vjs-fullscreen-control div span:nth-child(4) { border-bottom: 6px solid #fff; border-left: 6px solid rgba(0,0,0,0); } +/* Icon when video is in fullscreen mode */ +.vjs-fullscreen .vjs-fullscreen-control div span:nth-child(1) { border: none; border-bottom: 6px solid #fff; border-left: 6px solid rgba(0,0,0,0); } +.vjs-fullscreen .vjs-fullscreen-control div span:nth-child(2) { border: none; border-bottom: 6px solid #fff; border-right: 6px solid rgba(0,0,0,0); } +.vjs-fullscreen .vjs-fullscreen-control div span:nth-child(3) { border: none; border-top: 6px solid #fff; border-left: 6px solid rgba(0,0,0,0); } +.vjs-fullscreen .vjs-fullscreen-control div span:nth-child(4) { border: none; border-top: 6px solid #fff; border-right: 6px solid rgba(0,0,0,0); } + +/* Download Links - Used for browsers that don't support any video. +---------------------------------------------------------*/ +.vjs-no-video { font-size: small; line-height: 1.5; } + +/* Big Play Button (at start) +---------------------------------------------------------*/ +div.vjs-big-play-button { + display: none; /* Start hidden */ z-index: 2; + position: absolute; top: 50%; left: 50%; width: 80px; height: 80px; margin: -43px 0 0 -43px; text-align: center; vertical-align: center; cursor: pointer !important; + border: 3px solid #fff; opacity: 0.9; + border-radius: 20px; -webkit-border-radius: 20px; -moz-border-radius: 20px; + + /* CSS Background Gradients */ + /* Default */ background-color: #0B151A; + /* Webkit */ background: #1F3744 -webkit-gradient(linear, left top, left bottom, from(#0B151A), to(#1F3744)) left 40px; + /* Firefox */ background: #1F3744 -moz-linear-gradient(top, #0B151A, #1F3744) left 40px; + + /* CSS Shadows */ + box-shadow: 4px 4px 8px #000; -webkit-box-shadow: 4px 4px 8px #000; -moz-box-shadow: 4px 4px 8px #000; +} +div.vjs-big-play-button:hover { + box-shadow: 0px 0px 80px #fff; -webkit-box-shadow: 0px 0px 80px #fff; -moz-box-shadow: 0px 0px 80px #fff; +} + +div.vjs-big-play-button span { + display: block; font-size: 0; line-height: 0; + width: 0; height: 0; margin: 20px 0 0 23px; + /* Drawing the play triangle with borders - http://www.infimum.dk/HTML/slantinfo.html */ + border-left: 40px solid #fff; /* Width & Color of play icon */ + /* Height of play icon is total top & bottom border widths. Color is transparent. */ + border-top: 20px solid rgba(0,0,0,0); border-bottom: 20px solid rgba(0,0,0,0); +} + +/* Spinner Styles +---------------------------------------------------------*/ +/* CSS Spinners by Kilian Valkhof - http://kilianvalkhof.com/2010/css-xhtml/css3-loading-spinners-without-images/ */ +.vjs-spinner { display: none; position: absolute; top: 50%; left: 50%; width: 100px; height: 100px; z-index: 1; margin: -50px 0 0 -50px; + /* Scaling makes the circles look smoother. */ + transform: scale(0.5); -webkit-transform:scale(0.5); -moz-transform:scale(0.5); +} +/* Spinner circles */ +.vjs-spinner div { position:absolute; left: 40px; top: 40px; width: 20px; height: 20px; background: #fff; + border-radius: 20px; -webkit-border-radius: 20px; -moz-border-radius: 20px; + border: 1px solid #ccc; /* Added border so can be visible on white backgrounds */ +} +/* Each circle */ +.vjs-spinner div:nth-child(1) { opacity: 0.12; transform: rotate(000deg) translate(0, -40px) scale(0.1); -webkit-transform: rotate(000deg) translate(0, -40px) scale(0.1); -moz-transform: rotate(000deg) translate(0, -40px) scale(0.1); } +.vjs-spinner div:nth-child(2) { opacity: 0.25; transform: rotate(045deg) translate(0, -40px) scale(0.2); -webkit-transform: rotate(045deg) translate(0, -40px) scale(0.2); -moz-transform: rotate(045deg) translate(0, -40px) scale(0.2); } +.vjs-spinner div:nth-child(3) { opacity: 0.37; transform: rotate(090deg) translate(0, -40px) scale(0.4); -webkit-transform: rotate(090deg) translate(0, -40px) scale(0.4); -moz-transform: rotate(090deg) translate(0, -40px) scale(0.4); } +.vjs-spinner div:nth-child(4) { opacity: 0.50; transform: rotate(135deg) translate(0, -40px) scale(0.6); -webkit-transform: rotate(135deg) translate(0, -40px) scale(0.6); -moz-transform: rotate(135deg) translate(0, -40px) scale(0.6); } +.vjs-spinner div:nth-child(5) { opacity: 0.62; transform: rotate(180deg) translate(0, -40px) scale(0.8); -webkit-transform: rotate(180deg) translate(0, -40px) scale(0.8); -moz-transform: rotate(180deg) translate(0, -40px) scale(0.8); } +.vjs-spinner div:nth-child(6) { opacity: 0.75; transform: rotate(225deg) translate(0, -40px) scale(1.0); -webkit-transform: rotate(225deg) translate(0, -40px) scale(1.0); -moz-transform: rotate(225deg) translate(0, -40px) scale(1.0); } +.vjs-spinner div:nth-child(7) { opacity: 0.87; transform: rotate(270deg) translate(0, -40px) scale(1.1); -webkit-transform: rotate(270deg) translate(0, -40px) scale(1.1); -moz-transform: rotate(270deg) translate(0, -40px) scale(1.1); } +.vjs-spinner div:nth-child(8) { opacity: 1.00; transform: rotate(315deg) translate(0, -40px) scale(1.3); -webkit-transform: rotate(315deg) translate(0, -40px) scale(1.3); -moz-transform: rotate(315deg) translate(0, -40px) scale(1.3); } \ No newline at end of file Added: polly/trunk/www/video-js/video.js URL: http://llvm.org/viewvc/llvm-project/polly/trunk/www/video-js/video.js?rev=146487&view=auto ============================================================================== --- polly/trunk/www/video-js/video.js (added) +++ polly/trunk/www/video-js/video.js Tue Dec 13 09:09:09 2011 @@ -0,0 +1,1758 @@ +/* +VideoJS - HTML5 Video Player +v2.0.2 + +This file is part of VideoJS. Copyright 2010 Zencoder, Inc. + +VideoJS is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +VideoJS is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with VideoJS. If not, see . +*/ + +// Self-executing function to prevent global vars and help with minification +(function(window, undefined){ + var document = window.document; + +// Using jresig's Class implementation http://ejohn.org/blog/simple-javascript-inheritance/ +(function(){var initializing=false, fnTest=/xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; this.JRClass = function(){}; JRClass.extend = function(prop) { var _super = this.prototype; initializing = true; var prototype = new this(); initializing = false; for (var name in prop) { prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn){ return function() { var tmp = this._super; this._super = _super[name]; var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } function JRClass() { if ( !initializing && this.init ) this.init.apply(this, arguments); } JRClass.prototype = prototype; JRClass.constructor = JRClass; JRClass.extend = arguments.callee; return JRClass;};})(); + +// Video JS Player Class +var VideoJS = JRClass.extend({ + + // Initialize the player for the supplied video tag element + // element: video tag + init: function(element, setOptions){ + + // Allow an ID string or an element + if (typeof element == 'string') { + this.video = document.getElementById(element); + } else { + this.video = element; + } + // Store reference to player on the video element. + // So you can acess the player later: document.getElementById("video_id").player.play(); + this.video.player = this; + this.values = {}; // Cache video values. + this.elements = {}; // Store refs to controls elements. + + // Default Options + this.options = { + autoplay: false, + preload: true, + useBuiltInControls: false, // Use the browser's controls (iPhone) + controlsBelow: false, // Display control bar below video vs. in front of + controlsAtStart: false, // Make controls visible when page loads + controlsHiding: true, // Hide controls when not over the video + defaultVolume: 0.85, // Will be overridden by localStorage volume if available + playerFallbackOrder: ["html5", "flash", "links"], // Players and order to use them + flashPlayer: "htmlObject", + flashPlayerVersion: false // Required flash version for fallback + }; + // Override default options with global options + if (typeof VideoJS.options == "object") { _V_.merge(this.options, VideoJS.options); } + // Override default & global options with options specific to this player + if (typeof setOptions == "object") { _V_.merge(this.options, setOptions); } + // Override preload & autoplay with video attributes + if (this.getPreloadAttribute() !== undefined) { this.options.preload = this.getPreloadAttribute(); } + if (this.getAutoplayAttribute() !== undefined) { this.options.autoplay = this.getAutoplayAttribute(); } + + // Store reference to embed code pieces + this.box = this.video.parentNode; + this.linksFallback = this.getLinksFallback(); + this.hideLinksFallback(); // Will be shown again if "links" player is used + + // Loop through the player names list in options, "html5" etc. + // For each player name, initialize the player with that name under VideoJS.players + // If the player successfully initializes, we're done + // If not, try the next player in the list + this.each(this.options.playerFallbackOrder, function(playerType){ + if (this[playerType+"Supported"]()) { // Check if player type is supported + this[playerType+"Init"](); // Initialize player type + return true; // Stop looping though players + } + }); + + // Start Global Listeners - API doesn't exist before now + this.activateElement(this, "player"); + this.activateElement(this.box, "box"); + }, + /* Behaviors + ================================================================================ */ + behaviors: {}, + newBehavior: function(name, activate, functions){ + this.behaviors[name] = activate; + this.extend(functions); + }, + activateElement: function(element, behavior){ + // Allow passing and ID string + if (typeof element == "string") { element = document.getElementById(element); } + this.behaviors[behavior].call(this, element); + }, + /* Errors/Warnings + ================================================================================ */ + errors: [], // Array to track errors + warnings: [], + warning: function(warning){ + this.warnings.push(warning); + this.log(warning); + }, + /* History of errors/events (not quite there yet) + ================================================================================ */ + history: [], + log: function(event){ + if (!event) { return; } + if (typeof event == "string") { event = { type: event }; } + if (event.type) { this.history.push(event.type); } + if (this.history.length >= 50) { this.history.shift(); } + try { console.log(event.type); } catch(e) { try { opera.postError(event.type); } catch(e){} } + }, + /* Local Storage + ================================================================================ */ + setLocalStorage: function(key, value){ + if (!localStorage) { return; } + try { + localStorage[key] = value; + } catch(e) { + if (e.code == 22 || e.code == 1014) { // Webkit == 22 / Firefox == 1014 + this.warning(VideoJS.warnings.localStorageFull); + } + } + }, + /* Helpers + ================================================================================ */ + getPreloadAttribute: function(){ + if (typeof this.video.hasAttribute == "function" && this.video.hasAttribute("preload")) { + var preload = this.video.getAttribute("preload"); + // Only included the attribute, thinking it was boolean + if (preload === "" || preload === "true") { return "auto"; } + if (preload === "false") { return "none"; } + return preload; + } + }, + getAutoplayAttribute: function(){ + if (typeof this.video.hasAttribute == "function" && this.video.hasAttribute("autoplay")) { + var autoplay = this.video.getAttribute("autoplay"); + if (autoplay === "false") { return false; } + return true; + } + }, + // Calculates amoutn of buffer is full + bufferedPercent: function(){ return (this.duration()) ? this.buffered()[1] / this.duration() : 0; }, + // Each that maintains player as context + // Break if true is returned + each: function(arr, fn){ + if (!arr || arr.length === 0) { return; } + for (var i=0,j=arr.length; i= playerVersion; + } +}); +VideoJS.flashPlayers = {}; +VideoJS.flashPlayers.htmlObject = { + flashPlayerVersion: 9, + init: function() { return true; }, + api: { // No video API available with HTML Object embed method + width: function(width){ + if (width !== undefined) { + this.element.width = width; + this.box.style.width = width+"px"; + this.triggerResizeListeners(); + return this; + } + return this.element.width; + }, + height: function(height){ + if (height !== undefined) { + this.element.height = height; + this.box.style.height = height+"px"; + this.triggerResizeListeners(); + return this; + } + return this.element.height; + } + } +}; + + +/* Download Links Fallback (Player Type) +================================================================================ */ +VideoJS.player.extend({ + linksSupported: function(){ return true; }, + linksInit: function(){ + this.showLinksFallback(); + this.element = this.video; + }, + // Get the download links block element + getLinksFallback: function(){ return this.box.getElementsByTagName("P")[0]; }, + // Hide no-video download paragraph + hideLinksFallback: function(){ + if (this.linksFallback) { this.linksFallback.style.display = "none"; } + }, + // Hide no-video download paragraph + showLinksFallback: function(){ + if (this.linksFallback) { this.linksFallback.style.display = "block"; } + } +}); + +//////////////////////////////////////////////////////////////////////////////// +// Class Methods +// Functions that don't apply to individual videos. +//////////////////////////////////////////////////////////////////////////////// + +// Combine Objects - Use "safe" to protect from overwriting existing items +VideoJS.merge = function(obj1, obj2, safe){ + for (var attrname in obj2){ + if (obj2.hasOwnProperty(attrname) && (!safe || !obj1.hasOwnProperty(attrname))) { obj1[attrname]=obj2[attrname]; } + } + return obj1; +}; +VideoJS.extend = function(obj){ this.merge(this, obj, true); }; + +VideoJS.extend({ + // Add VideoJS to all video tags with the video-js class when the DOM is ready + setupAllWhenReady: function(options){ + // Options is stored globally, and added ot any new player on init + VideoJS.options = options; + VideoJS.DOMReady(VideoJS.setup); + }, + + // Run the supplied function when the DOM is ready + DOMReady: function(fn){ + VideoJS.addToDOMReady(fn); + }, + + // Set up a specific video or array of video elements + // "video" can be: + // false, undefined, or "All": set up all videos with the video-js class + // A video tag ID or video tag element: set up one video and return one player + // An array of video tag elements/IDs: set up each and return an array of players + setup: function(videos, options){ + var returnSingular = false, + playerList = [], + videoElement; + + // If videos is undefined or "All", set up all videos with the video-js class + if (!videos || videos == "All") { + videos = VideoJS.getVideoJSTags(); + // If videos is not an array, add to an array + } else if (typeof videos != 'object' || videos.nodeType == 1) { + videos = [videos]; + returnSingular = true; + } + + // Loop through videos and create players for them + for (var i=0; i 0) { + var newBufferEnd = (event.loaded / event.total) * this.duration(); + if (newBufferEnd > this.values.bufferEnd) { this.values.bufferEnd = newBufferEnd; } + } + }, + + iOSInterface: function(){ + if(VideoJS.iOSVersion() < 4) { this.forceTheSource(); } // Fix loading issues + if(VideoJS.isIPad()) { // iPad could work with controlsBelow + this.buildAndActivateSpinner(); // Spinner still works well on iPad, since iPad doesn't have one + } + }, + + // Fix android specific quirks + // Use built-in controls, but add the big play button, since android doesn't have one. + androidInterface: function(){ + this.forceTheSource(); // Fix loading issues + _V_.addListener(this.video, "click", function(){ this.play(); }); // Required to play + this.buildBigPlayButton(); // But don't activate the normal way. Pause doesn't work right on android. + _V_.addListener(this.bigPlayButton, "click", function(){ this.play(); }.context(this)); + this.positionBox(); + this.showBigPlayButtons(); + }, + /* Wait for styles (TODO: move to _V_) + ================================================================================ */ + loadInterface: function(){ + if(!this.stylesHaveLoaded()) { + // Don't want to create an endless loop either. + if (!this.positionRetries) { this.positionRetries = 1; } + if (this.positionRetries++ < 100) { + setTimeout(this.loadInterface.context(this),10); + return; + } + } + this.hideStylesCheckDiv(); + this.showPoster(); + if (this.video.paused !== false) { this.showBigPlayButtons(); } + if (this.options.controlsAtStart) { this.showControlBars(); } + this.positionAll(); + }, + /* Control Bar + ================================================================================ */ + buildAndActivateControlBar: function(){ + /* Creating this HTML +
+
+ +
+
+
+
+
+
+
+
+ 00:00 / 00:00 +
+
+
+ +
+
+
+
+ +
+
+
+ */ + + // Create a div to hold the different controls + this.controls = _V_.createElement("div", { className: "vjs-controls" }); + // Add the controls to the video's container + this.box.appendChild(this.controls); + this.activateElement(this.controls, "controlBar"); + this.activateElement(this.controls, "mouseOverVideoReporter"); + + // Build the play control + this.playControl = _V_.createElement("div", { className: "vjs-play-control", innerHTML: "" }); + this.controls.appendChild(this.playControl); + this.activateElement(this.playControl, "playToggle"); + + // Build the progress control + this.progressControl = _V_.createElement("div", { className: "vjs-progress-control" }); + this.controls.appendChild(this.progressControl); + + // Create a holder for the progress bars + this.progressHolder = _V_.createElement("div", { className: "vjs-progress-holder" }); + this.progressControl.appendChild(this.progressHolder); + this.activateElement(this.progressHolder, "currentTimeScrubber"); + + // Create the loading progress display + this.loadProgressBar = _V_.createElement("div", { className: "vjs-load-progress" }); + this.progressHolder.appendChild(this.loadProgressBar); + this.activateElement(this.loadProgressBar, "loadProgressBar"); + + // Create the playing progress display + this.playProgressBar = _V_.createElement("div", { className: "vjs-play-progress" }); + this.progressHolder.appendChild(this.playProgressBar); + this.activateElement(this.playProgressBar, "playProgressBar"); + + // Create the progress time display (00:00 / 00:00) + this.timeControl = _V_.createElement("div", { className: "vjs-time-control" }); + this.controls.appendChild(this.timeControl); + + // Create the current play time display + this.currentTimeDisplay = _V_.createElement("span", { className: "vjs-current-time-display", innerHTML: "00:00" }); + this.timeControl.appendChild(this.currentTimeDisplay); + this.activateElement(this.currentTimeDisplay, "currentTimeDisplay"); + + // Add time separator + this.timeSeparator = _V_.createElement("span", { innerHTML: " / " }); + this.timeControl.appendChild(this.timeSeparator); + + // Create the total duration display + this.durationDisplay = _V_.createElement("span", { className: "vjs-duration-display", innerHTML: "00:00" }); + this.timeControl.appendChild(this.durationDisplay); + this.activateElement(this.durationDisplay, "durationDisplay"); + + // Create the volumne control + this.volumeControl = _V_.createElement("div", { + className: "vjs-volume-control", + innerHTML: "
" + }); + this.controls.appendChild(this.volumeControl); + this.activateElement(this.volumeControl, "volumeScrubber"); + + this.volumeDisplay = this.volumeControl.children[0]; + this.activateElement(this.volumeDisplay, "volumeDisplay"); + + // Crete the fullscreen control + this.fullscreenControl = _V_.createElement("div", { + className: "vjs-fullscreen-control", + innerHTML: "
" + }); + this.controls.appendChild(this.fullscreenControl); + this.activateElement(this.fullscreenControl, "fullscreenToggle"); + }, + /* Poster Image + ================================================================================ */ + buildAndActivatePoster: function(){ + this.updatePosterSource(); + if (this.video.poster) { + this.poster = document.createElement("img"); + // Add poster to video box + this.box.appendChild(this.poster); + + // Add poster image data + this.poster.src = this.video.poster; + // Add poster styles + this.poster.className = "vjs-poster"; + this.activateElement(this.poster, "poster"); + } else { + this.poster = false; + } + }, + /* Big Play Button + ================================================================================ */ + buildBigPlayButton: function(){ + /* Creating this HTML +
+ */ + this.bigPlayButton = _V_.createElement("div", { + className: "vjs-big-play-button", + innerHTML: "" + }); + this.box.appendChild(this.bigPlayButton); + this.activateElement(this.bigPlayButton, "bigPlayButton"); + }, + /* Spinner (Loading) + ================================================================================ */ + buildAndActivateSpinner: function(){ + this.spinner = _V_.createElement("div", { + className: "vjs-spinner", + innerHTML: "
" + }); + this.box.appendChild(this.spinner); + this.activateElement(this.spinner, "spinner"); + }, + /* Styles Check - Check if styles are loaded (move ot _V_) + ================================================================================ */ + // Sometimes the CSS styles haven't been applied to the controls yet + // when we're trying to calculate the height and position them correctly. + // This causes a flicker where the controls are out of place. + buildStylesCheckDiv: function(){ + this.stylesCheckDiv = _V_.createElement("div", { className: "vjs-styles-check" }); + this.stylesCheckDiv.style.position = "absolute"; + this.box.appendChild(this.stylesCheckDiv); + }, + hideStylesCheckDiv: function(){ this.stylesCheckDiv.style.display = "none"; }, + stylesHaveLoaded: function(){ + if (this.stylesCheckDiv.offsetHeight != 5) { + return false; + } else { + return true; + } + }, + /* VideoJS Box - Holds all elements + ================================================================================ */ + positionAll: function(){ + this.positionBox(); + this.positionControlBars(); + this.positionPoster(); + }, + positionBox: function(){ + // Set width based on fullscreen or not. + if (this.videoIsFullScreen) { + this.box.style.width = ""; + this.element.style.height=""; + if (this.options.controlsBelow) { + this.box.style.height = ""; + this.element.style.height = (this.box.offsetHeight - this.controls.offsetHeight) + "px"; + } + } else { + this.box.style.width = this.width() + "px"; + this.element.style.height=this.height()+"px"; + if (this.options.controlsBelow) { + this.element.style.height = ""; + // this.box.style.height = this.video.offsetHeight + this.controls.offsetHeight + "px"; + } + } + }, + /* Subtitles + ================================================================================ */ + getSubtitles: function(){ + var tracks = this.video.getElementsByTagName("TRACK"); + for (var i=0,j=tracks.length; i "); + subtitle.start = this.parseSubtitleTime(time[0]); + subtitle.end = this.parseSubtitleTime(time[1]); + + // Additional lines - Subtitle Text + text = []; + for (var j=i; j'); + + // Add this subtitle + this.subtitles.push(subtitle); + } + } + }, + + parseSubtitleTime: function(timeText) { + var parts = timeText.split(':'), + time = 0; + // hours => seconds + time += parseFloat(parts[0])*60*60; + // minutes => seconds + time += parseFloat(parts[1])*60; + // get seconds + var seconds = parts[2].split(/\.|,/); // Either . or , + time += parseFloat(seconds[0]); + // add miliseconds + ms = parseFloat(seconds[1]); + if (ms) { time += ms/1000; } + return time; + }, + + buildSubtitles: function(){ + /* Creating this HTML +
+ */ + this.subtitlesDisplay = _V_.createElement("div", { className: 'vjs-subtitles' }); + this.box.appendChild(this.subtitlesDisplay); + this.activateElement(this.subtitlesDisplay, "subtitlesDisplay"); + }, + + /* Player API - Translate functionality from player to video + ================================================================================ */ + addVideoListener: function(type, fn){ _V_.addListener(this.video, type, fn.rEvtContext(this)); }, + + play: function(){ + this.video.play(); + return this; + }, + onPlay: function(fn){ this.addVideoListener("play", fn); return this; }, + + pause: function(){ + this.video.pause(); + return this; + }, + onPause: function(fn){ this.addVideoListener("pause", fn); return this; }, + paused: function() { return this.video.paused; }, + + currentTime: function(seconds){ + if (seconds !== undefined) { + try { this.video.currentTime = seconds; } + catch(e) { this.warning(VideoJS.warnings.videoNotReady); } + this.values.currentTime = seconds; + return this; + } + return this.video.currentTime; + }, + onCurrentTimeUpdate: function(fn){ + this.currentTimeListeners.push(fn); + }, + + duration: function(){ + return this.video.duration; + }, + + buffered: function(){ + // Storing values allows them be overridden by setBufferedFromProgress + if (this.values.bufferStart === undefined) { + this.values.bufferStart = 0; + this.values.bufferEnd = 0; + } + if (this.video.buffered && this.video.buffered.length > 0) { + var newEnd = this.video.buffered.end(0); + if (newEnd > this.values.bufferEnd) { this.values.bufferEnd = newEnd; } + } + return [this.values.bufferStart, this.values.bufferEnd]; + }, + + volume: function(percentAsDecimal){ + if (percentAsDecimal !== undefined) { + // Force value to between 0 and 1 + this.values.volume = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); + this.video.volume = this.values.volume; + this.setLocalStorage("volume", this.values.volume); + return this; + } + if (this.values.volume) { return this.values.volume; } + return this.video.volume; + }, + onVolumeChange: function(fn){ _V_.addListener(this.video, 'volumechange', fn.rEvtContext(this)); }, + + width: function(width){ + if (width !== undefined) { + this.video.width = width; // Not using style so it can be overridden on fullscreen. + this.box.style.width = width+"px"; + this.triggerResizeListeners(); + return this; + } + return this.video.offsetWidth; + }, + height: function(height){ + if (height !== undefined) { + this.video.height = height; + this.box.style.height = height+"px"; + this.triggerResizeListeners(); + return this; + } + return this.video.offsetHeight; + }, + + supportsFullScreen: function(){ + if(typeof this.video.webkitEnterFullScreen == 'function') { + // Seems to be broken in Chromium/Chrome + if (!navigator.userAgent.match("Chrome") && !navigator.userAgent.match("Mac OS X 10.5")) { + return true; + } + } + return false; + }, + + html5EnterNativeFullScreen: function(){ + try { + this.video.webkitEnterFullScreen(); + } catch (e) { + if (e.code == 11) { this.warning(VideoJS.warnings.videoNotReady); } + } + return this; + }, + + // Turn on fullscreen (window) mode + // Real fullscreen isn't available in browsers quite yet. + enterFullScreen: function(){ + if (this.supportsFullScreen()) { + this.html5EnterNativeFullScreen(); + } else { + this.enterFullWindow(); + } + }, + + exitFullScreen: function(){ + if (this.supportsFullScreen()) { + // Shouldn't be called + } else { + this.exitFullWindow(); + } + }, + + enterFullWindow: function(){ + this.videoIsFullScreen = true; + // Storing original doc overflow value to return to when fullscreen is off + this.docOrigOverflow = document.documentElement.style.overflow; + // Add listener for esc key to exit fullscreen + _V_.addListener(document, "keydown", this.fullscreenOnEscKey.rEvtContext(this)); + // Add listener for a window resize + _V_.addListener(window, "resize", this.fullscreenOnWindowResize.rEvtContext(this)); + // Hide any scroll bars + document.documentElement.style.overflow = 'hidden'; + // Apply fullscreen styles + _V_.addClass(this.box, "vjs-fullscreen"); + // Resize the box, controller, and poster + this.positionAll(); + }, + + // Turn off fullscreen (window) mode + exitFullWindow: function(){ + this.videoIsFullScreen = false; + document.removeEventListener("keydown", this.fullscreenOnEscKey, false); + window.removeEventListener("resize", this.fullscreenOnWindowResize, false); + // Unhide scroll bars. + document.documentElement.style.overflow = this.docOrigOverflow; + // Remove fullscreen styles + _V_.removeClass(this.box, "vjs-fullscreen"); + // Resize the box, controller, and poster to original sizes + this.positionAll(); + }, + + onError: function(fn){ this.addVideoListener("error", fn); return this; }, + onEnded: function(fn){ + this.addVideoListener("ended", fn); return this; + } +}); + +//////////////////////////////////////////////////////////////////////////////// +// Element Behaviors +// Tell elements how to act or react +//////////////////////////////////////////////////////////////////////////////// + +/* Player Behaviors - How VideoJS reacts to what the video is doing. +================================================================================ */ +VideoJS.player.newBehavior("player", function(player){ + this.onError(this.playerOnVideoError); + // Listen for when the video is played + this.onPlay(this.playerOnVideoPlay); + this.onPlay(this.trackCurrentTime); + // Listen for when the video is paused + this.onPause(this.playerOnVideoPause); + this.onPause(this.stopTrackingCurrentTime); + // Listen for when the video ends + this.onEnded(this.playerOnVideoEnded); + // Set interval for load progress using buffer watching method + // this.trackCurrentTime(); + this.trackBuffered(); + // Buffer Full + this.onBufferedUpdate(this.isBufferFull); + },{ + playerOnVideoError: function(event){ + this.log(event); + this.log(this.video.error); + }, + playerOnVideoPlay: function(event){ this.hasPlayed = true; }, + playerOnVideoPause: function(event){}, + playerOnVideoEnded: function(event){ + this.currentTime(0); + this.pause(); + }, + + /* Load Tracking -------------------------------------------------------------- */ + // Buffer watching method for load progress. + // Used for browsers that don't support the progress event + trackBuffered: function(){ + this.bufferedInterval = setInterval(this.triggerBufferedListeners.context(this), 500); + }, + stopTrackingBuffered: function(){ clearInterval(this.bufferedInterval); }, + bufferedListeners: [], + onBufferedUpdate: function(fn){ + this.bufferedListeners.push(fn); + }, + triggerBufferedListeners: function(){ + this.isBufferFull(); + this.each(this.bufferedListeners, function(listener){ + (listener.context(this))(); + }); + }, + isBufferFull: function(){ + if (this.bufferedPercent() == 1) { this.stopTrackingBuffered(); } + }, + + /* Time Tracking -------------------------------------------------------------- */ + trackCurrentTime: function(){ + if (this.currentTimeInterval) { clearInterval(this.currentTimeInterval); } + this.currentTimeInterval = setInterval(this.triggerCurrentTimeListeners.context(this), 100); // 42 = 24 fps + this.trackingCurrentTime = true; + }, + // Turn off play progress tracking (when paused or dragging) + stopTrackingCurrentTime: function(){ + clearInterval(this.currentTimeInterval); + this.trackingCurrentTime = false; + }, + currentTimeListeners: [], + // onCurrentTimeUpdate is in API section now + triggerCurrentTimeListeners: function(late, newTime){ // FF passes milliseconds late as the first argument + this.each(this.currentTimeListeners, function(listener){ + (listener.context(this))(newTime || this.currentTime()); + }); + }, + + /* Resize Tracking -------------------------------------------------------------- */ + resizeListeners: [], + onResize: function(fn){ + this.resizeListeners.push(fn); + }, + // Trigger anywhere the video/box size is changed. + triggerResizeListeners: function(){ + this.each(this.resizeListeners, function(listener){ + (listener.context(this))(); + }); + } + } +); +/* Mouse Over Video Reporter Behaviors - i.e. Controls hiding based on mouse location +================================================================================ */ +VideoJS.player.newBehavior("mouseOverVideoReporter", function(element){ + // Listen for the mouse move the video. Used to reveal the controller. + _V_.addListener(element, "mousemove", this.mouseOverVideoReporterOnMouseMove.context(this)); + // Listen for the mouse moving out of the video. Used to hide the controller. + _V_.addListener(element, "mouseout", this.mouseOverVideoReporterOnMouseOut.context(this)); + },{ + mouseOverVideoReporterOnMouseMove: function(){ + this.showControlBars(); + clearInterval(this.mouseMoveTimeout); + this.mouseMoveTimeout = setTimeout(this.hideControlBars.context(this), 4000); + }, + mouseOverVideoReporterOnMouseOut: function(event){ + // Prevent flicker by making sure mouse hasn't left the video + var parent = event.relatedTarget; + while (parent && parent !== this.box) { + parent = parent.parentNode; + } + if (parent !== this.box) { + this.hideControlBars(); + } + } + } +); +/* Mouse Over Video Reporter Behaviors - i.e. Controls hiding based on mouse location +================================================================================ */ +VideoJS.player.newBehavior("box", function(element){ + this.positionBox(); + _V_.addClass(element, "vjs-paused"); + this.activateElement(element, "mouseOverVideoReporter"); + this.onPlay(this.boxOnVideoPlay); + this.onPause(this.boxOnVideoPause); + },{ + boxOnVideoPlay: function(){ + _V_.removeClass(this.box, "vjs-paused"); + _V_.addClass(this.box, "vjs-playing"); + }, + boxOnVideoPause: function(){ + _V_.removeClass(this.box, "vjs-playing"); + _V_.addClass(this.box, "vjs-paused"); + } + } +); +/* Poster Image Overlay +================================================================================ */ +VideoJS.player.newBehavior("poster", function(element){ + this.activateElement(element, "mouseOverVideoReporter"); + this.activateElement(element, "playButton"); + this.onPlay(this.hidePoster); + this.onEnded(this.showPoster); + this.onResize(this.positionPoster); + },{ + showPoster: function(){ + if (!this.poster) { return; } + this.poster.style.display = "block"; + this.positionPoster(); + }, + positionPoster: function(){ + // Only if the poster is visible + if (!this.poster || this.poster.style.display == 'none') { return; } + this.poster.style.height = this.height() + "px"; // Need incase controlsBelow + this.poster.style.width = this.width() + "px"; // Could probably do 100% of box + }, + hidePoster: function(){ + if (!this.poster) { return; } + this.poster.style.display = "none"; + }, + // Update poster source from attribute or fallback image + // iPad breaks if you include a poster attribute, so this fixes that + updatePosterSource: function(){ + if (!this.video.poster) { + var images = this.video.getElementsByTagName("img"); + if (images.length > 0) { this.video.poster = images[0].src; } + } + } + } +); +/* Control Bar Behaviors +================================================================================ */ +VideoJS.player.newBehavior("controlBar", function(element){ + if (!this.controlBars) { + this.controlBars = []; + this.onResize(this.positionControlBars); + } + this.controlBars.push(element); + _V_.addListener(element, "mousemove", this.onControlBarsMouseMove.context(this)); + _V_.addListener(element, "mouseout", this.onControlBarsMouseOut.context(this)); + },{ + showControlBars: function(){ + if (!this.options.controlsAtStart && !this.hasPlayed) { return; } + this.each(this.controlBars, function(bar){ + bar.style.display = "block"; + }); + }, + // Place controller relative to the video's position (now just resizing bars) + positionControlBars: function(){ + this.updatePlayProgressBars(); + this.updateLoadProgressBars(); + }, + hideControlBars: function(){ + if (this.options.controlsHiding && !this.mouseIsOverControls) { + this.each(this.controlBars, function(bar){ + bar.style.display = "none"; + }); + } + }, + // Block controls from hiding when mouse is over them. + onControlBarsMouseMove: function(){ this.mouseIsOverControls = true; }, + onControlBarsMouseOut: function(event){ + this.mouseIsOverControls = false; + } + } +); +/* PlayToggle, PlayButton, PauseButton Behaviors +================================================================================ */ +// Play Toggle +VideoJS.player.newBehavior("playToggle", function(element){ + if (!this.elements.playToggles) { + this.elements.playToggles = []; + this.onPlay(this.playTogglesOnPlay); + this.onPause(this.playTogglesOnPause); + } + this.elements.playToggles.push(element); + _V_.addListener(element, "click", this.onPlayToggleClick.context(this)); + },{ + onPlayToggleClick: function(event){ + if (this.paused()) { + this.play(); + } else { + this.pause(); + } + }, + playTogglesOnPlay: function(event){ + this.each(this.elements.playToggles, function(toggle){ + _V_.removeClass(toggle, "vjs-paused"); + _V_.addClass(toggle, "vjs-playing"); + }); + }, + playTogglesOnPause: function(event){ + this.each(this.elements.playToggles, function(toggle){ + _V_.removeClass(toggle, "vjs-playing"); + _V_.addClass(toggle, "vjs-paused"); + }); + } + } +); +// Play +VideoJS.player.newBehavior("playButton", function(element){ + _V_.addListener(element, "click", this.onPlayButtonClick.context(this)); + },{ + onPlayButtonClick: function(event){ this.play(); } + } +); +// Pause +VideoJS.player.newBehavior("pauseButton", function(element){ + _V_.addListener(element, "click", this.onPauseButtonClick.context(this)); + },{ + onPauseButtonClick: function(event){ this.pause(); } + } +); +/* Play Progress Bar Behaviors +================================================================================ */ +VideoJS.player.newBehavior("playProgressBar", function(element){ + if (!this.playProgressBars) { + this.playProgressBars = []; + this.onCurrentTimeUpdate(this.updatePlayProgressBars); + } + this.playProgressBars.push(element); + },{ + // Ajust the play progress bar's width based on the current play time + updatePlayProgressBars: function(newTime){ + var progress = (newTime !== undefined) ? newTime / this.duration() : this.currentTime() / this.duration(); + if (isNaN(progress)) { progress = 0; } + this.each(this.playProgressBars, function(bar){ + if (bar.style) { bar.style.width = _V_.round(progress * 100, 2) + "%"; } + }); + } + } +); +/* Load Progress Bar Behaviors +================================================================================ */ +VideoJS.player.newBehavior("loadProgressBar", function(element){ + if (!this.loadProgressBars) { this.loadProgressBars = []; } + this.loadProgressBars.push(element); + this.onBufferedUpdate(this.updateLoadProgressBars); + },{ + updateLoadProgressBars: function(){ + this.each(this.loadProgressBars, function(bar){ + if (bar.style) { bar.style.width = _V_.round(this.bufferedPercent() * 100, 2) + "%"; } + }); + } + } +); + +/* Current Time Display Behaviors +================================================================================ */ +VideoJS.player.newBehavior("currentTimeDisplay", function(element){ + if (!this.currentTimeDisplays) { + this.currentTimeDisplays = []; + this.onCurrentTimeUpdate(this.updateCurrentTimeDisplays); + } + this.currentTimeDisplays.push(element); + },{ + // Update the displayed time (00:00) + updateCurrentTimeDisplays: function(newTime){ + if (!this.currentTimeDisplays) { return; } + // Allows for smooth scrubbing, when player can't keep up. + var time = (newTime) ? newTime : this.currentTime(); + this.each(this.currentTimeDisplays, function(dis){ + dis.innerHTML = _V_.formatTime(time); + }); + } + } +); + +/* Duration Display Behaviors +================================================================================ */ +VideoJS.player.newBehavior("durationDisplay", function(element){ + if (!this.durationDisplays) { + this.durationDisplays = []; + this.onCurrentTimeUpdate(this.updateDurationDisplays); + } + this.durationDisplays.push(element); + },{ + updateDurationDisplays: function(){ + if (!this.durationDisplays) { return; } + this.each(this.durationDisplays, function(dis){ + if (this.duration()) { dis.innerHTML = _V_.formatTime(this.duration()); } + }); + } + } +); + +/* Current Time Scrubber Behaviors +================================================================================ */ +VideoJS.player.newBehavior("currentTimeScrubber", function(element){ + _V_.addListener(element, "mousedown", this.onCurrentTimeScrubberMouseDown.rEvtContext(this)); + },{ + // Adjust the play position when the user drags on the progress bar + onCurrentTimeScrubberMouseDown: function(event, scrubber){ + event.preventDefault(); + this.currentScrubber = scrubber; + + this.stopTrackingCurrentTime(); // Allows for smooth scrubbing + + this.videoWasPlaying = !this.paused(); + this.pause(); + + _V_.blockTextSelection(); + this.setCurrentTimeWithScrubber(event); + _V_.addListener(document, "mousemove", this.onCurrentTimeScrubberMouseMove.rEvtContext(this)); + _V_.addListener(document, "mouseup", this.onCurrentTimeScrubberMouseUp.rEvtContext(this)); + }, + onCurrentTimeScrubberMouseMove: function(event){ // Removeable + this.setCurrentTimeWithScrubber(event); + }, + onCurrentTimeScrubberMouseUp: function(event){ // Removeable + _V_.unblockTextSelection(); + document.removeEventListener("mousemove", this.onCurrentTimeScrubberMouseMove, false); + document.removeEventListener("mouseup", this.onCurrentTimeScrubberMouseUp, false); + if (this.videoWasPlaying) { + this.play(); + this.trackCurrentTime(); + } + }, + setCurrentTimeWithScrubber: function(event){ + var newProgress = _V_.getRelativePosition(event.pageX, this.currentScrubber); + var newTime = newProgress * this.duration(); + this.triggerCurrentTimeListeners(0, newTime); // Allows for smooth scrubbing + // Don't let video end while scrubbing. + if (newTime == this.duration()) { newTime = newTime - 0.1; } + this.currentTime(newTime); + } + } +); +/* Volume Display Behaviors +================================================================================ */ +VideoJS.player.newBehavior("volumeDisplay", function(element){ + if (!this.volumeDisplays) { + this.volumeDisplays = []; + this.onVolumeChange(this.updateVolumeDisplays); + } + this.volumeDisplays.push(element); + this.updateVolumeDisplay(element); // Set the display to the initial volume + },{ + // Update the volume control display + // Unique to these default controls. Uses borders to create the look of bars. + updateVolumeDisplays: function(){ + if (!this.volumeDisplays) { return; } + this.each(this.volumeDisplays, function(dis){ + this.updateVolumeDisplay(dis); + }); + }, + updateVolumeDisplay: function(display){ + var volNum = Math.ceil(this.volume() * 6); + this.each(display.children, function(child, num){ + if (num < volNum) { + _V_.addClass(child, "vjs-volume-level-on"); + } else { + _V_.removeClass(child, "vjs-volume-level-on"); + } + }); + } + } +); +/* Volume Scrubber Behaviors +================================================================================ */ +VideoJS.player.newBehavior("volumeScrubber", function(element){ + _V_.addListener(element, "mousedown", this.onVolumeScrubberMouseDown.rEvtContext(this)); + },{ + // Adjust the volume when the user drags on the volume control + onVolumeScrubberMouseDown: function(event, scrubber){ + // event.preventDefault(); + _V_.blockTextSelection(); + this.currentScrubber = scrubber; + this.setVolumeWithScrubber(event); + _V_.addListener(document, "mousemove", this.onVolumeScrubberMouseMove.rEvtContext(this)); + _V_.addListener(document, "mouseup", this.onVolumeScrubberMouseUp.rEvtContext(this)); + }, + onVolumeScrubberMouseMove: function(event){ + this.setVolumeWithScrubber(event); + }, + onVolumeScrubberMouseUp: function(event){ + this.setVolumeWithScrubber(event); + _V_.unblockTextSelection(); + document.removeEventListener("mousemove", this.onVolumeScrubberMouseMove, false); + document.removeEventListener("mouseup", this.onVolumeScrubberMouseUp, false); + }, + setVolumeWithScrubber: function(event){ + var newVol = _V_.getRelativePosition(event.pageX, this.currentScrubber); + this.volume(newVol); + } + } +); +/* Fullscreen Toggle Behaviors +================================================================================ */ +VideoJS.player.newBehavior("fullscreenToggle", function(element){ + _V_.addListener(element, "click", this.onFullscreenToggleClick.context(this)); + },{ + // When the user clicks on the fullscreen button, update fullscreen setting + onFullscreenToggleClick: function(event){ + if (!this.videoIsFullScreen) { + this.enterFullScreen(); + } else { + this.exitFullScreen(); + } + }, + + fullscreenOnWindowResize: function(event){ // Removeable + this.positionControlBars(); + }, + // Create listener for esc key while in full screen mode + fullscreenOnEscKey: function(event){ // Removeable + if (event.keyCode == 27) { + this.exitFullScreen(); + } + } + } +); +/* Big Play Button Behaviors +================================================================================ */ +VideoJS.player.newBehavior("bigPlayButton", function(element){ + if (!this.elements.bigPlayButtons) { + this.elements.bigPlayButtons = []; + this.onPlay(this.bigPlayButtonsOnPlay); + this.onEnded(this.bigPlayButtonsOnEnded); + } + this.elements.bigPlayButtons.push(element); + this.activateElement(element, "playButton"); + },{ + bigPlayButtonsOnPlay: function(event){ this.hideBigPlayButtons(); }, + bigPlayButtonsOnEnded: function(event){ this.showBigPlayButtons(); }, + showBigPlayButtons: function(){ + this.each(this.elements.bigPlayButtons, function(element){ + element.style.display = "block"; + }); + }, + hideBigPlayButtons: function(){ + this.each(this.elements.bigPlayButtons, function(element){ + element.style.display = "none"; + }); + } + } +); +/* Spinner +================================================================================ */ +VideoJS.player.newBehavior("spinner", function(element){ + if (!this.spinners) { + this.spinners = []; + _V_.addListener(this.video, "loadeddata", this.spinnersOnVideoLoadedData.context(this)); + _V_.addListener(this.video, "loadstart", this.spinnersOnVideoLoadStart.context(this)); + _V_.addListener(this.video, "seeking", this.spinnersOnVideoSeeking.context(this)); + _V_.addListener(this.video, "seeked", this.spinnersOnVideoSeeked.context(this)); + _V_.addListener(this.video, "canplay", this.spinnersOnVideoCanPlay.context(this)); + _V_.addListener(this.video, "canplaythrough", this.spinnersOnVideoCanPlayThrough.context(this)); + _V_.addListener(this.video, "waiting", this.spinnersOnVideoWaiting.context(this)); + _V_.addListener(this.video, "stalled", this.spinnersOnVideoStalled.context(this)); + _V_.addListener(this.video, "suspend", this.spinnersOnVideoSuspend.context(this)); + _V_.addListener(this.video, "playing", this.spinnersOnVideoPlaying.context(this)); + _V_.addListener(this.video, "timeupdate", this.spinnersOnVideoTimeUpdate.context(this)); + } + this.spinners.push(element); + },{ + showSpinners: function(){ + this.each(this.spinners, function(spinner){ + spinner.style.display = "block"; + }); + clearInterval(this.spinnerInterval); + this.spinnerInterval = setInterval(this.rotateSpinners.context(this), 100); + }, + hideSpinners: function(){ + this.each(this.spinners, function(spinner){ + spinner.style.display = "none"; + }); + clearInterval(this.spinnerInterval); + }, + spinnersRotated: 0, + rotateSpinners: function(){ + this.each(this.spinners, function(spinner){ + // spinner.style.transform = 'scale(0.5) rotate('+this.spinnersRotated+'deg)'; + spinner.style.WebkitTransform = 'scale(0.5) rotate('+this.spinnersRotated+'deg)'; + spinner.style.MozTransform = 'scale(0.5) rotate('+this.spinnersRotated+'deg)'; + }); + if (this.spinnersRotated == 360) { this.spinnersRotated = 0; } + this.spinnersRotated += 45; + }, + spinnersOnVideoLoadedData: function(event){ this.hideSpinners(); }, + spinnersOnVideoLoadStart: function(event){ this.showSpinners(); }, + spinnersOnVideoSeeking: function(event){ /* this.showSpinners(); */ }, + spinnersOnVideoSeeked: function(event){ /* this.hideSpinners(); */ }, + spinnersOnVideoCanPlay: function(event){ /* this.hideSpinners(); */ }, + spinnersOnVideoCanPlayThrough: function(event){ this.hideSpinners(); }, + spinnersOnVideoWaiting: function(event){ + // Safari sometimes triggers waiting inappropriately + // Like after video has played, any you play again. + this.showSpinners(); + }, + spinnersOnVideoStalled: function(event){}, + spinnersOnVideoSuspend: function(event){}, + spinnersOnVideoPlaying: function(event){ this.hideSpinners(); }, + spinnersOnVideoTimeUpdate: function(event){ + // Safari sometimes calls waiting and doesn't recover + if(this.spinner.style.display == "block") { this.hideSpinners(); } + } + } +); +/* Subtitles +================================================================================ */ +VideoJS.player.newBehavior("subtitlesDisplay", function(element){ + if (!this.subtitleDisplays) { + this.subtitleDisplays = []; + this.onCurrentTimeUpdate(this.subtitleDisplaysOnVideoTimeUpdate); + this.onEnded(function() { this.lastSubtitleIndex = 0; }.context(this)); + } + this.subtitleDisplays.push(element); + },{ + subtitleDisplaysOnVideoTimeUpdate: function(time){ + // Assuming all subtitles are in order by time, and do not overlap + if (this.subtitles) { + // If current subtitle should stay showing, don't do anything. Otherwise, find new subtitle. + if (!this.currentSubtitle || this.currentSubtitle.start >= time || this.currentSubtitle.end < time) { + var newSubIndex = false, + // Loop in reverse if lastSubtitle is after current time (optimization) + // Meaning the user is scrubbing in reverse or rewinding + reverse = (this.subtitles[this.lastSubtitleIndex].start > time), + // If reverse, step back 1 becase we know it's not the lastSubtitle + i = this.lastSubtitleIndex - (reverse) ? 1 : 0; + while (true) { // Loop until broken + if (reverse) { // Looping in reverse + // Stop if no more, or this subtitle ends before the current time (no earlier subtitles should apply) + if (i < 0 || this.subtitles[i].end < time) { break; } + // End is greater than time, so if start is less, show this subtitle + if (this.subtitles[i].start < time) { + newSubIndex = i; + break; + } + i--; + } else { // Looping forward + // Stop if no more, or this subtitle starts after time (no later subtitles should apply) + if (i >= this.subtitles.length || this.subtitles[i].start > time) { break; } + // Start is less than time, so if end is later, show this subtitle + if (this.subtitles[i].end > time) { + newSubIndex = i; + break; + } + i++; + } + } + + // Set or clear current subtitle + if (newSubIndex !== false) { + this.currentSubtitle = this.subtitles[newSubIndex]; + this.lastSubtitleIndex = newSubIndex; + this.updateSubtitleDisplays(this.currentSubtitle.text); + } else if (this.currentSubtitle) { + this.currentSubtitle = false; + this.updateSubtitleDisplays(""); + } + } + } + }, + updateSubtitleDisplays: function(val){ + this.each(this.subtitleDisplays, function(disp){ + disp.innerHTML = val; + }); + } + } +); + +//////////////////////////////////////////////////////////////////////////////// +// Convenience Functions (mini library) +// Functions not specific to video or VideoJS and could probably be replaced with a library like jQuery +//////////////////////////////////////////////////////////////////////////////// + +VideoJS.extend({ + + addClass: function(element, classToAdd){ + if ((" "+element.className+" ").indexOf(" "+classToAdd+" ") == -1) { + element.className = element.className === "" ? classToAdd : element.className + " " + classToAdd; + } + }, + removeClass: function(element, classToRemove){ + if (element.className.indexOf(classToRemove) == -1) { return; } + var classNames = element.className.split(/\s+/); + classNames.splice(classNames.lastIndexOf(classToRemove),1); + element.className = classNames.join(" "); + }, + createElement: function(tagName, attributes){ + return this.merge(document.createElement(tagName), attributes); + }, + + // Attempt to block the ability to select text while dragging controls + blockTextSelection: function(){ + document.body.focus(); + document.onselectstart = function () { return false; }; + }, + // Turn off text selection blocking + unblockTextSelection: function(){ document.onselectstart = function () { return true; }; }, + + // Return seconds as MM:SS + formatTime: function(secs) { + var seconds = Math.round(secs); + var minutes = Math.floor(seconds / 60); + minutes = (minutes >= 10) ? minutes : "0" + minutes; + seconds = Math.floor(seconds % 60); + seconds = (seconds >= 10) ? seconds : "0" + seconds; + return minutes + ":" + seconds; + }, + + // Return the relative horizonal position of an event as a value from 0-1 + getRelativePosition: function(x, relativeElement){ + return Math.max(0, Math.min(1, (x - this.findPosX(relativeElement)) / relativeElement.offsetWidth)); + }, + // Get an objects position on the page + findPosX: function(obj) { + var curleft = obj.offsetLeft; + while(obj = obj.offsetParent) { + curleft += obj.offsetLeft; + } + return curleft; + }, + getComputedStyleValue: function(element, style){ + return window.getComputedStyle(element, null).getPropertyValue(style); + }, + + round: function(num, dec) { + if (!dec) { dec = 0; } + return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec); + }, + + addListener: function(element, type, handler){ + if (element.addEventListener) { + element.addEventListener(type, handler, false); + } else if (element.attachEvent) { + element.attachEvent("on"+type, handler); + } + }, + removeListener: function(element, type, handler){ + if (element.removeEventListener) { + element.removeEventListener(type, handler, false); + } else if (element.attachEvent) { + element.detachEvent("on"+type, handler); + } + }, + + get: function(url, onSuccess){ + if (typeof XMLHttpRequest == "undefined") { + XMLHttpRequest = function () { + try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e) {} + try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (f) {} + try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (g) {} + //Microsoft.XMLHTTP points to Msxml2.XMLHTTP.3.0 and is redundant + throw new Error("This browser does not support XMLHttpRequest."); + }; + } + var request = new XMLHttpRequest(); + request.open("GET",url); + request.onreadystatechange = function() { + if (request.readyState == 4 && request.status == 200) { + onSuccess(request.responseText); + } + }.context(this); + request.send(); + }, + + trim: function(string){ return string.toString().replace(/^\s+/, "").replace(/\s+$/, ""); }, + + // DOM Ready functionality adapted from jQuery. http://jquery.com/ + bindDOMReady: function(){ + if (document.readyState === "complete") { + return VideoJS.onDOMReady(); + } + if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", VideoJS.DOMContentLoaded, false); + window.addEventListener("load", VideoJS.onDOMReady, false); + } else if (document.attachEvent) { + document.attachEvent("onreadystatechange", VideoJS.DOMContentLoaded); + window.attachEvent("onload", VideoJS.onDOMReady); + } + }, + + DOMContentLoaded: function(){ + if (document.addEventListener) { + document.removeEventListener( "DOMContentLoaded", VideoJS.DOMContentLoaded, false); + VideoJS.onDOMReady(); + } else if ( document.attachEvent ) { + if ( document.readyState === "complete" ) { + document.detachEvent("onreadystatechange", VideoJS.DOMContentLoaded); + VideoJS.onDOMReady(); + } + } + }, + + // Functions to be run once the DOM is loaded + DOMReadyList: [], + addToDOMReady: function(fn){ + if (VideoJS.DOMIsReady) { + fn.call(document); + } else { + VideoJS.DOMReadyList.push(fn); + } + }, + + DOMIsReady: false, + onDOMReady: function(){ + if (VideoJS.DOMIsReady) { return; } + if (!document.body) { return setTimeout(VideoJS.onDOMReady, 13); } + VideoJS.DOMIsReady = true; + if (VideoJS.DOMReadyList) { + for (var i=0; i Hi, The optLevel was not passed to "XCoreDAGToDAGISel" making the related passes to run always with the llvm default level of optimization. This patch fixes that. Kyriakos Georgiou | XMOS www.xmos.com -------------- next part -------------- A non-text attachment was scrubbed... Name: PassOptLevelToXCoreDAGToDAGISel.diff Type: text/x-patch Size: 2732 bytes Desc: PassOptLevelToXCoreDAGToDAGISel.diff Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20111213/1cdac022/attachment.bin From hfinkel at anl.gov Tue Dec 13 10:22:49 2011 From: hfinkel at anl.gov (Hal Finkel) Date: Tue, 13 Dec 2011 10:22:49 -0600 Subject: [llvm-commits] [LLVMdev] Turning on/off instruction extensions In-Reply-To: <4EE73E6E.4030603@die.upm.es> References: <1322145210.2507.451.camel@sapling> <5D288300-8F23-4E9B-8846-57A88BF061F3@die.upm.es> <1322502723.2507.790.camel@sapling> <1322581121.2507.1184.camel@sapling> <1322856408.2507.2956.camel@sapling> <4EE5ECB7.4070300@die.upm.es> <1323706071.590.381.camel@sapling> <4EE73E6E.4030603@die.upm.es> Message-ID: <1323793369.590.1136.camel@sapling> On Tue, 2011-12-13 at 13:00 +0100, Pablo Barrio wrote: > On 12/12/11 17:07, Hal Finkel wrote: > > On Mon, 2011-12-12 at 12:59 +0100, Pablo Barrio wrote: > >> > >> I'm still getting the following error: > >> > >> --- > >> 1 out of 3 hunks FAILED -- saving rejects to file > >> lib/Transforms/IPO/PassManagerBuilder.cpp.rej > >> --- > >> > >> I'm using LLVM rev. 146369 (current trunk). Is it the same as you? If > >> not, tell me your revision and I'll try again. > > LLVM develops quickly ;) -- The patch you have is again out of sync. > > I'll send an updated patch to the list soon. > > Great! I'll wait for the new patch. Thanks for the help! > > One more question: I'm currently using dragonegg for autovectorization, > but I cannot get any vector longer than 4 elements for floats and 2 for > doubles. I suspect this is because my processor doesn't support bigger > vectors. However, I would like to generate bigger vectors into the LLVM > IR, and then decide what to do with them in the backend. Can your > vectorizer do something like that? Yes, just pass the flag: -bb-vectorize-vector-bits=256 (or whatever). It will then try to generate vectors *up to* that size (could be smaller, but not larger). -Hal > > Thanks, > Pablo > > >> Suggestion: would it be possible to have a patch for the stable version > >> (LLVM 3.0)? > > I'll add that to my TODO list, but I probably won't get to it until > > after the current patch finishes code review. I'll worry about > > backporting after that. > > > > -Hal > > > >> Thanks ahead, > >> Pablo > > -- Hal Finkel Postdoctoral Appointee Leadership Computing Facility Argonne National Laboratory From tonic at nondot.org Tue Dec 13 10:19:46 2011 From: tonic at nondot.org (Tanya Lattner) Date: Tue, 13 Dec 2011 16:19:46 -0000 Subject: [llvm-commits] [www] r146489 - /www/trunk/demo/index.cgi Message-ID: <20111213161946.44AF32A6C12C@llvm.org> Author: tbrethou Date: Tue Dec 13 10:19:45 2011 New Revision: 146489 URL: http://llvm.org/viewvc/llvm-project?rev=146489&view=rev Log: Upgrade to 3.0 Modified: www/trunk/demo/index.cgi Modified: www/trunk/demo/index.cgi URL: http://llvm.org/viewvc/llvm-project/www/trunk/demo/index.cgi?rev=146489&r1=146488&r2=146489&view=diff ============================================================================== --- www/trunk/demo/index.cgi (original) +++ www/trunk/demo/index.cgi Tue Dec 13 10:19:45 2011 @@ -131,7 +131,7 @@
- Try out LLVM and Clang 2.9 in your browser! + Try out LLVM and Clang 3.0 in your browser!
@@ -146,7 +146,7 @@ - -
From tonic at nondot.org Tue Dec 13 10:22:23 2011 From: tonic at nondot.org (Tanya Lattner) Date: Tue, 13 Dec 2011 16:22:23 -0000 Subject: [llvm-commits] [www] r146490 - /www/trunk/devmtg/2011-11/index.html Message-ID: <20111213162223.C56D42A6C12C@llvm.org> Author: tbrethou Date: Tue Dec 13 10:22:23 2011 New Revision: 146490 URL: http://llvm.org/viewvc/llvm-project?rev=146490&view=rev Log: Fix some messed up links. Modified: www/trunk/devmtg/2011-11/index.html Modified: www/trunk/devmtg/2011-11/index.html URL: http://llvm.org/viewvc/llvm-project/www/trunk/devmtg/2011-11/index.html?rev=146490&r1=146489&r2=146490&view=diff ============================================================================== --- www/trunk/devmtg/2011-11/index.html (original) +++ www/trunk/devmtg/2011-11/index.html Tue Dec 13 10:22:23 2011 @@ -125,7 +125,7 @@
[Slides] -

[Video] (Computer) +

[Video] (Computer)
[Video] (Mobile)

Android Renderscript
Stephen Hines, Google
Register Allocation in LLVM 3.0
Jakob Olesen, Apple
[Slides] (PDF) +
[Slides] (PDF)
[Slides] (HTML)

[Video] (Computer)
[Video] (Mobile)

From tonic at nondot.org Tue Dec 13 10:25:47 2011 From: tonic at nondot.org (Tanya Lattner) Date: Tue, 13 Dec 2011 16:25:47 -0000 Subject: [llvm-commits] [www] r146491 - /www/trunk/devmtg/2011-11/index.html Message-ID: <20111213162547.B2C032A6C12C@llvm.org> Author: tbrethou Date: Tue Dec 13 10:25:47 2011 New Revision: 146491 URL: http://llvm.org/viewvc/llvm-project?rev=146491&view=rev Log: really fix the link. Modified: www/trunk/devmtg/2011-11/index.html Modified: www/trunk/devmtg/2011-11/index.html URL: http://llvm.org/viewvc/llvm-project/www/trunk/devmtg/2011-11/index.html?rev=146491&r1=146490&r2=146491&view=diff ============================================================================== --- www/trunk/devmtg/2011-11/index.html (original) +++ www/trunk/devmtg/2011-11/index.html Tue Dec 13 10:25:47 2011 @@ -146,7 +146,7 @@
Register Allocation in LLVM 3.0
Jakob Olesen, Apple
[Slides] (PDF) +
[Slides] (PDF)
[Slides] (HTML)

[Video] (Computer)
[Video] (Mobile)

From mcrosier at apple.com Tue Dec 13 11:45:06 2011 From: mcrosier at apple.com (Chad Rosier) Date: Tue, 13 Dec 2011 17:45:06 -0000 Subject: [llvm-commits] [llvm] r146492 - /llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Message-ID: <20111213174506.EE27A2A6C12C@llvm.org> Author: mcrosier Date: Tue Dec 13 11:45:06 2011 New Revision: 146492 URL: http://llvm.org/viewvc/llvm-project?rev=146492&view=rev Log: [fast-isel] Remove SelectInsertValue() as fast-isel wasn't designed to handle instructions that define aggregate types. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=146492&r1=146491&r2=146492&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Tue Dec 13 11:45:06 2011 @@ -942,106 +942,6 @@ } bool -FastISel::SelectInsertValue(const User *U) { - return false; - const InsertValueInst *IVI = dyn_cast(U); - if (!IVI) - return false; - - // Only try to handle inserts of legal types. But also allow i16/i8/i1 because - // they're easy. - const Value *Val = IVI->getOperand(1); - Type *ValTy = Val->getType(); - EVT ValVT = TLI.getValueType(ValTy, /*AllowUnknown=*/true); - if (!ValVT.isSimple()) - return false; - MVT VT = ValVT.getSimpleVT(); - if (!TLI.isTypeLegal(VT) && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1) - return false; - - // Get the Val register. - unsigned ValReg = getRegForValue(Val); - if (ValReg == 0) return false; - - const Value *Agg = IVI->getOperand(0); - Type *AggTy = Agg->getType(); - - // TODO: Is there a better way to do this? For each insertvalue we allocate - // a new set of virtual registers, which results in a large number of - // loads/stores from/to the stack that copies the aggregate all over the place - // and results in lots of spill code. I believe this is necessary to preserve - // SSA form, but maybe there's something we could do to improve this. - - // Get the Aggregate base register. - unsigned AggBaseReg; - DenseMap::iterator I = FuncInfo.ValueMap.find(Agg); - if (I != FuncInfo.ValueMap.end()) - AggBaseReg = I->second; - else if (isa(Agg)) - AggBaseReg = FuncInfo.InitializeRegForValue(Agg); - else if (isa(Agg)) - // In this case we don't need to allocate a new set of register that will - // never be defined. Just copy Val into the proper result registers. - AggBaseReg = 0; - else - return false; // fast-isel can't handle aggregate constants at the moment - - // Create result register(s). - unsigned ResultBaseReg = FuncInfo.CreateRegs(AggTy); - - // Get the actual result register, which is an offset from the base register. - unsigned LinearIndex = ComputeLinearIndex(Agg->getType(), IVI->getIndices()); - - SmallVector AggValueVTs; - ComputeValueVTs(TLI, AggTy, AggValueVTs); - - // Copy the beginning value(s) from the original aggregate. - unsigned SrcReg; - unsigned DestReg; - unsigned BaseRegOff = 0; - unsigned i = 0; - for (; i != LinearIndex; ++i) { - unsigned NRE = TLI.getNumRegisters(FuncInfo.Fn->getContext(), - AggValueVTs[i]); - for (unsigned NRI = 0; NRI != NRE; NRI++) { - if (AggBaseReg) { - SrcReg = AggBaseReg + BaseRegOff + NRI; - DestReg = ResultBaseReg + BaseRegOff + NRI; - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), - DestReg).addReg(SrcReg); - } - } - BaseRegOff += NRE; - } - - // FIXME: Handle aggregate inserts. Haven't seen these in practice, but.. - // Copy value(s) from the inserted value(s). - DestReg = ResultBaseReg + BaseRegOff; - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), - DestReg).addReg(ValReg); - ++BaseRegOff; - ++i; - - // Copy remaining value(s) from the original aggregate. - if (AggBaseReg) { - for (unsigned NumAggValues = AggValueVTs.size(); i != NumAggValues; ++i) { - unsigned NRE = TLI.getNumRegisters(FuncInfo.Fn->getContext(), - AggValueVTs[i]); - for (unsigned NRI = 0; NRI != NRE; NRI++) { - SrcReg = AggBaseReg + BaseRegOff + NRI; - DestReg = ResultBaseReg + BaseRegOff + NRI; - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), - DestReg).addReg(SrcReg); - - } - BaseRegOff += NRE; - } - } - UpdateValueMap(IVI, ResultBaseReg); - return true; -} - -bool FastISel::SelectOperator(const User *I, unsigned Opcode) { switch (Opcode) { case Instruction::Add: @@ -1148,9 +1048,6 @@ case Instruction::ExtractValue: return SelectExtractValue(I); - case Instruction::InsertValue: - return SelectInsertValue(I); - case Instruction::PHI: llvm_unreachable("FastISel shouldn't visit PHI nodes!"); From Erik.Olofsson at hansoft.se Tue Dec 13 11:56:49 2011 From: Erik.Olofsson at hansoft.se (Erik Olofsson) Date: Tue, 13 Dec 2011 17:56:49 +0000 Subject: [llvm-commits] PATCH: Enable direct selection of bsf and bsr instructions for cttz and ctlz with zero-undef behavior In-Reply-To: References: Message-ID: Just a note, BSR/BSF might have some performance implications depending on which CPU is running the code. See http://www.realworldtech.com/beta/forums/index.cfm?action=detail&id=82507&threadid=82344&roomid=2 It would probably be safest to just use lzcnt/tzcnt when available unless you know which CPU you are optimizing for. Regards, Erik On 2011-12-13, at 13:31 , Chandler Carruth wrote: This just enables the necessary patterns for x86. I really know nothing about the tablegen-backed patterns, so please review and be gentle. =] There is still quite a bit of work to be done on the zero-undef front. We need to teach the entire middle end about this behavior and have it transform both to and from the zero-undef variants based on conditions and known bits of the operand. I've updated the test to demonstrate that no more cmov instructions are generated for the common case, but we still generate them when required by the instruction semantics unless there are trivially bits set in the operand. This also doesn't teach the x86 backend to prefer bsf and bsr when they are sufficient even though lzcnt and tzcnt are available. That behavior would be beneficial as bsf and bsr encode more compactly. If someone can shed light on how to do this, that would really help. I'm completely out of my depth in the actual target pattern magic of TableGen. =] _______________________________________________ llvm-commits mailing list llvm-commits at cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20111213/656747ce/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: fix-cttz-x86-patterns.patch Type: text/x-patch Size: 4336 bytes Desc: fix-cttz-x86-patterns.patch Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20111213/656747ce/attachment.bin From sabre at nondot.org Tue Dec 13 11:55:30 2011 From: sabre at nondot.org (Chris Lattner) Date: Tue, 13 Dec 2011 17:55:30 -0000 Subject: [llvm-commits] [llvm] r146493 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <20111213175531.0AF662A6C12C@llvm.org> Author: lattner Date: Tue Dec 13 11:55:30 2011 New Revision: 146493 URL: http://llvm.org/viewvc/llvm-project?rev=146493&view=rev Log: Rip llvm 3.0 out of the release notes, making room for LLVM 3.1 Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=146493&r1=146492&r2=146493&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Tue Dec 13 11:55:30 2011 @@ -4,11 +4,11 @@ - LLVM 3.0 Release Notes + LLVM 3.1 Release Notes -

LLVM 3.0 Release Notes

+

LLVM 3.1 Release Notes

-

@@ -46,7 +44,7 @@

This document contains the release notes for the LLVM Compiler - Infrastructure, release 3.0. Here we describe the status of LLVM, including + Infrastructure, release 3.1. Here we describe the status of LLVM, including major improvements from the previous release, improvements in various subprojects of LLVM, and some of the current users of the code. All LLVM releases may be downloaded from @@ -74,7 +72,7 @@

-

The LLVM 3.0 distribution currently consists of code from the core LLVM +

The LLVM 3.1 distribution currently consists of code from the core LLVM repository (which roughly includes the LLVM optimizers, code generators and supporting tools), and the Clang repository. In addition to this code, the LLVM Project includes other sub-projects that are @@ -96,49 +94,12 @@ production-quality compiler for C, Objective-C, C++ and Objective-C++ on x86 (32- and 64-bit), and for Darwin/ARM targets.

-

In the LLVM 3.0 time-frame, the Clang team has made many improvements:

+

In the LLVM 3.1 time-frame, the Clang team has made many improvements:

    -
  • Greatly improved support for building C++ applications, with greater - stability and better diagnostics.
  • - -
  • Improved support for - the C++ - 2011 standard (aka "C++'0x"), including implementations of non-static data member - initializers, alias templates, delegating constructors, range-based - for loops, and implicitly-generated move constructors and move assignment - operators, among others.
  • - -
  • Implemented support for some features of the upcoming C1x standard, - including static assertions and generic selections.
  • - -
  • Better detection of include and linking paths for system headers and - libraries, especially for Linux distributions.
  • - -
  • Several improvements to Objective-C support, including: - -
      -
    • - Automatic Reference Counting (ARC) and an improved memory model - cleanly separating object and C memory.
    • - -
    • A migration tool for moving manual retain/release code to ARC
    • - -
    • Better support for data hiding, allowing instance variables to be - declared in implementation contexts or class extensions
    • -
    • Weak linking support for Objective-C classes
    • -
    • Improved static type checking by inferring the return type of methods - such as +alloc and -init.
    • -
    - - Some new Objective-C features require either the Mac OS X 10.7 / iOS 5 - Objective-C runtime, or version 1.6 or later of the GNUstep Objective-C - runtime version.
  • - -
  • Implemented a number of optimizations in libclang, the Clang C - interface, to improve the performance of code completion and the mapping - from source locations to abstract syntax tree nodes.
  • +
  • ...
-

For more details about the changes to Clang since the 2.9 release, see the + +

For more details about the changes to Clang since the 2.9 release, see the Clang release notes

@@ -164,24 +125,11 @@ supports Ada, C, C++ and Fortran. It has partial support for Go, Java, Obj-C and Obj-C++.

-

The 3.0 release has the following notable changes:

+

The 3.1 release has the following notable changes:

    -
  • GCC version 4.6 is now fully supported.
  • -
  • Patching and building GCC is no longer required: the plugin should work - with your system GCC (version 4.5 or 4.6; on Debian/Ubuntu systems the - gcc-4.5-plugin-dev or gcc-4.6-plugin-dev package is also needed).
  • - -
  • The -fplugin-arg-dragonegg-enable-gcc-optzns option, which runs - GCC's optimizers as well as LLVM's, now works much better. This is the - option to use if you want ultimate performance! It is still experimental - though: it may cause the plugin to crash. Setting the optimization level - to -O4 when using this option will optimize even harder, though - this usually doesn't result in any improvement over -O3.
  • - -
  • The type and constant conversion logic has been almost entirely rewritten, - fixing a multitude of obscure bugs.
  • +
  • ...
@@ -203,9 +151,7 @@ implementations of this and other low-level routines (some are 3x faster than the equivalent libgcc routines).

-

In the LLVM 3.0 timeframe, the target specific ARM code has converted to - "unified" assembly syntax, and several new functions have been added to the - library.

+

....

@@ -221,11 +167,7 @@ Clang parser to provide high-fidelity expression parsing (particularly for C++) and uses the LLVM JIT for target support.

-

LLDB has advanced by leaps and bounds in the 3.0 timeframe. It is - dramatically more stable and useful, and includes both a - new tutorial and - a side-by-side comparison with - GDB.

+

...

@@ -240,8 +182,7 @@ licensed under the MIT and UIUC license, allowing it to be used more permissively.

-

Libc++ has been ported to FreeBSD and imported into the base system. It is - planned to be the default STL implementation for FreeBSD 10.

+

...

@@ -256,71 +197,20 @@ implementation of a Java Virtual Machine (Java VM or JVM) that uses LLVM for static and just-in-time compilation. -

In the LLVM 3.0 time-frame, VMKit has had significant improvements on both +

In the LLVM 3.1 time-frame, VMKit has had significant improvements on both runtime and startup performance:

    -
  • Precompilation: by compiling ahead of time a small subset of Java's core - library, the startup performance have been highly optimized to the point that - running a 'Hello World' program takes less than 30 milliseconds.
  • - -
  • Customization: by customizing virtual methods for individual classes, - the VM can statically determine the target of a virtual call, and decide to - inline it.
  • - -
  • Inlining: the VM does more inlining than it did before, by allowing more - bytecode instructions to be inlined, and thanks to customization. It also - inlines GC barriers, and object allocations.
  • - -
  • New exception model: the generated code for a method that does not do - any try/catch is not penalized anymore by the eventuality of calling a - method that throws an exception. Instead, the method that throws the - exception jumps directly to the method that could catch it.
  • +
  • ...
- - -

-LLBrowse: IR Browser -

- -
- -

- LLBrowse is an interactive viewer for LLVM modules. It can load any LLVM - module and displays its contents as an expandable tree view, facilitating an - easy way to inspect types, functions, global variables, or metadata nodes. It - is fully cross-platform, being based on the popular wxWidgets GUI - toolkit.

- -
- - - - -

- External Open Source Projects Using LLVM 3.0 + External Open Source Projects Using LLVM 3.1

@@ -328,404 +218,15 @@

An exciting aspect of LLVM is that it is used as an enabling technology for a lot of other language and tools projects. This section lists some of the - projects that have already been updated to work with LLVM 3.0.

- - -

AddressSanitizer

- -
- -

AddressSanitizer - uses compiler instrumentation and a specialized malloc library to find C/C++ - bugs such as use-after-free and out-of-bound accesses to heap, stack, and - globals. The key feature of the tool is speed: the average slowdown - introduced by AddressSanitizer is less than 2x.

- -
- - -

ClamAV

- -
- -

Clam AntiVirus is an open source (GPL) - anti-virus toolkit for UNIX, designed especially for e-mail scanning on mail - gateways.

- -

Since version 0.96 it - has bytecode - signatures that allow writing detections for complex malware. - It uses LLVM's JIT to speed up the execution of bytecode on X86, X86-64, - PPC32/64, falling back to its own interpreter otherwise. The git version was - updated to work with LLVM 3.0.

- -
- - -

clang_complete for VIM

- -
- -

clang_complete is a - VIM plugin, that provides accurate C/C++ autocompletion using the clang front - end. The development version of clang complete, can directly use libclang - which can maintain a cache to speed up auto completion.

- -
- - -

clReflect

- -
- -

clReflect is a C++ - parser that uses clang/LLVM to derive a light-weight reflection database - suitable for use in game development. It comes with a very simple runtime - library for loading and querying the database, requiring no external - dependencies (including CRT), and an additional utility library for object - management and serialisation.

- -
- - -

Cling C++ Interpreter

- -
- -

Cling is an interactive compiler interface - (aka C++ interpreter). It supports C++ and C, and uses LLVM's JIT and the - Clang parser. It has a prompt interface, runs source files, calls into shared - libraries, prints the value of expressions, even does runtime lookup of - identifiers (dynamic scopes). And it just behaves like one would expect from - an interpreter.

- -
- - -

Crack Programming Language

- -
- -

Crack aims to provide - the ease of development of a scripting language with the performance of a - compiled language. The language derives concepts from C++, Java and Python, - incorporating object-oriented programming, operator overloading and strong - typing.

- -
- - -

Eero

- -
- -

Eero is a fully - header-and-binary-compatible dialect of Objective-C 2.0, implemented with a - patched version of the Clang/LLVM compiler. It features a streamlined syntax, - Python-like indentation, and new operators, for improved readability and - reduced code clutter. It also has new features such as limited forms of - operator overloading and namespaces, and strict (type-and-operator-safe) - enumerations. It is inspired by languages such as Smalltalk, Python, and - Ruby.

- -
- - -

FAUST Real-Time Audio Signal Processing Language

- -
- -

FAUST is a compiled language for - real-time audio signal processing. The name FAUST stands for Functional - AUdio STream. Its programming model combines two approaches: functional - programming and block diagram composition. In addition with the C, C++, Java - output formats, the Faust compiler can now generate LLVM bitcode, and works - with LLVM 2.7-3.0. -

- -
- - -

Glasgow Haskell Compiler (GHC)

- -
- -

GHC is an open source, state-of-the-art programming suite for Haskell, a - standard lazy functional programming language. It includes an optimizing - static compiler generating good code for a variety of platforms, together - with an interactive system for convenient, quick development.

- -

GHC 7.0 and onwards include an LLVM code generator, supporting LLVM 2.8 and - later. Since LLVM 2.9, GHC now includes experimental support for the ARM - platform with LLVM 3.0.

- -
- - -

gwXscript

- -
- -

gwXscript is an object oriented, - aspect oriented programming language which can create both executables (ELF, - EXE) and shared libraries (DLL, SO, DYNLIB). The compiler is implemented in - its own language and translates scripts into LLVM-IR which can be optimized - and translated into native code by the LLVM framework. Source code in - gwScript contains definitions that expand the namespaces. So you can build - your project and simply 'plug out' features by removing a file. The remaining - project does not leave scars since you directly separate concerns by the - 'template' feature of gwX. It is also possible to add new features to a - project by just adding files and without editing the original project. This - language is used for example to create games or content management systems - that should be extendable.

- -

gwXscript is strongly typed and offers comfort with its native types string, - hash and array. You can easily write new libraries in gwXscript or native - code. gwXscript is type safe and users should not be able to crash your - program or execute malicious code except code that is eating CPU time.

- -
- - -

include-what-you-use

- -
- -

include-what-you-use - is a tool to ensure that a file directly #includes - all .h files that provide a symbol that the file uses. It also - removes superfluous #includes from source files.

- -
- - -

ispc: The Intel SPMD Program Compiler

- -
- -

ispc is a compiler for "single program, - multiple data" (SPMD) programs. It compiles a C-based SPMD programming - language to run on the SIMD units of CPUs; it often delivers 5-6x speedups on - a single core of a CPU with an 8-wide SIMD unit compared to serial code, - while still providing a clean and easy-to-understand programming model. For - an introduction to the language and its performance, - see the walkthrough of a short - example program. ispc is licensed under the BSD license.

- -
- - -

The Julia Programming Language

- -
- -

Julia is a high-level, - high-performance dynamic language for technical - computing. It provides a sophisticated compiler, distributed parallel - execution, numerical accuracy, and an extensive mathematical function - library. The compiler uses type inference to generate fast code - without any type declarations, and uses LLVM's optimization passes and - JIT compiler. The language is designed around multiple dispatch, - giving programs a large degree of flexibility. It is ready for use on many - kinds of problems.

-
- - -

LanguageKit and Pragmatic Smalltalk

- -
- -

LanguageKit is - a framework for implementing dynamic languages sharing an object model with - Objective-C. It provides static and JIT compilation using LLVM along with - its own interpreter. Pragmatic Smalltalk is a dialect of Smalltalk, built on - top of LanguageKit, that interfaces directly with Objective-C, sharing the - same object representation and message sending behaviour. These projects are - developed as part of the Étoilé desktop environment.

- -
- - -

LuaAV

- -
- -

LuaAV is a real-time - audiovisual scripting environment based around the Lua language and a - collection of libraries for sound, graphics, and other media protocols. LuaAV - uses LLVM and Clang to JIT compile efficient user-defined audio synthesis - routines specified in a declarative syntax.

- -
+ projects that have already been updated to work with LLVM 3.1.

- -

Mono

- -
- -

An open source, cross-platform implementation of C# and the CLR that is - binary compatible with Microsoft.NET. Has an optional, dynamically-loaded - LLVM code generation backend in Mini, the JIT compiler.

- -

Note that we use a Git mirror of LLVM with some patches.

- -
- - -

Polly

- -
- -

Polly is an advanced data-locality - optimizer and automatic parallelizer. It uses an advanced, mathematical - model to calculate detailed data dependency information which it uses to - optimize the loop structure of a program. Polly can speed up sequential code - by improving memory locality and consequently the cache use. Furthermore, - Polly is able to expose different kind of parallelism which it exploits by - introducing (basic) OpenMP and SIMD code. A mid-term goal of Polly is to - automatically create optimized GPU code.

- -
- - -

Portable OpenCL (pocl)

- -
- -

Portable OpenCL is an open source implementation of the OpenCL standard which - can be easily adapted for new targets. One of the goals of the project is - improving performance portability of OpenCL programs, avoiding the need for - target-dependent manual optimizations. A "native" target is included, which - allows running OpenCL kernels on the host (CPU).

- -
- - -

Pure

- -
-

Pure is an - algebraic/functional programming language based on term rewriting. Programs - are collections of equations which are used to evaluate expressions in a - symbolic fashion. The interpreter uses LLVM as a backend to JIT-compile Pure - programs to fast native code. Pure offers dynamic typing, eager and lazy - evaluation, lexical closures, a hygienic macro system (also based on term - rewriting), built-in list and matrix support (including list and matrix - comprehensions) and an easy-to-use interface to C and other programming - languages (including the ability to load LLVM bitcode modules, and inline C, - C++, Fortran and Faust code in Pure programs if the corresponding LLVM-enabled - compilers are installed).

- -

Pure version 0.48 has been tested and is known to work with LLVM 3.0 - (and continues to work with older LLVM releases >= 2.5).

- -
- - -

Renderscript

- -
- -

Renderscript - is Android's advanced 3D graphics rendering and compute API. It provides a - portable C99-based language with extensions to facilitate common use cases - for enhancing graphics and thread level parallelism. The Renderscript - compiler frontend is based on Clang/LLVM. It emits a portable bitcode format - for the actual compiled script code, as well as reflects a Java interface for - developers to control the execution of the compiled bitcode. Executable - machine code is then generated from this bitcode by an LLVM backend on the - device. Renderscript is thus able to provide a mechanism by which Android - developers can improve performance of their applications while retaining - portability.

- -
- - -

SAFECode

- -
- -

SAFECode is a memory safe C/C++ - compiler built using LLVM. It takes standard, unannotated C/C++ code, - analyzes the code to ensure that memory accesses and array indexing - operations are safe, and instruments the code with run-time checks when - safety cannot be proven statically. SAFECode can be used as a debugging aid - (like Valgrind) to find and repair memory safety bugs. It can also be used - to protect code from security attacks at run-time.

- -
- - -

The Stupid D Compiler (SDC)

- -
- -

The Stupid D Compiler is a - project seeking to write a self-hosting compiler for the D programming - language without using the frontend of the reference compiler (DMD).

- -
- - -

TTA-based Co-design Environment (TCE)

- -
- -

TCE is a toolset for designing application-specific processors (ASP) based on - the Transport triggered architecture (TTA). The toolset provides a complete - co-design flow from C/C++ programs down to synthesizable VHDL and parallel - program binaries. Processor customization points include the register files, - function units, supported operations, and the interconnection network.

- -

TCE uses Clang and LLVM for C/C++ language support, target independent - optimizations and also for parts of code generation. It generates new - LLVM-based code generators "on the fly" for the designed TTA processors and - loads them in to the compiler backend as runtime libraries to avoid - per-target recompilation of larger parts of the compiler chain.

- -
- - -

Tart Programming Language

- -
- -

Tart is a general-purpose, - strongly typed programming language designed for application - developers. Strongly inspired by Python and C#, Tart focuses on practical - solutions for the professional software developer, while avoiding the clutter - and boilerplate of legacy languages like Java and C++. Although Tart is still - in development, the current implementation supports many features expected of - a modern programming language, such as garbage collection, powerful - bidirectional type inference, a greatly simplified syntax for template - metaprogramming, closures and function literals, reflection, operator - overloading, explicit mutability and immutability, and much more. Tart is - flexible enough to accommodate a broad range of programming styles and - philosophies, while maintaining a strong commitment to simplicity, minimalism - and elegance in design.

- -
- - -

ThreadSanitizer

- -
- -

ThreadSanitizer is a - data race detector for (mostly) C and C++ code, available for Linux, Mac OS - and Windows. On different systems, we use binary instrumentation frameworks - (Valgrind and Pin) as frontends that generate the program events for the race - detection algorithm. On Linux, there's an option of using LLVM-based - compile-time instrumentation.

- -
+ ... to be filled in right before the release ...

- What's New in LLVM 3.0? + What's New in LLVM 3.1?

@@ -759,49 +260,10 @@ llvm/lib/Archive - replace with lib object? --> -

LLVM 3.0 includes several major changes and big features:

+

LLVM 3.1 includes several major changes and big features:

    -
  • llvm-gcc is no longer supported, and not included in the release. We - recommend switching to Clang or DragonEgg.
  • - -
  • The linear scan register allocator has been replaced with a new "greedy" - register allocator, enabling live range splitting and many other - optimizations that lead to better code quality. Please see its blog post or its talk at the Developer Meeting - for more information.
  • -
  • LLVM IR now includes full support for atomics - memory operations intended to support the C++'11 and C'1x memory models. - This includes atomic load and store, - compare and exchange, and read/modify/write instructions as well as a - full set of memory ordering constraints. - Please see the Atomics Guide for more - information. -
  • -
  • The LLVM IR exception handling representation has been redesigned and - reimplemented, making it more elegant, fixing a huge number of bugs, and - enabling inlining and other optimizations. Please see its blog - post and the Exception Handling - documentation for more information.
  • -
  • The LLVM IR Type system has been redesigned and reimplemented, making it - faster and solving some long-standing problems. - Please see its blog - post for more information.
  • - -
  • The MIPS backend has made major leaps in this release, going from an - experimental target to being virtually production quality and supporting a - wide variety of MIPS subtargets. See the MIPS section - below for more information.
  • - -
  • The optimizer and code generator now supports gprof and gcov-style coverage - and profiling information, and includes a new llvm-cov tool (but also works - with gcov). Clang exposes coverage and profiling through GCC-compatible - command line options.
  • +
  • ....
@@ -818,27 +280,7 @@ expose new optimization opportunities:

@@ -854,35 +296,7 @@ optimizers:

    -
  • The pass manager now has an extension API that allows front-ends and plugins - to insert their own optimizations in the well-known places in the standard - pass optimization pipeline.
  • - -
  • Information about branch probability - and basic block frequency is now available within LLVM, based on a - combination of static branch prediction heuristics and - __builtin_expect calls. That information is currently used for - register spill placement and if-conversion, with additional optimizations - planned for future releases. The same framework is intended for eventual - use with profile-guided optimization.
  • - -
  • The "-indvars" induction variable simplification pass only modifies - induction variables when profitable. Sign and zero extension - elimination, linear function test replacement, loop unrolling, and - other simplifications that require induction variable analysis have - been generalized so they no longer require loops to be rewritten into - canonical form prior to optimization. This new design - preserves more IR level information, avoids undoing earlier loop - optimizations (particularly hand-optimized loops), and no longer - requires the code generator to reconstruct loops into an optimal form - - an intractable problem.
  • - -
  • LLVM now includes a pass to optimize retain/release calls for the - Automatic - Reference Counting (ARC) Objective-C language feature (in - lib/Transforms/Scalar/ObjCARC.cpp). It is a decent example of implementing - a source-language-specific optimization in LLVM.
  • - +
  • ....
@@ -902,30 +316,7 @@ to the LLVM MC Project Blog Post.

    -
  • The MC layer has undergone significant refactoring to eliminate layering - violations that caused it to pull in the LLVM compiler backend code.
  • -
  • The ELF object file writers are much more full featured.
  • -
  • The integrated assembler now supports #line directives.
  • -
  • An early implementation of a JIT built on top of the MC framework (known - as MC-JIT) has been implemented and will eventually replace the old JIT. - It emits object files direct to memory and uses a runtime dynamic linker to - resolve references and drive lazy compilation. The MC-JIT enables much - greater code reuse between the JIT and the static compiler and provides - better integration with the platform ABI as a result. -
  • -
  • The assembly printer now makes uses of assemblers instruction aliases - (InstAliases) to print simplified mneumonics when possible.
  • -
  • TableGen can now autogenerate MC expansion logic for pseudo - instructions that expand to multiple MC instructions (through the - PseudoInstExpansion class).
  • -
  • A new llvm-dwarfdump tool provides a start of a drop-in - replacement for the corresponding tool that use LLVM libraries. As part of - this, LLVM has the beginnings of a dwarf parsing library.
  • -
  • llvm-objdump has more output including, symbol by symbol disassembly, - inline relocations, section headers, symbol tables, and section contents. - Support for archive files has also been added.
  • -
  • llvm-nm has gained support for archives of binary files.
  • -
  • llvm-size has been added. This tool prints out section sizes.
  • +
  • ....
@@ -942,30 +333,7 @@ make it run faster:

    -
  • LLVM can now produce code that works with libgcc - to dynamically allocate stack - segments, as opposed to allocating a worst-case chunk of - virtual memory for each thread.
  • -
  • LLVM generates substantially better code for indirect gotos due to a new - tail duplication pass, which can be a substantial performance win for - interpreter loops that use them.
  • -
  • Exception handling and debug frame information is now emitted with CFI - directives. This lets the assembler produce more compact info as it knows - the final offsets, yielding much smaller executables for some C++ applications. - If the system assembler doesn't support it, MC exands the directives when - the integrated assembler is not used. -
  • - -
  • The code generator now supports vector "select" operations on vector - comparisons, turning them into various optimized code sequences (e.g. - using the SSE4/AVX "blend" instructions).
  • -
  • The SSE execution domain fix pass and the ARM NEON move fix pass have been - merged to a target independent execution dependency fix pass. This pass is - used to select alternative equivalent opcodes in a way that minimizes - execution domain crossings. Closely connected instructions are moved to - the same execution domain when possible. Targets can override the - getExecutionDomain and setExecutionDomain hooks - to use the pass.
  • +
  • ....
@@ -979,30 +347,7 @@

New features and major changes in the X86 target include:

    -
  • The X86 backend, assembler and disassembler now have full support for AVX 1. - To enable it pass -mavx to the compiler. AVX2 implementation is - underway on mainline.
  • -
  • The integrated assembler and disassembler now support a broad range of new - instructions including Atom, Ivy Bridge, SSE4a/BMI instructions, rdrand and many others.
  • -
  • The X86 backend now fully supports the X87 - floating point stack inline assembly constraints.
  • -
  • The integrated assembler now supports the .code32 and - .code64 directives to switch between 32-bit and 64-bit - instructions.
  • -
  • The X86 backend now synthesizes horizontal add/sub instructions from generic - vector code when the appropriate instructions are enabled.
  • -
  • The X86-64 backend generates smaller and faster code at -O0 due to - improvements in fast instruction selection.
  • -
  • Native Client - subtarget support has been added.
  • - -
  • The CRC32 intrinsics have been renamed. The intrinsics were previously - @llvm.x86.sse42.crc32.[8|16|32] - and @llvm.x86.sse42.crc64.[8|64]. They have been renamed to - @llvm.x86.sse42.crc32.32.[8|16|32] and - @llvm.x86.sse42.crc32.64.[8|64].
  • +
  • ....
@@ -1017,15 +362,7 @@

New features of the ARM target include:

    -
  • The ARM backend generates much faster code for Cortex-A9 chips.
  • -
  • The ARM backend has improved support for Cortex-M series processors.
  • -
  • The ARM inline assembly constraints have been implemented and are now fully - supported.
  • -
  • NEON code produced by Clang often runs much faster due to improvements in - the Scalar Replacement of Aggregates pass.
  • -
  • The old ARM disassembler is replaced with a new one based on autogenerated - encoding information from ARM .td files.
  • -
  • The integrated assembler has made major leaps forward, but is still beta quality in LLVM 3.0.
  • +
  • ....
@@ -1041,53 +378,20 @@ backend. Some of the major new features include:

    -
  • Most MIPS32r1 and r2 instructions are now supported.
  • -
  • LE/BE MIPS32r1/r2 has been tested extensively.
  • -
  • O32 ABI has been fully tested.
  • -
  • MIPS backend has migrated to using the MC infrastructure for assembly printing. Initial support for direct object code emission has been implemented too.
  • -
  • Delay slot filler has been updated. Now it tries to fill delay slots with useful instructions instead of always filling them with NOPs.
  • -
  • Support for old-style JIT is complete.
  • -
  • Support for old architectures (MIPS1 and MIPS2) has been removed.
  • -
  • Initial support for MIPS64 has been added.
  • +
  • ....

- PTX Target Improvements -

- -
- -

- The PTX back-end is still experimental, but is fairly usable for compute kernels - in LLVM 3.0. Most scalar arithmetic is implemented, as well as intrinsics to - access the special PTX registers and sync instructions. The major missing - pieces are texture/sampler support and some vector operations.

- -

That said, the backend is already being used for domain-specific languages - and can be used by Clang to - compile OpenCL - C code into PTX.

- -
- - -

Other Target Specific Improvements

    -
  • Many PowerPC improvements have been implemented for ELF targets, including - support for varargs and initial support for direct .o file emission.
  • +
  • ....
  • -
  • MicroBlaze scheduling itineraries were added that model the - 3-stage and the 5-stage pipeline architectures. The 3-stage - pipeline model can be selected with -mcpu=mblaze3 - and the 5-stage pipeline model can be selected with - -mcpu=mblaze5.
@@ -1101,49 +405,18 @@

If you're already an LLVM user or developer with out-of-tree changes based on - LLVM 2.9, this section lists some "gotchas" that you may run into upgrading + LLVM 3.1, this section lists some "gotchas" that you may run into upgrading from the previous release.

    -
  • LLVM 3.0 removes support for reading LLVM 2.8 and earlier files, and LLVM - 3.1 will eliminate support for reading LLVM 2.9 files. Going forward, we - aim for all future versions of LLVM to read bitcode files and .ll files - produced by LLVM 3.0.
  • -
  • Tablegen has been split into a library, allowing the clang tblgen pieces - to now live in the clang tree. The llvm version has been renamed to - llvm-tblgen instead of tblgen.
  • -
  • The LLVMC meta compiler driver was removed.
  • -
  • The unused PostOrder Dominator Frontiers and LowerSetJmp passes were removed.
  • - - -
  • The old TailDup pass was not used in the standard pipeline - and was unable to update ssa form, so it has been removed. -
  • The syntax of volatile loads and stores in IR has been changed to - "load volatile"/"store volatile". The old - syntax ("volatile load"/"volatile store") - is still accepted, but is now considered deprecated and will be removed in - 3.1.
  • -
  • llvm-gcc's frontend tests have been removed from llvm/test/Frontend*, sunk - into the clang and dragonegg testsuites.
  • -
  • The old atomic intrinsics (llvm.memory.barrier and - llvm.atomic.*) are now gone. Please use the new atomic - instructions, described in the atomics guide. -
  • LLVM's configure script doesn't depend on llvm-gcc anymore, eliminating a - strange circular dependence between projects.
  • -
- -

Windows (32-bit)

-
- -
    -
  • On Win32(MinGW32 and MSVC), Windows 2000 will not be supported. - Windows XP or higher is required.
  • +
  • LLVM 3.1 removes support for reading LLVM 2.9 bitcode files. Going forward, + we aim for all future versions of LLVM to read bitcode files and .ll files + produced by LLVM 3.0 and later.
  • +
  • ....
-
-

Internal API Changes @@ -1155,100 +428,7 @@ LLVM API changes are:

    -
  • The biggest and most pervasive change is that the type system has been - rewritten: PATypeHolder and OpaqueType are gone, - and all APIs deal with Type* instead of const - Type*. If you need to create recursive structures, then create a - named structure, and use setBody() when all its elements are - built. Type merging and refining is gone too: named structures are not - merged with other structures, even if their layout is identical. (of - course anonymous structures are still uniqued by layout).
  • - -
  • PHINode::reserveOperandSpace has been removed. Instead, you - must specify how many operands to reserve space for when you create the - PHINode, by passing an extra argument - into PHINode::Create.
  • - -
  • PHINodes no longer store their incoming BasicBlocks as operands. Instead, - the list of incoming BasicBlocks is stored separately, and can be accessed - with new functions PHINode::block_begin - and PHINode::block_end.
  • - -
  • Various functions now take an ArrayRef instead of either a - pair of pointers (or iterators) to the beginning and end of a range, or a - pointer and a length. Others now return an ArrayRef instead - of a reference to a SmallVector - or std::vector. These include: -
      - -
    • CallInst::Create
    • -
    • ComputeLinearIndex (in llvm/CodeGen/Analysis.h)
    • -
    • ConstantArray::get
    • -
    • ConstantExpr::getExtractElement
    • -
    • ConstantExpr::getGetElementPtr
    • -
    • ConstantExpr::getInBoundsGetElementPtr
    • -
    • ConstantExpr::getIndices
    • -
    • ConstantExpr::getInsertElement
    • -
    • ConstantExpr::getWithOperands
    • -
    • ConstantFoldCall (in llvm/Analysis/ConstantFolding.h)
    • -
    • ConstantFoldInstOperands (in llvm/Analysis/ConstantFolding.h)
    • -
    • ConstantVector::get
    • -
    • DIBuilder::createComplexVariable
    • -
    • DIBuilder::getOrCreateArray
    • -
    • ExtractValueInst::Create
    • -
    • ExtractValueInst::getIndexedType
    • -
    • ExtractValueInst::getIndices
    • -
    • FindInsertedValue (in llvm/Analysis/ValueTracking.h)
    • -
    • gep_type_begin (in llvm/Support/GetElementPtrTypeIterator.h)
    • -
    • gep_type_end (in llvm/Support/GetElementPtrTypeIterator.h)
    • -
    • GetElementPtrInst::Create
    • -
    • GetElementPtrInst::CreateInBounds
    • -
    • GetElementPtrInst::getIndexedType
    • -
    • InsertValueInst::Create
    • -
    • InsertValueInst::getIndices
    • -
    • InvokeInst::Create
    • -
    • IRBuilder::CreateCall
    • -
    • IRBuilder::CreateExtractValue
    • -
    • IRBuilder::CreateGEP
    • -
    • IRBuilder::CreateInBoundsGEP
    • -
    • IRBuilder::CreateInsertValue
    • -
    • IRBuilder::CreateInvoke
    • -
    • MDNode::get
    • -
    • MDNode::getIfExists
    • -
    • MDNode::getTemporary
    • -
    • MDNode::getWhenValsUnresolved
    • -
    • SimplifyGEPInst (in llvm/Analysis/InstructionSimplify.h)
    • -
    • TargetData::getIndexedOffset
    • -
  • - -
  • All forms of StringMap::getOrCreateValue have been remove - except for the one which takes a StringRef.
  • - -
  • The LLVMBuildUnwind function from the C API was removed. The - LLVM unwind instruction has been deprecated for a long time - and isn't used by the current front-ends. So this was removed during the - exception handling rewrite.
  • - -
  • The LLVMAddLowerSetJmpPass function from the C API was - removed because the LowerSetJmp pass was removed.
  • - -
  • The DIBuilder interface used by front ends to encode - debugging information in the LLVM IR now expects clients to - use DIBuilder::finalize() at the end of translation unit to - complete debugging information encoding.
  • - -
  • TargetSelect.h moved to Support/ from Target/
  • - -
  • UpgradeIntrinsicCall no longer upgrades pre-2.9 intrinsic calls (for - example llvm.memset.i32).
  • - -
  • It is mandatory to initialize all out-of-tree passes too and their dependencies now with - INITIALIZE_PASS{BEGIN,END,} - and INITIALIZE_{PASS,AG}_DEPENDENCY.
  • - -
  • The interface for MemDepResult in MemoryDependenceAnalysis has been - enhanced with new return types Unknown and NonFuncLocal, in addition to - the existing types Clobber, Def, and NonLocal.
  • +
  • ....

@@ -1312,130 +492,6 @@ - - - - -
From clattner at apple.com Tue Dec 13 12:08:36 2011 From: clattner at apple.com (Chris Lattner) Date: Tue, 13 Dec 2011 10:08:36 -0800 Subject: [llvm-commits] Passing OptLevel to XCoreDAGToDAGISel In-Reply-To: References: Message-ID: On Dec 13, 2011, at 8:07 AM, Kyriakos Georgiou wrote: > Hi, > > The optLevel was not passed to "XCoreDAGToDAGISel" making the related passes to run always with the llvm default level of optimization. This patch fixes that. Looks fine to me, please commit. -Chris From clattner at apple.com Tue Dec 13 12:09:55 2011 From: clattner at apple.com (Chris Lattner) Date: Tue, 13 Dec 2011 10:09:55 -0800 Subject: [llvm-commits] [llvm] r146492 - /llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp In-Reply-To: <20111213174506.EE27A2A6C12C@llvm.org> References: <20111213174506.EE27A2A6C12C@llvm.org> Message-ID: On Dec 13, 2011, at 9:45 AM, Chad Rosier wrote: > Author: mcrosier > Date: Tue Dec 13 11:45:06 2011 > New Revision: 146492 > > URL: http://llvm.org/viewvc/llvm-project?rev=146492&view=rev > Log: > [fast-isel] Remove SelectInsertValue() as fast-isel wasn't designed to handle > instructions that define aggregate types. Hi Chad, Are you sure that this isn't used? On X86-64, we do need to return aggregates to match the ABI. This is typically seen as a series of insertvalues right before the return. Is this simple case being handled still? -Chris > > Modified: > llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=146492&r1=146491&r2=146492&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Tue Dec 13 11:45:06 2011 > @@ -942,106 +942,6 @@ > } > > bool > -FastISel::SelectInsertValue(const User *U) { > - return false; > - const InsertValueInst *IVI = dyn_cast(U); > - if (!IVI) > - return false; > - > - // Only try to handle inserts of legal types. But also allow i16/i8/i1 because > - // they're easy. > - const Value *Val = IVI->getOperand(1); > - Type *ValTy = Val->getType(); > - EVT ValVT = TLI.getValueType(ValTy, /*AllowUnknown=*/true); > - if (!ValVT.isSimple()) > - return false; > - MVT VT = ValVT.getSimpleVT(); > - if (!TLI.isTypeLegal(VT) && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1) > - return false; > - > - // Get the Val register. > - unsigned ValReg = getRegForValue(Val); > - if (ValReg == 0) return false; > - > - const Value *Agg = IVI->getOperand(0); > - Type *AggTy = Agg->getType(); > - > - // TODO: Is there a better way to do this? For each insertvalue we allocate > - // a new set of virtual registers, which results in a large number of > - // loads/stores from/to the stack that copies the aggregate all over the place > - // and results in lots of spill code. I believe this is necessary to preserve > - // SSA form, but maybe there's something we could do to improve this. > - > - // Get the Aggregate base register. > - unsigned AggBaseReg; > - DenseMap::iterator I = FuncInfo.ValueMap.find(Agg); > - if (I != FuncInfo.ValueMap.end()) > - AggBaseReg = I->second; > - else if (isa(Agg)) > - AggBaseReg = FuncInfo.InitializeRegForValue(Agg); > - else if (isa(Agg)) > - // In this case we don't need to allocate a new set of register that will > - // never be defined. Just copy Val into the proper result registers. > - AggBaseReg = 0; > - else > - return false; // fast-isel can't handle aggregate constants at the moment > - > - // Create result register(s). > - unsigned ResultBaseReg = FuncInfo.CreateRegs(AggTy); > - > - // Get the actual result register, which is an offset from the base register. > - unsigned LinearIndex = ComputeLinearIndex(Agg->getType(), IVI->getIndices()); > - > - SmallVector AggValueVTs; > - ComputeValueVTs(TLI, AggTy, AggValueVTs); > - > - // Copy the beginning value(s) from the original aggregate. > - unsigned SrcReg; > - unsigned DestReg; > - unsigned BaseRegOff = 0; > - unsigned i = 0; > - for (; i != LinearIndex; ++i) { > - unsigned NRE = TLI.getNumRegisters(FuncInfo.Fn->getContext(), > - AggValueVTs[i]); > - for (unsigned NRI = 0; NRI != NRE; NRI++) { > - if (AggBaseReg) { > - SrcReg = AggBaseReg + BaseRegOff + NRI; > - DestReg = ResultBaseReg + BaseRegOff + NRI; > - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), > - DestReg).addReg(SrcReg); > - } > - } > - BaseRegOff += NRE; > - } > - > - // FIXME: Handle aggregate inserts. Haven't seen these in practice, but.. > - // Copy value(s) from the inserted value(s). > - DestReg = ResultBaseReg + BaseRegOff; > - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), > - DestReg).addReg(ValReg); > - ++BaseRegOff; > - ++i; > - > - // Copy remaining value(s) from the original aggregate. > - if (AggBaseReg) { > - for (unsigned NumAggValues = AggValueVTs.size(); i != NumAggValues; ++i) { > - unsigned NRE = TLI.getNumRegisters(FuncInfo.Fn->getContext(), > - AggValueVTs[i]); > - for (unsigned NRI = 0; NRI != NRE; NRI++) { > - SrcReg = AggBaseReg + BaseRegOff + NRI; > - DestReg = ResultBaseReg + BaseRegOff + NRI; > - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), > - DestReg).addReg(SrcReg); > - > - } > - BaseRegOff += NRE; > - } > - } > - UpdateValueMap(IVI, ResultBaseReg); > - return true; > -} > - > -bool > FastISel::SelectOperator(const User *I, unsigned Opcode) { > switch (Opcode) { > case Instruction::Add: > @@ -1148,9 +1048,6 @@ > case Instruction::ExtractValue: > return SelectExtractValue(I); > > - case Instruction::InsertValue: > - return SelectInsertValue(I); > - > case Instruction::PHI: > llvm_unreachable("FastISel shouldn't visit PHI nodes!"); > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From mcrosier at apple.com Tue Dec 13 12:18:55 2011 From: mcrosier at apple.com (Chad Rosier) Date: Tue, 13 Dec 2011 10:18:55 -0800 Subject: [llvm-commits] [llvm] r146492 - /llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp In-Reply-To: References: <20111213174506.EE27A2A6C12C@llvm.org> Message-ID: <8F01FD0C-D2CF-4124-BB57-A6C15A2982CA@apple.com> On Dec 13, 2011, at 10:09 AM, Chris Lattner wrote: > > On Dec 13, 2011, at 9:45 AM, Chad Rosier wrote: > >> Author: mcrosier >> Date: Tue Dec 13 11:45:06 2011 >> New Revision: 146492 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=146492&view=rev >> Log: >> [fast-isel] Remove SelectInsertValue() as fast-isel wasn't designed to handle >> instructions that define aggregate types. > > Hi Chad, > > Are you sure that this isn't used? On X86-64, we do need to return aggregates to match the ABI. This is typically seen as a series of insertvalues right before the return. Is this simple case being handled still? I implemented this last week, but Dan explained to me that fast-isel was never designed to support instructions that return an aggregate type (or rather define a series of registers). I believe UpdateValueMap wasn't designed to handle this case. For example, define void @test1() nounwind ssp { %1 = insertvalue %struct.x undef, i32 1, 0 %2 = insertvalue %struct.x %1, i32 2, 1 call void @f(%struct.x %2) nounwind ret void } For the above test case SelectInsertValue would generate the following machine instructions: %vreg2 = MOVi16 2, pred:14, pred:%noreg; GPR:%vreg2 %vreg7 = MOVi16 1, pred:14, pred:%noreg; GPR:%vreg7 %vreg8 = COPY %vreg7; GPR:%vreg8,%vreg7 %vreg9 = IMPLICIT_DEF; GPR:%vreg9 %vreg5 = COPY %vreg8; GPR:%vreg5,%vreg8 %vreg6 = COPY %vreg2; GPR:%vreg6,%vreg2 ADJCALLSTACKDOWN 0, pred:14, pred:%noreg, %SP, %SP %R0 = COPY %vreg5; GPR:%vreg5 %R1 = COPY %vreg1; GPR:%vreg1 BLr9 , %R0, %R1, %R0, %R1, %R7, %SP, ... ADJCALLSTACKUP 0, 0, pred:14, pred:%noreg, %SP, %SP BX_RET pred:14, pred:%noreg Notice %R1 is begin defined by a undefined virtual register, %vreg1. %R1 = COPY %vreg1; GPR:%vreg1 It should be defined by %vreg6. If this is something we really want I could discuss things with Dan. Chad > -Chris > >> >> Modified: >> llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp >> >> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=146492&r1=146491&r2=146492&view=diff >> ============================================================================== >> --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) >> +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Tue Dec 13 11:45:06 2011 >> @@ -942,106 +942,6 @@ >> } >> >> bool >> -FastISel::SelectInsertValue(const User *U) { >> - return false; Also note that I disabled this on Saturday after the nightly testers reported a bunch of miscompiles for the ARM testers. Chad >> - const InsertValueInst *IVI = dyn_cast(U); >> - if (!IVI) >> - return false; >> - >> - // Only try to handle inserts of legal types. But also allow i16/i8/i1 because >> - // they're easy. >> - const Value *Val = IVI->getOperand(1); >> - Type *ValTy = Val->getType(); >> - EVT ValVT = TLI.getValueType(ValTy, /*AllowUnknown=*/true); >> - if (!ValVT.isSimple()) >> - return false; >> - MVT VT = ValVT.getSimpleVT(); >> - if (!TLI.isTypeLegal(VT) && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1) >> - return false; >> - >> - // Get the Val register. >> - unsigned ValReg = getRegForValue(Val); >> - if (ValReg == 0) return false; >> - >> - const Value *Agg = IVI->getOperand(0); >> - Type *AggTy = Agg->getType(); >> - >> - // TODO: Is there a better way to do this? For each insertvalue we allocate >> - // a new set of virtual registers, which results in a large number of >> - // loads/stores from/to the stack that copies the aggregate all over the place >> - // and results in lots of spill code. I believe this is necessary to preserve >> - // SSA form, but maybe there's something we could do to improve this. >> - >> - // Get the Aggregate base register. >> - unsigned AggBaseReg; >> - DenseMap::iterator I = FuncInfo.ValueMap.find(Agg); >> - if (I != FuncInfo.ValueMap.end()) >> - AggBaseReg = I->second; >> - else if (isa(Agg)) >> - AggBaseReg = FuncInfo.InitializeRegForValue(Agg); >> - else if (isa(Agg)) >> - // In this case we don't need to allocate a new set of register that will >> - // never be defined. Just copy Val into the proper result registers. >> - AggBaseReg = 0; >> - else >> - return false; // fast-isel can't handle aggregate constants at the moment >> - >> - // Create result register(s). >> - unsigned ResultBaseReg = FuncInfo.CreateRegs(AggTy); >> - >> - // Get the actual result register, which is an offset from the base register. >> - unsigned LinearIndex = ComputeLinearIndex(Agg->getType(), IVI->getIndices()); >> - >> - SmallVector AggValueVTs; >> - ComputeValueVTs(TLI, AggTy, AggValueVTs); >> - >> - // Copy the beginning value(s) from the original aggregate. >> - unsigned SrcReg; >> - unsigned DestReg; >> - unsigned BaseRegOff = 0; >> - unsigned i = 0; >> - for (; i != LinearIndex; ++i) { >> - unsigned NRE = TLI.getNumRegisters(FuncInfo.Fn->getContext(), >> - AggValueVTs[i]); >> - for (unsigned NRI = 0; NRI != NRE; NRI++) { >> - if (AggBaseReg) { >> - SrcReg = AggBaseReg + BaseRegOff + NRI; >> - DestReg = ResultBaseReg + BaseRegOff + NRI; >> - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), >> - DestReg).addReg(SrcReg); >> - } >> - } >> - BaseRegOff += NRE; >> - } >> - >> - // FIXME: Handle aggregate inserts. Haven't seen these in practice, but.. >> - // Copy value(s) from the inserted value(s). >> - DestReg = ResultBaseReg + BaseRegOff; >> - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), >> - DestReg).addReg(ValReg); >> - ++BaseRegOff; >> - ++i; >> - >> - // Copy remaining value(s) from the original aggregate. >> - if (AggBaseReg) { >> - for (unsigned NumAggValues = AggValueVTs.size(); i != NumAggValues; ++i) { >> - unsigned NRE = TLI.getNumRegisters(FuncInfo.Fn->getContext(), >> - AggValueVTs[i]); >> - for (unsigned NRI = 0; NRI != NRE; NRI++) { >> - SrcReg = AggBaseReg + BaseRegOff + NRI; >> - DestReg = ResultBaseReg + BaseRegOff + NRI; >> - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), >> - DestReg).addReg(SrcReg); >> - >> - } >> - BaseRegOff += NRE; >> - } >> - } >> - UpdateValueMap(IVI, ResultBaseReg); >> - return true; >> -} >> - >> -bool >> FastISel::SelectOperator(const User *I, unsigned Opcode) { >> switch (Opcode) { >> case Instruction::Add: >> @@ -1148,9 +1048,6 @@ >> case Instruction::ExtractValue: >> return SelectExtractValue(I); >> >> - case Instruction::InsertValue: >> - return SelectInsertValue(I); >> - >> case Instruction::PHI: >> llvm_unreachable("FastISel shouldn't visit PHI nodes!"); >> >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From mcrosier at apple.com Tue Dec 13 12:23:08 2011 From: mcrosier at apple.com (Chad Rosier) Date: Tue, 13 Dec 2011 10:23:08 -0800 Subject: [llvm-commits] [llvm] r146492 - /llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp In-Reply-To: <8F01FD0C-D2CF-4124-BB57-A6C15A2982CA@apple.com> References: <20111213174506.EE27A2A6C12C@llvm.org> <8F01FD0C-D2CF-4124-BB57-A6C15A2982CA@apple.com> Message-ID: On Dec 13, 2011, at 10:18 AM, Chad Rosier wrote: >> Are you sure that this isn't used? On X86-64, we do need to return aggregates to match the ABI. This is typically seen as a series of insertvalues right before the return. Is this simple case being handled still? And to answer your second question. I don't believe this case was ever handled nor is it being handled now. Chad -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20111213/105808ae/attachment.html From krasin at chromium.org Tue Dec 13 12:33:39 2011 From: krasin at chromium.org (Ivan Krasin) Date: Tue, 13 Dec 2011 10:33:39 -0800 Subject: [llvm-commits] lib/Linker: initial support of bitcode shared objects Message-ID: Hi llvm team, A few days ago, I have submitted a proposal to extend lib/Linker and (possibly) llvm-ld to be able to link with bitcode "so": special bitcode stubs for native dynamic libraries to allow linking against them on the bitcode level, which is important for cases when using llvm gold plugin is not desirable. See the thread for more details: http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-December/046055.html The attachment contains the first patch for initial support of bitcode ".so" files. It's not complete in terms of features but it's the minimal viable change to lib/Linker to allow to implement at least basic "dynamic" linking in llvm-ld or similar tools. Please, let me know if the approach is valid and which issues should be addressed before the commit. thanks, krasin -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20111213/078c6a53/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: lib_linker_dynsym.patch Type: text/x-patch Size: 5585 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20111213/078c6a53/attachment.bin From daniel at zuster.org Tue Dec 13 12:36:32 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 13 Dec 2011 18:36:32 -0000 Subject: [llvm-commits] [zorg] r146495 - /zorg/trunk/llvmlab/llvmlab/ui/static/View2D.js Message-ID: <20111213183632.EF1202A6C12C@llvm.org> Author: ddunbar Date: Tue Dec 13 12:36:32 2011 New Revision: 146495 URL: http://llvm.org/viewvc/llvm-project?rev=146495&view=rev Log: llvmlab: Fix another broken symbolic link. Modified: zorg/trunk/llvmlab/llvmlab/ui/static/View2D.js (contents, props changed) Modified: zorg/trunk/llvmlab/llvmlab/ui/static/View2D.js URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/llvmlab/llvmlab/ui/static/View2D.js?rev=146495&r1=146494&r2=146495&view=diff ============================================================================== --- zorg/trunk/llvmlab/llvmlab/ui/static/View2D.js (original) +++ zorg/trunk/llvmlab/llvmlab/ui/static/View2D.js Tue Dec 13 12:36:32 2011 @@ -1 +1 @@ -link ../../../../lnt/lnt/viewer/js/View2D.js \ No newline at end of file +link ../../../../lnt/lnt/server/ui/static/View2D.js \ No newline at end of file From clattner at apple.com Tue Dec 13 12:58:12 2011 From: clattner at apple.com (Chris Lattner) Date: Tue, 13 Dec 2011 10:58:12 -0800 Subject: [llvm-commits] [llvm] r146492 - /llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp In-Reply-To: <8F01FD0C-D2CF-4124-BB57-A6C15A2982CA@apple.com> References: <20111213174506.EE27A2A6C12C@llvm.org> <8F01FD0C-D2CF-4124-BB57-A6C15A2982CA@apple.com> Message-ID: <797D7AAD-F477-4BE3-9098-65675A7FCE5E@apple.com> On Dec 13, 2011, at 10:18 AM, Chad Rosier wrote: >> Are you sure that this isn't used? On X86-64, we do need to return aggregates to match the ABI. This is typically seen as a series of insertvalues right before the return. Is this simple case being handled still? > > I implemented this last week, but Dan explained to me that fast-isel was never designed to support instructions that return an aggregate type (or rather define a series of registers). I believe UpdateValueMap wasn't designed to handle this case. Aha, ok. I was just concerned about a regression on x86-64 not about enabling a new class of stuff. Thanks for checking. -Chris From mcrosier at apple.com Tue Dec 13 13:00:13 2011 From: mcrosier at apple.com (Chad Rosier) Date: Tue, 13 Dec 2011 11:00:13 -0800 Subject: [llvm-commits] [llvm] r146492 - /llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp In-Reply-To: <797D7AAD-F477-4BE3-9098-65675A7FCE5E@apple.com> References: <20111213174506.EE27A2A6C12C@llvm.org> <8F01FD0C-D2CF-4124-BB57-A6C15A2982CA@apple.com> <797D7AAD-F477-4BE3-9098-65675A7FCE5E@apple.com> Message-ID: <30659000-387F-4653-BF37-F9B458B8C17B@apple.com> On Dec 13, 2011, at 10:58 AM, Chris Lattner wrote: > > On Dec 13, 2011, at 10:18 AM, Chad Rosier wrote: >>> Are you sure that this isn't used? On X86-64, we do need to return aggregates to match the ABI. This is typically seen as a series of insertvalues right before the return. Is this simple case being handled still? >> >> I implemented this last week, but Dan explained to me that fast-isel was never designed to support instructions that return an aggregate type (or rather define a series of registers). I believe UpdateValueMap wasn't designed to handle this case. > > Aha, ok. I was just concerned about a regression on x86-64 not about enabling a new class of stuff. Thanks for checking. > No problem. Chad > -Chris From kcc at google.com Tue Dec 13 12:58:48 2011 From: kcc at google.com (Kostya Serebryany) Date: Tue, 13 Dec 2011 18:58:48 -0000 Subject: [llvm-commits] [compiler-rt] r146499 - in /compiler-rt/trunk: Makefile make/config.mk Message-ID: <20111213185848.24CF02A6C12C@llvm.org> Author: kcc Date: Tue Dec 13 12:58:47 2011 New Revision: 146499 URL: http://llvm.org/viewvc/llvm-project?rev=146499&view=rev Log: build compiler-rt with -fPIC, otherwise the run-time libs will not link with -pie, at least on linux Modified: compiler-rt/trunk/Makefile compiler-rt/trunk/make/config.mk Modified: compiler-rt/trunk/Makefile URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/Makefile?rev=146499&r1=146498&r2=146499&view=diff ============================================================================== --- compiler-rt/trunk/Makefile (original) +++ compiler-rt/trunk/Makefile Tue Dec 13 12:58:47 2011 @@ -227,7 +227,7 @@ $(Verb) $(Tmp.CC) $(Tmp.CFLAGS) -c -o $$@ $$< $(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.c $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir $(Summary) " COMPILE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<" - $(Verb) $(Tmp.CC) $(Tmp.CFLAGS) -c -o $$@ $$< + $(Verb) $(Tmp.CC) $(Tmp.CFLAGS) -c $(COMMON_CFLAGS) -o $$@ $$< $(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.cc $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir $(Summary) " COMPILE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<" $(Verb) $(Tmp.CC) $(Tmp.CFLAGS) -c $(COMMON_CXXFLAGS) -o $$@ $$< Modified: compiler-rt/trunk/make/config.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/make/config.mk?rev=146499&r1=146498&r2=146499&view=diff ============================================================================== --- compiler-rt/trunk/make/config.mk (original) +++ compiler-rt/trunk/make/config.mk Tue Dec 13 12:58:47 2011 @@ -42,4 +42,5 @@ ### # Common compiler options -COMMON_CXXFLAGS=-fno-exceptions +COMMON_CXXFLAGS=-fno-exceptions -fPIC +COMMON_CFLAGS=-fPIC From daniel at zuster.org Tue Dec 13 13:00:47 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 13 Dec 2011 19:00:47 -0000 Subject: [llvm-commits] [zorg] r146500 - in /zorg/trunk/llvmlab/llvmlab/ui: ci/views.py frontend/views.py templates/index.html templates/layout.html Message-ID: <20111213190047.D6E102A6C12C@llvm.org> Author: ddunbar Date: Tue Dec 13 13:00:47 2011 New Revision: 146500 URL: http://llvm.org/viewvc/llvm-project?rev=146500&view=rev Log: llvmlab.ui: Compatibility update for Flask 0.7+ change to blueprint model. Modified: zorg/trunk/llvmlab/llvmlab/ui/ci/views.py zorg/trunk/llvmlab/llvmlab/ui/frontend/views.py zorg/trunk/llvmlab/llvmlab/ui/templates/index.html zorg/trunk/llvmlab/llvmlab/ui/templates/layout.html Modified: zorg/trunk/llvmlab/llvmlab/ui/ci/views.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/llvmlab/llvmlab/ui/ci/views.py?rev=146500&r1=146499&r2=146500&view=diff ============================================================================== --- zorg/trunk/llvmlab/llvmlab/ui/ci/views.py (original) +++ zorg/trunk/llvmlab/llvmlab/ui/ci/views.py Tue Dec 13 13:00:47 2011 @@ -7,7 +7,7 @@ from flask import session from flask import url_for from flask import current_app -ci = flask.Module(__name__, url_prefix='/ci') +ci = flask.Module(__name__, url_prefix='/ci', name='ci') from llvmlab import util Modified: zorg/trunk/llvmlab/llvmlab/ui/frontend/views.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/llvmlab/llvmlab/ui/frontend/views.py?rev=146500&r1=146499&r2=146500&view=diff ============================================================================== --- zorg/trunk/llvmlab/llvmlab/ui/frontend/views.py (original) +++ zorg/trunk/llvmlab/llvmlab/ui/frontend/views.py Tue Dec 13 13:00:47 2011 @@ -13,7 +13,7 @@ ### # Top-level Information -frontend = flask.Module(__name__) +frontend = flask.Module(__name__, name="frontend") @frontend.route('/') def index(): Modified: zorg/trunk/llvmlab/llvmlab/ui/templates/index.html URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/llvmlab/llvmlab/ui/templates/index.html?rev=146500&r1=146499&r2=146500&view=diff ============================================================================== --- zorg/trunk/llvmlab/llvmlab/ui/templates/index.html (original) +++ zorg/trunk/llvmlab/llvmlab/ui/templates/index.html Tue Dec 13 13:00:47 2011 @@ -9,7 +9,7 @@
  • logout
  • machines
  • users
  • -
  • dashboard
  • +
  • dashboard
  • {% if session.logged_in %}
  • my info
  • admin
  • Modified: zorg/trunk/llvmlab/llvmlab/ui/templates/layout.html URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/llvmlab/llvmlab/ui/templates/layout.html?rev=146500&r1=146499&r2=146500&view=diff ============================================================================== --- zorg/trunk/llvmlab/llvmlab/ui/templates/layout.html (original) +++ zorg/trunk/llvmlab/llvmlab/ui/templates/layout.html Tue Dec 13 13:00:47 2011 @@ -13,7 +13,7 @@
    - {# + {# #}lab.llvm.org | {{ self.title() }} {% if session.logged_in %}     @@ -27,7 +27,7 @@
    {% block body %}{% endblock %}