Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stablefunctest2 #109522

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1320,10 +1320,10 @@ static void runThinLTOBackend(
Conf.CGFileType = getCodeGenFileType(Action);
break;
}
if (Error E =
thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
/* ModuleMap */ nullptr, CGOpts.CmdArgs)) {
if (Error E = thinBackend(
Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
/* ModuleMap */ nullptr, Conf.CodeGenOnly, CGOpts.CmdArgs)) {
handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
});
Expand Down
1 change: 1 addition & 0 deletions lld/MachO/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ add_lld_library(lldMachO
Core
DebugInfoDWARF
Demangle
IPO
LTO
MC
ObjCARCOpts
Expand Down
19 changes: 17 additions & 2 deletions lld/MachO/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1326,7 +1326,8 @@ static void codegenDataGenerate() {
TimeTraceScope timeScope("Generating codegen data");

OutlinedHashTreeRecord globalOutlineRecord;
for (ConcatInputSection *isec : inputSections)
StableFunctionMapRecord globalMergeRecord;
for (ConcatInputSection *isec : inputSections) {
if (isec->getSegName() == segment_names::data &&
isec->getName() == section_names::outlinedHashTree) {
// Read outlined hash tree from each section.
Expand All @@ -1337,11 +1338,25 @@ static void codegenDataGenerate() {
// Merge it to the global hash tree.
globalOutlineRecord.merge(localOutlineRecord);
}
if (isec->getSegName() == segment_names::data &&
isec->getName() == section_names::functionmap) {
// Read stable functions from each section.
StableFunctionMapRecord localMergeRecord;
auto *data = isec->data.data();
localMergeRecord.deserialize(data);

// Merge it to the global function map.
globalMergeRecord.merge(localMergeRecord);
}
}

globalMergeRecord.finalize();

CodeGenDataWriter Writer;
if (!globalOutlineRecord.empty())
Writer.addRecord(globalOutlineRecord);

if (!globalMergeRecord.empty())
Writer.addRecord(globalMergeRecord);
std::error_code EC;
auto fileName = config->codegenDataGeneratePath;
assert(!fileName.empty());
Expand Down
1 change: 1 addition & 0 deletions lld/MachO/InputSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ constexpr const char const_[] = "__const";
constexpr const char lazySymbolPtr[] = "__la_symbol_ptr";
constexpr const char lazyBinding[] = "__lazy_binding";
constexpr const char literals[] = "__literals";
constexpr const char functionmap[] = "__llvm_merge";
constexpr const char moduleInitFunc[] = "__mod_init_func";
constexpr const char moduleTermFunc[] = "__mod_term_func";
constexpr const char nonLazySymbolPtr[] = "__nl_symbol_ptr";
Expand Down
9 changes: 7 additions & 2 deletions lld/MachO/LTO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/ObjCARC.h"

using namespace lld;
Expand All @@ -38,6 +39,8 @@ static std::string getThinLTOOutputFile(StringRef modulePath) {
config->thinLTOPrefixReplaceNew);
}

extern cl::opt<bool> EnableGlobalMergeFunc;

static lto::Config createConfig() {
lto::Config c;
c.Options = initTargetOptionsFromCodeGenFlags();
Expand All @@ -48,7 +51,10 @@ static lto::Config createConfig() {
c.CPU = getCPUStr();
c.MAttrs = getMAttrs();
c.DiagHandler = diagnosticHandler;

c.PreCodeGenPassesHook = [](legacy::PassManager &pm) {
if (EnableGlobalMergeFunc)
pm.add(createGlobalMergeFuncPass());
};
c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty();

c.TimeTraceEnabled = config->timeTraceEnabled;
Expand Down Expand Up @@ -97,7 +103,6 @@ BitcodeCompiler::BitcodeCompiler() {
onIndexWrite, config->thinLTOEmitIndexFiles,
config->thinLTOEmitImportsFiles);
}

ltoObj = std::make_unique<lto::LTO>(createConfig(), backend);
}

Expand Down
6 changes: 3 additions & 3 deletions lld/test/MachO/cgdata-generate.s
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

# RUN: rm -rf %t; split-file %s %t

# Synthesize raw cgdata without the header (24 byte) from the indexed cgdata.
# Synthesize raw cgdata without the header (32 byte) from the indexed cgdata.
# RUN: llvm-cgdata --convert --format binary %t/raw-1.cgtext -o %t/raw-1.cgdata
# RUN: od -t x1 -j 24 -An %t/raw-1.cgdata | tr -d '\n\r\t' | sed 's/[ ][ ]*/ /g; s/^[ ]*//; s/[ ]*$//; s/[ ]/,0x/g; s/^/0x/' > %t/raw-1-bytes.txt
# RUN: od -t x1 -j 32 -An %t/raw-1.cgdata | tr -d '\n\r\t' | sed 's/[ ][ ]*/ /g; s/^[ ]*//; s/[ ]*$//; s/[ ]/,0x/g; s/^/0x/' > %t/raw-1-bytes.txt
# RUN: sed "s/<RAW_BYTES>/$(cat %t/raw-1-bytes.txt)/g" %t/merge-template.s > %t/merge-1.s
# RUN: llvm-cgdata --convert --format binary %t/raw-2.cgtext -o %t/raw-2.cgdata
# RUN: od -t x1 -j 24 -An %t/raw-2.cgdata | tr -d '\n\r\t' | sed 's/[ ][ ]*/ /g; s/^[ ]*//; s/[ ]*$//; s/[ ]/,0x/g; s/^/0x/' > %t/raw-2-bytes.txt
# RUN: od -t x1 -j 32 -An %t/raw-2.cgdata | tr -d '\n\r\t' | sed 's/[ ][ ]*/ /g; s/^[ ]*//; s/[ ]*$//; s/[ ]/,0x/g; s/^/0x/' > %t/raw-2-bytes.txt
# RUN: sed "s/<RAW_BYTES>/$(cat %t/raw-2-bytes.txt)/g" %t/merge-template.s > %t/merge-2.s

# RUN: llvm-mc -filetype obj -triple arm64-apple-darwin %t/merge-1.s -o %t/merge-1.o
Expand Down
52 changes: 51 additions & 1 deletion llvm/include/llvm/CGData/CodeGenData.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/CGData/OutlinedHashTree.h"
#include "llvm/CGData/OutlinedHashTreeRecord.h"
#include "llvm/CGData/StableFunctionMapRecord.h"
#include "llvm/IR/Module.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/ErrorHandling.h"
Expand All @@ -39,7 +40,9 @@ enum class CGDataKind {
Unknown = 0x0,
// A function outlining info.
FunctionOutlinedHashTree = 0x1,
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/FunctionOutlinedHashTree)
// A function merging info.
StableFunctionMergingMap = 0x2,
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/StableFunctionMergingMap)
};

