Add VTune as an optional external dependency and add task tracking.

llvm-svn: 178940
This commit is contained in:
Michael J. Spencer 2013-04-06 00:56:40 +00:00
parent e9846f7f3c
commit d4eb47c110
5 changed files with 182 additions and 1 deletions

View File

@ -68,6 +68,20 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
"`CMakeFiles'. Please delete them.")
endif()
list (APPEND CMAKE_MODULE_PATH "${LLD_SOURCE_DIR}/cmake/modules")
option(LLD_USE_VTUNE
"Enable VTune user task tracking."
OFF)
if (LLD_USE_VTUNE)
find_package(VTune)
if (VTUNE_FOUND)
include_directories(${VTune_INCLUDE_DIRS})
list(APPEND LLVM_COMMON_LIBS ${VTune_LIBRARIES})
add_definitions(-DLLD_HAS_VTUNE)
endif()
endif()
# lld requires c++11 to build. Make sure that we have a compiler and standard
# library combination that can do that.
if (MSVC11)

View File

@ -0,0 +1,31 @@
# - Find VTune ittnotify.
# Defines:
# VTune_FOUND
# VTune_INCLUDE_DIRS
# VTune_LIBRARIES
set(dirs
"$ENV{VTUNE_AMPLIFIER_XE_2013_DIR}/"
"C:/Program Files (x86)/Intel/VTune Amplifier XE 2013/"
"$ENV{VTUNE_AMPLIFIER_XE_2011_DIR}/"
"C:/Program Files (x86)/Intel/VTune Amplifier XE 2011/"
)
find_path(VTune_INCLUDE_DIRS ittnotify.h
PATHS ${dirs}
PATH_SUFFIXES include)
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
set(vtune_lib_dir lib64)
else()
set(vtune_lib_dir lib32)
endif()
find_library(VTune_LIBRARIES libittnotify
HINTS "${VTune_INCLUDE_DIRS}/.."
PATHS ${dirs}
PATH_SUFFIXES ${vtune_lib_dir})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
VTune DEFAULT_MSG VTune_LIBRARIES VTune_INCLUDE_DIRS)

View File

@ -0,0 +1,129 @@
//===- include/Core/Instrumentation.h - Instrumentation API ---------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provide an Instrumentation API that optionally uses VTune interfaces.
///
//===----------------------------------------------------------------------===//
#ifndef LLD_CORE_INSTRUMENTATION_H
#define LLD_CORE_INSTRUMENTATION_H
#ifdef LLD_HAS_VTUNE
# include <ittnotify.h>
#endif
namespace lld {
#ifdef LLD_HAS_VTUNE
/// \brief A unique global scope for instrumentation data.
///
/// Domains last for the lifetime of the application and cannot be destroyed.
/// Multiple Domains created with the same name represent the same domain.
class Domain {
__itt_domain *_domain;
public:
Domain(const char *name) : _domain(__itt_domain_createA(name)) {}
operator __itt_domain *() const { return _domain; }
__itt_domain *operator->() const { return _domain; }
};
/// \brief A global reference to a string constant.
///
/// These are uniqued by the ITT runtime and cannot be deleted. They are not
/// specific to a domain.
///
/// Prefer reusing a single StringHandle over passing a ntbs when the same
/// string will be used often.
class StringHandle {
__itt_string_handle *_handle;
public:
StringHandle(const char *name) : _handle(__itt_string_handle_createA(name)) {}
operator __itt_string_handle *() const { return _handle; }
};
/// \brief A task on a single thread. Nests within other tasks.
///
/// Each thread has its own task stack and tasks nest recursively on that stack.
/// A task cannot transfer threads.
///
/// SBRM is used to ensure task starts and ends are ballanced. The lifetime of
/// a task is either the liftime of this object, or until end is called.
class ScopedTask {
__itt_domain *_domain;
ScopedTask(const ScopedTask &) LLVM_DELETED_FUNCTION;
ScopedTask &operator=(const ScopedTask &) LLVM_DELETED_FUNCTION;
public:
/// \brief Create a task in Domain \p d named \p s.
ScopedTask(const Domain &d, const StringHandle &s) : _domain(d) {
__itt_task_begin(d, __itt_null, __itt_null, s);
}
ScopedTask(ScopedTask &&other) {
*this = std::move(other);
}
ScopedTask &operator=(ScopedTask &&other) {
_domain = other._domain;
other._domain = nullptr;
return *this;
}
/// \brief Prematurely end this task.
void end() {
if (_domain)
__itt_task_end(_domain);
_domain = nullptr;
}
~ScopedTask() { end(); }
};
/// \brief A specific point in time. Allows metadata to be associated.
class Marker {
public:
Marker(const Domain &d, const StringHandle &s) {
__itt_marker(d, __itt_null, s, __itt_scope_global);
}
};
#else
class Domain {
public:
Domain(const char *name) {}
};
class StringHandle {
public:
StringHandle(const char *name) {}
};
class ScopedTask {
public:
ScopedTask(const Domain &d, const StringHandle &s) {}
void end() {}
};
class Marker {
public:
Marker(const Domain &d, const StringHandle &s) {}
};
#endif
inline const Domain &getDefaultDomain() {
static Domain domain("org.llvm.lld");
return domain;
}
} // end namespace lld.
#endif

