LLVM: lib/CGData/CodeGenData.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

22

23#define DEBUG_TYPE "cg-data"

24

25using namespace llvm;

26using namespace cgdata;

27

30 cl::desc("Emit CodeGen Data into custom sections"));

33 cl::desc("File path to where .cgdata file is read"));

34

35namespace llvm {

38 cl::desc("Enable two-round ThinLTO code generation. The first round "

39 "emits codegen data, while the second round uses the emitted "

40 "codegen data for further optimizations."));

41}

42

44 const std::string &ErrMsg = "") {

45 std::string Msg;

47

48 switch (Err) {

50 OS << "success";

51 break;

53 OS << "end of File";

54 break;

56 OS << "invalid codegen data (bad magic)";

57 break;

59 OS << "invalid codegen data (file header is corrupt)";

60 break;

62 OS << "empty codegen data";

63 break;

65 OS << "malformed codegen data";

66 break;

68 OS << "unsupported codegen data version";

69 break;

70 }

71

72

73 if (!ErrMsg.empty())

74 OS << ": " << ErrMsg;

75

76 return OS.str();

77}

78

79namespace {

80

81

82

83

84class CGDataErrorCategoryType : public std::error_category {

85 const char *name() const noexcept override { return "llvm.cgdata"; }

86

87 std::string message(int IE) const override {

89 }

90};

91

92}

93

95 static CGDataErrorCategoryType ErrorCategory;

96 return ErrorCategory;

97}

98

102

104

105namespace {

106

107const char *CodeGenDataSectNameCommon[] = {

108#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \

109 SectNameCommon,

111};

112

113const char *CodeGenDataSectNameCoff[] = {

114#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \

115 SectNameCoff,

117};

118

119const char *CodeGenDataSectNamePrefix[] = {

120#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Prefix,

122};

123

124}

125

126namespace llvm {

127

130 bool AddSegmentInfo) {

131 std::string SectName;

132

134 SectName = CodeGenDataSectNamePrefix[CGSK];

135

137 SectName += CodeGenDataSectNameCoff[CGSK];

138 else

139 SectName += CodeGenDataSectNameCommon[CGSK];

140

141 return SectName;

142}

143

144std::unique_ptr CodeGenData::Instance = nullptr;

145std::once_flag CodeGenData::OnceFlag;

146

148 std::call_once(CodeGenData::OnceFlag, []() {

149 Instance = std::unique_ptr(new CodeGenData());

150

152 Instance->EmitCGData = true;

154

155

156

157

160 if (Error E = ReaderOrErr.takeError()) {

162 return;

163 }

164

165 auto Reader = ReaderOrErr->get();

166 if (Reader->hasOutlinedHashTree())

167 Instance->publishOutlinedHashTree(Reader->releaseOutlinedHashTree());

168 if (Reader->hasStableFunctionMap())

169 Instance->publishStableFunctionMap(Reader->releaseStableFunctionMap());

170 }

171 });

172 return *Instance;

173}

174

176

179

180 static_assert(std::is_standard_layout_vllvm::IndexedCGData::Header,

181 "The header should be standard layout type since we use offset "

182 "of fields to read.");

191

193 "Please update the offset computation below if a new field has "

194 "been added to the header.");

195 H.OutlinedHashTreeOffset =

197 if (H.Version >= 2)

198 H.StableFunctionMapOffset =

200

201 return H;

202}

203

204}

205

207

210 if (!Whence.empty())

211 errs() << Whence << ": ";

212 errs() << Message << "\n";

213 if (!Hint.empty())

215}

216

224

228 << " in Task " << Task << "\n");

233 std::unique_ptr &Stream = *StreamOrErr;

234

236 true);

237

238 if (Error Err = Stream->commit())

240}

241

243 unsigned Task,

247 << " in Task " << Task << "\n");

249 IRFiles[Task], "in-memory IR file", false);

250 auto RestoredModule = parseBitcodeFile(*FileBuffer, Context);

251 if (!RestoredModule)

253 Twine("Failed to parse optimized bitcode loaded for Task: ") +

254 Twine(Task) + "\n");

255

256

257 (*RestoredModule)->setModuleIdentifier(OrigModule.getModuleIdentifier());

258 return std::move(*RestoredModule);

259}

260

265 for (auto File : ObjFiles) {

266 if (File.empty())

267 continue;

269 File, "in-memory object file", false);

272 if (!BinOrErr)

274

275 std::unique_ptrobject::ObjectFile &Obj = BinOrErr.get();

277 Obj.get(), GlobalOutlineRecord, GlobalStableFunctionMapRecord,

278 &CombinedHash))

279 return E;

280 }

281

282 GlobalStableFunctionMapRecord.finalize();

283

284 if (!GlobalOutlineRecord.empty())

286 if (!GlobalStableFunctionMapRecord.empty())

288 std::move(GlobalStableFunctionMapRecord.FunctionMap));

289

290 return CombinedHash;

291}

292

293}

294

295}

