[BOLT] Fix Windows build

Summary:
Make BOLT build in VisualStudio compiler and run without
crashing on a simple test. Other tests are not running.

(cherry picked from FBD32378736)
This commit is contained in:
Rafael Auler 2021-11-11 18:14:53 -08:00 committed by Maksim Panchenko
parent 0e7dd1aad1
commit ae585be11c
11 changed files with 104 additions and 125 deletions

View File

@ -4,55 +4,77 @@ set(BOLT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(BOLT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(CMAKE_CXX_STANDARD 14)
if (NOT CMAKE_HOST_SYSTEM_NAME MATCHES Linux)
message(WARNING "Not building BOLT on unsupported platform")
else()
set(BOLT_ENABLE_RUNTIME OFF)
if (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64")
set(BOLT_ENABLE_RUNTIME ON)
endif()
set(BOLT_ENABLE_RUNTIME OFF)
if (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64")
set(BOLT_ENABLE_RUNTIME ON)
endif()
set(BOLT_INCLUDE_TESTS OFF)
if (LLVM_INCLUDE_TESTS)
string(FIND "${LLVM_ENABLE_PROJECTS}" "clang" POSITION)
set(BOLT_INCLUDE_TESTS OFF)
if (LLVM_INCLUDE_TESTS)
string(FIND "${LLVM_ENABLE_PROJECTS}" "clang" POSITION)
if (NOT ${POSITION} EQUAL -1)
string(FIND "${LLVM_ENABLE_PROJECTS}" "lld" POSITION)
if (NOT ${POSITION} EQUAL -1)
string(FIND "${LLVM_ENABLE_PROJECTS}" "lld" POSITION)
if (NOT ${POSITION} EQUAL -1)
set(BOLT_INCLUDE_TESTS ON)
else()
message(WARNING "Not including BOLT tests since lld is disabled")
endif()
set(BOLT_INCLUDE_TESTS ON)
else()
message(WARNING "Not including BOLT tests since clang is disabled")
message(WARNING "Not including BOLT tests since lld is disabled")
endif()
endif()
if (BOLT_ENABLE_RUNTIME)
message(STATUS "Building BOLT runtime libraries for X86")
ExternalProject_Add(bolt_rt
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/runtime"
STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-stamps
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins
CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
-DCMAKE_INSTALL_PREFIX=${LLVM_BINARY_DIR}
BUILD_ALWAYS True
)
install(CODE "execute_process\(COMMAND \${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=\${CMAKE_INSTALL_PREFIX} -P ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins/cmake_install.cmake \)"
COMPONENT bolt_rt)
add_llvm_install_targets(install-bolt_rt
DEPENDS bolt_rt
COMPONENT bolt_rt)
endif()
include_directories( ${BOLT_SOURCE_DIR}/include )
add_subdirectory(lib)
add_subdirectory(tools)
if (BOLT_INCLUDE_TESTS)
add_subdirectory(test)
else()
message(WARNING "Not including BOLT tests since clang is disabled")
endif()
endif()
if (BOLT_ENABLE_RUNTIME)
message(STATUS "Building BOLT runtime libraries for X86")
ExternalProject_Add(bolt_rt
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/runtime"
STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-stamps
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins
CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
-DCMAKE_INSTALL_PREFIX=${LLVM_BINARY_DIR}
BUILD_ALWAYS True
)
install(CODE "execute_process\(COMMAND \${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=\${CMAKE_INSTALL_PREFIX} -P ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins/cmake_install.cmake \)"
COMPONENT bolt_rt)
add_llvm_install_targets(install-bolt_rt
DEPENDS bolt_rt
COMPONENT bolt_rt)
endif()
# Get the current git revision for BOLT.
find_program(git_executable NAMES git git.exe git.cmd)
if (git_executable)
execute_process(COMMAND ${git_executable} rev-parse HEAD
WORKING_DIRECTORY ${LLVM_MAIN_SRC_DIR}
TIMEOUT 5
RESULT_VARIABLE git_result
OUTPUT_VARIABLE git_output)
if( git_result EQUAL 0 )
string(STRIP "${git_output}" git_ref_id)
set(BOLT_REVISION "${git_ref_id}")
endif()
endif()
# If we can't find a revision, set it to "<unknown>".
if (NOT BOLT_REVISION)
set(BOLT_REVISION "<unknown>")
endif()
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/include/bolt/Utils/BoltRevision.inc.in
${CMAKE_CURRENT_BINARY_DIR}/include/bolt/Utils/BoltRevision.inc)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR}/include
)
add_subdirectory(lib)
add_subdirectory(tools)
if (BOLT_INCLUDE_TESTS)
add_subdirectory(test)
endif()

View File

@ -1012,8 +1012,11 @@ private:
}
};
/// Keep the size of the BinaryBasicBlock within a reasonable size class.
#if defined(LLVM_ON_UNIX)
/// Keep the size of the BinaryBasicBlock within a reasonable size class
/// (jemalloc bucket) on Linux
static_assert(sizeof(BinaryBasicBlock) <= 256, "");
#endif
bool operator<(const BinaryBasicBlock &LHS, const BinaryBasicBlock &RHS);