const std::error_category &cgdata_category();
Expand Down Expand Up @@ -106,6 +109,8 @@ enum CGDataMode {
class CodeGenData {
/// Global outlined hash tree that has oulined hash sequences across modules.
std::unique_ptr<OutlinedHashTree> PublishedHashTree;
/// Global stable function map that has stable function info across modules.
std::unique_ptr<StableFunctionMap> PublishedStableFunctionMap;

/// This flag is set when -fcodegen-data-generate is passed.
/// Or, it can be mutated with -fcodegen-data-thinlto-two-rounds.
Expand All @@ -129,12 +134,18 @@ class CodeGenData {
bool hasOutlinedHashTree() {
return PublishedHashTree && !PublishedHashTree->empty();
}
bool hasStableFunctionMap() {
return PublishedStableFunctionMap && !PublishedStableFunctionMap->empty();
}

/// Returns the outlined hash tree. This can be globally used in a read-only
/// manner.
const OutlinedHashTree *getOutlinedHashTree() {
return PublishedHashTree.get();
}
const StableFunctionMap *getStableFunctionMap() {
return PublishedStableFunctionMap.get();
}

/// Returns true if we should write codegen data.
bool emitCGData() { return EmitCGData; }
Expand All @@ -145,6 +156,12 @@ class CodeGenData {
// Ensure we disable emitCGData as we do not want to read and write both.
EmitCGData = false;
}
void
publishStableFunctionMap(std::unique_ptr<StableFunctionMap> FunctionMap) {
PublishedStableFunctionMap = std::move(FunctionMap);
// Ensure we disable emitCGData as we do not want to read and write both.
EmitCGData = false;
}
};

namespace cgdata {
Expand All @@ -153,17 +170,47 @@ inline bool hasOutlinedHashTree() {
return CodeGenData::getInstance().hasOutlinedHashTree();
}

inline bool hasStableFunctionMap() {
return CodeGenData::getInstance().hasStableFunctionMap();
}

inline const OutlinedHashTree *getOutlinedHashTree() {
return CodeGenData::getInstance().getOutlinedHashTree();
}

inline const StableFunctionMap *getStableFunctionMap() {
return CodeGenData::getInstance().getStableFunctionMap();
}

inline bool emitCGData() { return CodeGenData::getInstance().emitCGData(); }

inline void
publishOutlinedHashTree(std::unique_ptr<OutlinedHashTree> HashTree) {
CodeGenData::getInstance().publishOutlinedHashTree(std::move(HashTree));
}

inline void
publishStableFunctionMap(std::unique_ptr<StableFunctionMap> FunctionMap) {
CodeGenData::getInstance().publishStableFunctionMap(std::move(FunctionMap));
}

void initializeTwoCodegenRounds();

/// Save \p TheModule before the first codegen round.
/// \p Task represents the partition number in the parallel code generation
/// process.
void saveModuleForTwoRounds(const Module &TheModule, unsigned Task);

/// Load the optimized module before the second codegen round.
std::unique_ptr<Module> loadModuleForTwoRounds(BitcodeModule &OrigModule,
unsigned Task,
LLVMContext &Context);

/// Merge the codegen data from the input files in scratch vector in ThinLTO
/// two-codegen rounds.
Error mergeCodeGenData(
const std::unique_ptr<std::vector<llvm::SmallString<0>>> InputFiles);

void warn(Error E, StringRef Whence = "");
void warn(Twine Message, std::string Whence = "", std::string Hint = "");

Expand All @@ -179,6 +226,8 @@ enum CGDataVersion {
// Version 1 is the first version. This version supports the outlined
// hash tree.
Version1 = 1,
// Version 2 supports the stable function merging map.
Version2 = 2,
CurrentVersion = CG_DATA_INDEX_VERSION
};
const uint64_t Version = CGDataVersion::CurrentVersion;
Expand All @@ -188,6 +237,7 @@ struct Header {
uint32_t Version;
uint32_t DataKind;
uint64_t OutlinedHashTreeOffset;
uint64_t StableFunctionMapOffset;

// New fields should only be added at the end to ensure that the size
// computation is correct. The methods below need to be updated to ensure that
Expand Down
12 changes: 9 additions & 3 deletions llvm/include/llvm/CGData/CodeGenData.inc
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,33 @@
#define CG_DATA_DEFINED
CG_DATA_SECT_ENTRY(CG_outline, CG_DATA_QUOTE(CG_DATA_OUTLINE_COMMON),
CG_DATA_OUTLINE_COFF, "__DATA,")
CG_DATA_SECT_ENTRY(CG_merge, CG_DATA_QUOTE(CG_DATA_MERGE_COMMON),
CG_DATA_MERGE_COFF, "__DATA,")

#undef CG_DATA_SECT_ENTRY
#endif

/* section name strings common to all targets other
than WIN32 */
#define CG_DATA_OUTLINE_COMMON __llvm_outline
#define CG_DATA_MERGE_COMMON __llvm_merge
/* Since cg data sections are not allocated, we don't need to
* access them at runtime.
*/
#define CG_DATA_OUTLINE_COFF ".loutline"
#define CG_DATA_MERGE_COFF ".lmerge"

#ifdef _WIN32
/* Runtime section names and name strings. */
#define CG_DATA_SECT_NAME CG_DATA_OUTLINE_COFF
#define CG_DATA_OUTLINE_SECT_NAME CG_DATA_OUTLINE_COFF
#define CG_DATA_MERGE_SECT_NAME CG_DATA_MERGE_COFF

#else
/* Runtime section names and name strings. */
#define CG_DATA_SECT_NAME CG_DATA_QUOTE(CG_DATA_OUTLINE_COMMON)
#define CG_DATA_OUTLINE_SECT_NAME CG_DATA_QUOTE(CG_DATA_OUTLINE_COMMON)
#define CG_DATA_MERGE_SECT_NAME CG_DATA_QUOTE(CG_DATA_MERGE_COMMON)

#endif

/* Indexed codegen data format version (start from 1). */
#define CG_DATA_INDEX_VERSION 1
#define CG_DATA_INDEX_VERSION 2
27 changes: 25 additions & 2 deletions llvm/include/llvm/CGData/CodeGenDataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "llvm/CGData/CodeGenData.h"
#include "llvm/CGData/OutlinedHashTreeRecord.h"
#include "llvm/CGData/StableFunctionMapRecord.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/VirtualFileSystem.h"

Expand All @@ -36,10 +37,15 @@ class CodeGenDataReader {
virtual CGDataKind getDataKind() const = 0;
/// Return true if the data has an outlined hash tree.
virtual bool hasOutlinedHashTree() const = 0;
/// Return true if the data has a stable function map.
virtual bool hasStableFunctionMap() const = 0;
/// Return the outlined hash tree that is released from the reader.
std::unique_ptr<OutlinedHashTree> releaseOutlinedHashTree() {
return std::move(HashTreeRecord.HashTree);
}
std::unique_ptr<StableFunctionMap> releaseStableFunctionMap() {
return std::move(FunctionMapRecord.FunctionMap);
}

/// Factory method to create an appropriately typed reader for the given
/// codegen data file path and file system.
Expand All @@ -54,14 +60,20 @@ class CodeGenDataReader {
/// Extract the cgdata embedded in sections from the given object file and
/// merge them into the GlobalOutlineRecord. This is a static helper that
/// is used by `llvm-cgdata --merge` or ThinLTO's two-codegen rounds.
static Error mergeFromObjectFile(const object::ObjectFile *Obj,
OutlinedHashTreeRecord &GlobalOutlineRecord);
static Error
mergeFromObjectFile(const object::ObjectFile *Obj,
OutlinedHashTreeRecord &GlobalOutlineRecord,
StableFunctionMapRecord &GlobalFunctionMapRecord);

protected:
/// The outlined hash tree that has been read. When it's released by
/// releaseOutlinedHashTree(), it's no longer valid.
OutlinedHashTreeRecord HashTreeRecord;

/// The stable function map that has been read. When it's released by
// releaseStableFunctionMap(), it's no longer valid.
StableFunctionMapRecord FunctionMapRecord;

/// Set the current error and return same.
Error error(cgdata_error Err, const std::string &ErrMsg = "") {
LastError = Err;
Expand Down Expand Up @@ -112,6 +124,11 @@ class IndexedCodeGenDataReader : public CodeGenDataReader {
return Header.DataKind &
static_cast<uint32_t>(CGDataKind::FunctionOutlinedHashTree);
}
/// Return true if the header indicates the data has a stable function map.
bool hasStableFunctionMap() const override {
return Header.DataKind &
static_cast<uint32_t>(CGDataKind::StableFunctionMergingMap);
}
};

/// This format is a simple text format that's suitable for test data.
Expand Down Expand Up @@ -147,6 +164,12 @@ class TextCodeGenDataReader : public CodeGenDataReader {
return static_cast<uint32_t>(DataKind) &
static_cast<uint32_t>(CGDataKind::FunctionOutlinedHashTree);
}
/// Return true if the header indicates the data has a stable function map.
/// This does not mean that the data is still available.
bool hasStableFunctionMap() const override {
return static_cast<uint32_t>(DataKind) &
static_cast<uint32_t>(CGDataKind::StableFunctionMergingMap);
}
};

} // end namespace llvm
Expand Down
Loading