View File

@ -9,6 +9,7 @@
#include "lld/Core/PassManager.h"
#include "lld/Core/Instrumentation.h"
#include "lld/Core/Pass.h"
#include "llvm/Support/ErrorOr.h"
@ -16,6 +17,7 @@
namespace lld {
ErrorOr<void> PassManager::runOnFile(MutableFile &mf) {
for (auto &pass : _passes) {
ScopedTask task(getDefaultDomain(), "Pass");
pass->perform(mf);
}
return llvm::error_code::success();

View File

@ -11,7 +11,8 @@
#define DEBUG_TYPE "LayoutPass"
#include "lld/Passes/LayoutPass.h"
#include "llvm/Support/Debug.h"
#include "lld/Core/Instrumentation.h"
#include "llvm/Support/Debug.h"
@ -133,6 +134,7 @@ bool LayoutPass::CompareAtoms::operator()(const DefinedAtom *left,
/// targetAtom until the targetAtom has all atoms of size 0, then chain the
/// targetAtoms and its tree to the current chain
void LayoutPass::buildFollowOnTable(MutableFile::DefinedAtomRange &range) {
ScopedTask task(getDefaultDomain(), "LayoutPass::buildFollowOnTable");
for (auto ai : range) {
for (const Reference *r : *ai) {
if (r->kind() == lld::Reference::kindLayoutAfter) {
@ -250,6 +252,7 @@ void LayoutPass::buildFollowOnTable(MutableFile::DefinedAtomRange &range) {
/// if not add the atom to the chain, so that the current atom is part of the
/// the chain where the rootAtom is in
void LayoutPass::buildInGroupTable(MutableFile::DefinedAtomRange &range) {
ScopedTask task(getDefaultDomain(), "LayoutPass::buildInGroupTable");
// This table would convert precededby references to follow on
// references so that we have only one table
for (auto ai : range) {
@ -336,6 +339,7 @@ void LayoutPass::buildInGroupTable(MutableFile::DefinedAtomRange &range) {
/// same chain), chain all the atoms that are lead by the targetAtom into
/// the current chain
void LayoutPass::buildPrecededByTable(MutableFile::DefinedAtomRange &range) {
ScopedTask task(getDefaultDomain(), "LayoutPass::buildPrecededByTable");
// This table would convert precededby references to follow on
// references so that we have only one table
for (auto ai : range) {
@ -400,6 +404,7 @@ void LayoutPass::buildPrecededByTable(MutableFile::DefinedAtomRange &range) {
/// already assigned skip the atom and move to the next. This is the
/// main map thats used to sort the atoms while comparing two atoms together
void LayoutPass::buildOrdinalOverrideMap(MutableFile::DefinedAtomRange &range) {
ScopedTask task(getDefaultDomain(), "LayoutPass::buildOrdinalOverrideMap");
uint64_t index = 0;
for (auto ai : range) {
const DefinedAtom *atom = ai;