static std::string getCGDataErrString(cgdata_error Err, const std::string &ErrMsg="")

Definition CodeGenData.cpp:43

static cl::opt< std::string > CodeGenDataUsePath("codegen-data-use-path", cl::init(""), cl::Hidden, cl::desc("File path to where .cgdata file is read"))

static cl::opt< bool > CodeGenDataGenerate("codegen-data-generate", cl::init(false), cl::Hidden, cl::desc("Emit CodeGen Data into custom sections"))

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

Represents a module in a bitcode file.

StringRef getModuleIdentifier() const

std::string message() const override

Return the error message as a string.

Definition CodeGenData.cpp:99

static LLVM_ABI Expected< std::unique_ptr< CodeGenDataReader > > create(const Twine &Path, vfs::FileSystem &FS)

Factory method to create an appropriately typed reader for the given codegen data file path and file ...

static LLVM_ABI Error mergeFromObjectFile(const object::ObjectFile *Obj, OutlinedHashTreeRecord &GlobalOutlineRecord, StableFunctionMapRecord &GlobalFunctionMapRecord, stable_hash *CombinedHash=nullptr)

Extract the cgdata embedded in sections from the given object file and merge them into the GlobalOutl...

static LLVM_ABI CodeGenData & getInstance()

Definition CodeGenData.cpp:147

Lightweight error class with error context and mandatory checking.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

reference get()

Returns a reference to the stored T value.

This is an important class for using LLVM in a threaded context.

static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)

Open the specified memory range as a MemoryBuffer.

A Module instance is used to store all the information related to an LLVM module.

const std::string & getModuleIdentifier() const

Get the module identifier which is, essentially, the name of the module.

StringRef - Represent a constant reference to a string, i.e.

constexpr bool empty() const

empty - Check if the string is empty.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

static LLVM_ABI raw_ostream & warning()

Convenience method for printing "warning: " to stderr.

static LLVM_ABI raw_ostream & note()

Convenience method for printing "note: " to stderr.

static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)

A raw_ostream that writes to an std::string.

std::string & str()

Returns the string's reference.

LLVM_ABI Expected< stable_hash > mergeCodeGenData(ArrayRef< StringRef > ObjectFiles)

Merge the codegen data from the scratch objects ObjectFiles from the first codegen round.

Definition CodeGenData.cpp:261

void publishOutlinedHashTree(std::unique_ptr< OutlinedHashTree > HashTree)

LLVM_ABI void warn(Error E, StringRef Whence="")

Definition CodeGenData.cpp:217

void publishStableFunctionMap(std::unique_ptr< StableFunctionMap > FunctionMap)

LLVM_ABI void saveModuleForTwoRounds(const Module &TheModule, unsigned Task, AddStreamFn AddStream)

Save TheModule before the first codegen round.

Definition CodeGenData.cpp:225

LLVM_ABI std::unique_ptr< Module > loadModuleForTwoRounds(BitcodeModule &OrigModule, unsigned Task, LLVMContext &Context, ArrayRef< StringRef > IRFiles)

Load the optimized bitcode module for the second codegen round.

Definition CodeGenData.cpp:242

initializer< Ty > init(const Ty &Val)

value_type readNext(const CharT *&memory, endianness endian)

Read a value of a particular endianness from a buffer, and increment the buffer past that value.

LLVM_ABI IntrusiveRefCntPtr< FileSystem > getRealFileSystem()

Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI Expected< std::unique_ptr< Module > > parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context, ParserCallbacks Callbacks={})

Read the specified bitcode file, returning the module.

LLVM_ABI void WriteBitcodeToFile(const Module &M, raw_ostream &Out, bool ShouldPreserveUseListOrder=false, const ModuleSummaryIndex *Index=nullptr, bool GenerateHash=false, ModuleHash *ModHash=nullptr)

Write the specified module to the specified raw output stream.

cl::opt< bool > CodeGenDataThinLTOTwoRounds("codegen-data-thinlto-two-rounds", cl::init(false), cl::Hidden, cl::desc("Enable two-round ThinLTO code generation. The first round " "emits codegen data, while the second round uses the emitted " "codegen data for further optimizations."))

void handleAllErrors(Error E, HandlerTs &&... Handlers)

Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...

uint64_t stable_hash

An opaque object representing a stable hash code.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

LLVM_ABI const std::error_category & cgdata_category()

Definition CodeGenData.cpp:94

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

std::function< Expected< std::unique_ptr< CachedFileStream > >( unsigned Task, const Twine &ModuleName)> AddStreamFn

This type defines the callback to add a file that is generated on the fly.

LLVM_ABI std::string getCodeGenDataSectionName(CGDataSectKind CGSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)

Definition CodeGenData.cpp:128

std::unique_ptr< OutlinedHashTree > HashTree

The structure of the serialized stable function map is as follows:

void finalize(bool SkipTrim=false)

Finalize the stable function map by trimming content.

std::unique_ptr< StableFunctionMap > FunctionMap