View File

@ -176,10 +176,10 @@ private:
/// Memory map info for a single file
struct MMapInfo {
pid_t PID{-1LL};
uint64_t BaseAddress;
uint64_t Size;
uint64_t Offset;
int32_t PID{-1};
bool Forked{false};
uint64_t Time{0ULL}; // time in micro seconds
};
@ -189,8 +189,8 @@ private:
/// Fork event info
struct ForkInfo {
pid_t ParentPID;
pid_t ChildPID;
int32_t ParentPID;
int32_t ChildPID;
uint64_t Time{0ULL};
};
@ -351,7 +351,7 @@ private:
Optional<ForkInfo> parseForkEvent();
/// Parse 'PERF_RECORD_COMM exec'. Don't consume the string.
Optional<pid_t> parseCommExecEvent();
Optional<int32_t> parseCommExecEvent();
/// Parse the full output generated by `perf script --show-mmap-events`
/// to generate mapping between binary files and their memory mappings for

View File

@ -0,0 +1 @@
#define BOLT_VERSION_STRING "@BOLT_REVISION@"

View File

@ -81,8 +81,9 @@ bool BinaryBasicBlock::validateSuccessorInvariants() {
// any overlapping jump tables. We only look at the entries for the jump
// table that is referenced at the last instruction.
const auto Range = JT->getEntriesForAddress(BC.MIB->getJumpTable(*Inst));
const std::vector<const MCSymbol *> Entries(&JT->Entries[Range.first],
&JT->Entries[Range.second]);
const std::vector<const MCSymbol *> Entries(
std::next(JT->Entries.begin(), Range.first),
std::next(JT->Entries.begin(), Range.second));
std::set<const MCSymbol *> UniqueSyms(Entries.begin(), Entries.end());
for (BinaryBasicBlock *Succ : Successors) {
auto Itr = UniqueSyms.find(Succ->getLabel());

View File

@ -18,6 +18,7 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/edit_distance.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCContext.h"
@ -34,7 +35,6 @@
#include "llvm/Support/Regex.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <cxxabi.h>
#include <functional>
#include <limits>
#include <numeric>
@ -259,12 +259,7 @@ BinaryFunction::hasRestoredNameRegex(const StringRef Name) const {
std::string BinaryFunction::getDemangledName() const {
StringRef MangledName = NameResolver::restore(getOneName());
int Status = 0;
char *const Name =
abi::__cxa_demangle(MangledName.str().c_str(), 0, 0, &Status);
const std::string NameStr(Status == 0 ? Name : MangledName);
::free(Name);
return NameStr;
return demangle(MangledName.str());
}
BinaryBasicBlock *
@ -3791,8 +3786,10 @@ void BinaryFunction::updateLayout(BinaryBasicBlock *Start,
// Insert new blocks in the layout immediately after Start.
auto Pos = std::find(layout_begin(), layout_end(), Start);
assert(Pos != layout_end());
BinaryBasicBlock **Begin = &BasicBlocks[getIndex(Start) + 1];
BinaryBasicBlock **End = &BasicBlocks[getIndex(Start) + NumNewBlocks + 1];
BasicBlockListType::iterator Begin =
std::next(BasicBlocks.begin(), getIndex(Start) + 1);
BasicBlockListType::iterator End =
std::next(BasicBlocks.begin(), getIndex(Start) + NumNewBlocks + 1);
BasicBlocksLayout.insert(Pos + 1, Begin, End);
updateLayoutIndices();
}

View File

@ -863,7 +863,8 @@ IndirectCallPromotion::fixCFG(BinaryBasicBlock &IndCallBlock,
std::vector<BinaryBranchInfo> BBI;
std::vector<BinaryBranchInfo> ScaledBBI;
for (const Callsite &Target : Targets) {
const size_t NumEntries = std::max(1UL, Target.JTIndices.size());
const size_t NumEntries =
std::max(static_cast<std::size_t>(1UL), Target.JTIndices.size());
for (size_t I = 0; I < NumEntries; ++I) {
BBI.push_back(
BinaryBranchInfo{(Target.Branches + NumEntries - 1) / NumEntries,
@ -882,7 +883,8 @@ IndirectCallPromotion::fixCFG(BinaryBasicBlock &IndCallBlock,
std::vector<MCSymbol*> SymTargets;
for (const Callsite &Target : Targets) {
const size_t NumEntries = std::max(1UL, Target.JTIndices.size());
const size_t NumEntries =
std::max(static_cast<std::size_t>(1UL), Target.JTIndices.size());
for (size_t I = 0; I < NumEntries; ++I) {
SymTargets.push_back(Target.To.Sym);
}

View File

@ -18,6 +18,7 @@
#include "bolt/Profile/Heatmap.h"
#include "bolt/Utils/CommandLineOpts.h"
#include "bolt/Utils/Utils.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
@ -29,8 +30,6 @@
#include <map>
#include <unordered_map>
#include <unistd.h>
#define DEBUG_TYPE "aggregator"
using namespace llvm;
@ -329,18 +328,17 @@ bool DataAggregator::checkPerfDataMagic(StringRef FileName) {
if (opts::ReadPreAggregated)
return true;
int FD;
if (sys::fs::openFileForRead(FileName, FD)) {
Expected<sys::fs::file_t> FD = sys::fs::openNativeFileForRead(FileName);
if (!FD)
return false;
}
char Buf[7] = {0, 0, 0, 0, 0, 0, 0};
if (::read(FD, Buf, 7) == -1) {
::close(FD);
auto Close = make_scope_exit([&] { sys::fs::closeFile(*FD); });
Expected<size_t> BytesRead = sys::fs::readNativeFileSlice(
*FD, makeMutableArrayRef(Buf, sizeof(Buf)), 0);
if (!BytesRead || *BytesRead != 7)
return false;
}
::close(FD);
if (strncmp(Buf, "PERFILE", 7) == 0)
return true;
@ -1805,8 +1803,7 @@ void DataAggregator::processPreAggregated() {
outs() << "\n";
}
Optional<pid_t>
DataAggregator::parseCommExecEvent() {
Optional<int32_t> DataAggregator::parseCommExecEvent() {
size_t LineEnd = ParsingBuf.find_first_of("\n");
if (LineEnd == StringRef::npos) {
reportError("expected rest of line");
@ -1824,7 +1821,7 @@ DataAggregator::parseCommExecEvent() {
// Line:
// PERF_RECORD_COMM exec: <name>:<pid>/<tid>"
StringRef PIDStr = Line.rsplit(':').second.split('/').first;
pid_t PID;
int32_t PID;
if (PIDStr.getAsInteger(10, PID)) {
reportError("expected PID");
Diag << "Found: " << PIDStr << "in '" << Line << "'\n";
@ -2077,7 +2074,7 @@ std::error_code DataAggregator::parseTaskEvents() {
TimerGroupDesc, opts::TimeAggregator);
while (hasData()) {
if (Optional<pid_t> CommInfo = parseCommExecEvent()) {
if (Optional<int32_t> CommInfo = parseCommExecEvent()) {
// Remove forked child that ran execve
auto MMapInfoIter = BinaryMMapInfo.find(*CommInfo);
if (MMapInfoIter != BinaryMMapInfo.end() &&

View File

@ -3201,7 +3201,7 @@ void RewriteInstance::encodePseudoProbes() {
SmallString<8> Contents;
MCDecodedPseudoProbe *LastProbe = nullptr;
auto EmitInt = [&](uint64_t Value, uint Size) {
auto EmitInt = [&](uint64_t Value, uint32_t Size) {
const bool IsLittleEndian = BC->AsmInfo->isLittleEndian();
uint64_t Swapped = support::endian::byte_swap(
Value, IsLittleEndian ? support::little : support::big);
@ -3240,7 +3240,7 @@ void RewriteInstance::encodePseudoProbes() {
EmitSLEB128IntValue(Delta);
} else {
// Emit absolute address for encoding the first pseudo probe.
unsigned AddrSize = BC->AsmInfo->getCodePointerSize();
uint32_t AddrSize = BC->AsmInfo->getCodePointerSize();
EmitInt(CurProbe->getAddress(), AddrSize);
}
};

View File

@ -1,46 +1,3 @@
# Get the current git revision for BOLT.
function(get_version ofn)
find_program(git_executable NAMES git git.exe git.cmd)
if (git_executable)
execute_process(COMMAND ${git_executable} rev-parse HEAD
WORKING_DIRECTORY ${LLVM_MAIN_SRC_DIR}
TIMEOUT 5
RESULT_VARIABLE git_result
OUTPUT_VARIABLE git_output)
if( git_result EQUAL 0 )
string(STRIP "${git_output}" git_ref_id)
set(BOLT_REVISION "${git_ref_id}")
endif()
endif()
# If we can't find a revision, set it to "<unknown>".
if (NOT BOLT_REVISION)
set(BOLT_REVISION "<unknown>")
endif()
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
COMMAND echo '"${BOLT_REVISION}"' > ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
COMMENT "Generating bogus ${ofn}..."
)
set(VERSION_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE)
# `make clean' must remove all those generated files:
set_property(DIRECTORY APPEND
PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${ofn})
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${ofn} PROPERTIES
GENERATED 1)
endfunction()
# Creates a public target for generating the revision file.
function(add_public_gen_version_target target)
add_custom_target(${target} DEPENDS ${VERSION_OUTPUT})
set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} ${target} PARENT_SCOPE)
endfunction()
get_version(BoltRevision.inc)
add_public_gen_version_target(GenBoltRevision)
add_llvm_library(LLVMBOLTUtils
CommandLineOpts.cpp
Utils.cpp

View File

@ -11,14 +11,13 @@
//===----------------------------------------------------------------------===//
#include "bolt/Utils/CommandLineOpts.h"
#include "bolt/Utils/BoltRevision.inc"
using namespace llvm;
namespace llvm {
namespace bolt {
const char *BoltRevision =
#include "BoltRevision.inc"
;
const char *BoltRevision = BOLT_VERSION_STRING;
}
}