Skip to content

Commit 7db390c

Browse files
committed
Revert "[LTO] Use lto::backend for code generation."
This reverts commit 6a59f05, because it is causing failures on green dragon.
1 parent 0a17664 commit 7db390c

File tree

5 files changed

+103
-85
lines changed

5 files changed

+103
-85
lines changed

llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@
4141
#include "llvm/ADT/StringSet.h"
4242
#include "llvm/IR/GlobalValue.h"
4343
#include "llvm/IR/Module.h"
44-
#include "llvm/LTO/Config.h"
45-
#include "llvm/LTO/LTO.h"
4644
#include "llvm/Support/CommandLine.h"
4745
#include "llvm/Support/Error.h"
4846
#include "llvm/Support/ToolOutputFile.h"
@@ -75,10 +73,6 @@ struct LTOCodeGenerator {
7573
LTOCodeGenerator(LLVMContext &Context);
7674
~LTOCodeGenerator();
7775

78-
/// Return a lto::Config object which contains the options set in
79-
/// LTOCodeGenerator.
80-
lto::Config toConfig() const;
81-
8276
/// Merge given module. Return true on success.
8377
///
8478
/// Resets \a HasVerifiedInput.
@@ -171,14 +165,14 @@ struct LTOCodeGenerator {
171165
/// if the compilation was not successful.
172166
std::unique_ptr<MemoryBuffer> compileOptimized();
173167

174-
/// Compile the merged optimized module \p ParallelismLevel output files each
168+
/// Compile the merged optimized module into out.size() output files each
175169
/// representing a linkable partition of the module. If out contains more
176-
/// than one element, code generation is done in parallel with \p
177-
/// ParallelismLevel threads. Output files will be written to the streams
178-
/// created using the \p AddStream callback. Returns true on success.
170+
/// than one element, code generation is done in parallel with out.size()
171+
/// threads. Output files will be written to members of out. Returns true on
172+
/// success.
179173
///
180174
/// Calls \a verifyMergedModuleOnce().
181-
bool compileOptimized(lto::AddStreamFn AddStream, unsigned ParallelismLevel);
175+
bool compileOptimized(ArrayRef<raw_pwrite_stream *> Out);
182176

183177
/// Enable the Freestanding mode: indicate that the optimizer should not
184178
/// assume builtins are present on the target.
@@ -194,6 +188,8 @@ struct LTOCodeGenerator {
194188
void DiagnosticHandler(const DiagnosticInfo &DI);
195189

196190
private:
191+
void initializeLTOPasses();
192+
197193
/// Verify the merged module on first call.
198194
///
199195
/// Sets \a HasVerifiedInput on first call and doesn't run again on the same

llvm/lib/LTO/LTOCodeGenerator.cpp

Lines changed: 85 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
#include "llvm/IR/Verifier.h"
3838
#include "llvm/InitializePasses.h"
3939
#include "llvm/LTO/LTO.h"
40-
#include "llvm/LTO/LTOBackend.h"
4140
#include "llvm/LTO/legacy/LTOModule.h"
4241
#include "llvm/LTO/legacy/UpdateCompilerUsed.h"
4342
#include "llvm/Linker/Linker.h"
@@ -124,29 +123,41 @@ LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
124123
TheLinker(new Linker(*MergedModule)) {
125124
Context.setDiscardValueNames(LTODiscardValueNames);
126125
Context.enableDebugTypeODRUniquing();
126+
initializeLTOPasses();
127127
}
128128

129129
LTOCodeGenerator::~LTOCodeGenerator() {}
130130

131-
lto::Config LTOCodeGenerator::toConfig() const {
132-
lto::Config Conf;
133-
Conf.CGFileType = FileType;
134-
Conf.CPU = MCpu;
135-
Conf.MAttrs = MAttrs;
136-
Conf.RelocModel = RelocModel;
137-
Conf.Options = Options;
138-
Conf.CodeModel = None;
139-
Conf.StatsFile = LTOStatsFile;
140-
Conf.OptLevel = OptLevel;
141-
Conf.Freestanding = Freestanding;
142-
Conf.PTO.LoopVectorization = OptLevel > 1;
143-
Conf.PTO.SLPVectorization = OptLevel > 1;
144-
Conf.DisableVerify = DisableVerify;
145-
Conf.PreCodeGenPassesHook = [](legacy::PassManager &PM) {
146-
PM.add(createObjCARCContractPass());
147-
};
148-
149-
return Conf;
131+
// Initialize LTO passes. Please keep this function in sync with
132+
// PassManagerBuilder::populateLTOPassManager(), and make sure all LTO
133+
// passes are initialized.
134+
void LTOCodeGenerator::initializeLTOPasses() {
135+
PassRegistry &R = *PassRegistry::getPassRegistry();
136+
137+
initializeInternalizeLegacyPassPass(R);
138+
initializeIPSCCPLegacyPassPass(R);
139+
initializeGlobalOptLegacyPassPass(R);
140+
initializeConstantMergeLegacyPassPass(R);
141+
initializeDAHPass(R);
142+
initializeInstructionCombiningPassPass(R);
143+
initializeSimpleInlinerPass(R);
144+
initializePruneEHPass(R);
145+
initializeGlobalDCELegacyPassPass(R);
146+
initializeOpenMPOptLegacyPassPass(R);
147+
initializeArgPromotionPass(R);
148+
initializeJumpThreadingPass(R);
149+
initializeSROALegacyPassPass(R);
150+
initializeAttributorLegacyPassPass(R);
151+
initializeAttributorCGSCCLegacyPassPass(R);
152+
initializePostOrderFunctionAttrsLegacyPassPass(R);
153+
initializeReversePostOrderFunctionAttrsLegacyPassPass(R);
154+
initializeGlobalsAAWrapperPassPass(R);
155+
initializeLegacyLICMPassPass(R);
156+
initializeMergedLoadStoreMotionLegacyPassPass(R);
157+
initializeGVNLegacyPassPass(R);
158+
initializeMemCpyOptLegacyPassPass(R);
159+
initializeDCELegacyPassPass(R);
160+
initializeCFGSimplifyPassPass(R);
150161
}
151162

152163
void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
@@ -257,35 +268,38 @@ bool LTOCodeGenerator::writeMergedModules(StringRef Path) {
257268
bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
258269
// make unique temp output file to put generated code
259270
SmallString<128> Filename;
271+
int FD;
260272

261-
auto AddStream =
262-
[&](size_t Task) -> std::unique_ptr<lto::NativeObjectStream> {
263-
StringRef Extension(FileType == CGFT_AssemblyFile ? "s" : "o");
273+
StringRef Extension
274+
(FileType == CGFT_AssemblyFile ? "s" : "o");
264275

265-
int FD;
266-
std::error_code EC =
267-
sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename);
268-
if (EC)
269-
emitError(EC.message());
276+
std::error_code EC =
277+
sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename);
278+
if (EC) {
279+
emitError(EC.message());
280+
return false;
281+
}
270282

271-
return std::make_unique<lto::NativeObjectStream>(
272-
std::make_unique<llvm::raw_fd_ostream>(FD, true));
273-
};
283+
// generate object file
284+
ToolOutputFile objFile(Filename, FD);
274285

275-
bool genResult = compileOptimized(AddStream, 1);
286+
bool genResult = compileOptimized(&objFile.os());
287+
objFile.os().close();
288+
if (objFile.os().has_error()) {
289+
emitError((Twine("could not write object file: ") + Filename + ": " +
290+
objFile.os().error().message())
291+
.str());
292+
objFile.os().clear_error();
293+
sys::fs::remove(Twine(Filename));
294+
return false;
295+
}
276296

297+
objFile.keep();
277298
if (!genResult) {
278299
sys::fs::remove(Twine(Filename));
279300
return false;
280301
}
281302

282-
// If statistics were requested, save them to the specified file or
283-
// print them out after codegen.
284-
if (StatsFile)
285-
PrintStatisticsJSON(StatsFile->os());
286-
else if (AreStatisticsEnabled())
287-
PrintStatistics();
288-
289303
NativeObjectPath = Filename.c_str();
290304
*Name = NativeObjectPath.c_str();
291305
return true;
@@ -554,43 +568,57 @@ bool LTOCodeGenerator::optimize() {
554568
// Write LTOPostLink flag for passes that require all the modules.
555569
MergedModule->addModuleFlag(Module::Error, "LTOPostLink", 1);
556570

571+
// Instantiate the pass manager to organize the passes.
572+
legacy::PassManager passes;
573+
557574
// Add an appropriate DataLayout instance for this module...
558575
MergedModule->setDataLayout(TargetMach->createDataLayout());
559576

560-
lto::Config Conf = toConfig();
577+
passes.add(
578+
createTargetTransformInfoWrapperPass(TargetMach->getTargetIRAnalysis()));
561579

562-
ModuleSummaryIndex CombinedIndex(false);
563-
TargetMach = createTargetMachine();
564-
if (!opt(Conf, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false,
565-
/*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
566-
/*CmdArgs*/ std::vector<uint8_t>())) {
567-
emitError("LTO middle-end optimizations failed");
568-
return false;
569-
}
580+
Triple TargetTriple(TargetMach->getTargetTriple());
581+
PassManagerBuilder PMB;
582+
PMB.LoopVectorize = true;
583+
PMB.SLPVectorize = true;
584+
PMB.Inliner = createFunctionInliningPass();
585+
PMB.LibraryInfo = new TargetLibraryInfoImpl(TargetTriple);
586+
if (Freestanding)
587+
PMB.LibraryInfo->disableAllFunctions();
588+
PMB.OptLevel = OptLevel;
589+
PMB.VerifyInput = !DisableVerify;
590+
PMB.VerifyOutput = !DisableVerify;
591+
592+
PMB.populateLTOPassManager(passes);
593+
594+
// Run our queue of passes all at once now, efficiently.
595+
passes.run(*MergedModule);
570596

571597
return true;
572598
}
573599

574-
bool LTOCodeGenerator::compileOptimized(lto::AddStreamFn AddStream,
575-
unsigned ParallelismLevel) {
600+
bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out) {
576601
if (!this->determineTarget())
577602
return false;
578603

579604
// We always run the verifier once on the merged module. If it has already
580605
// been called in optimize(), this call will return early.
581606
verifyMergedModuleOnce();
582607

608+
legacy::PassManager preCodeGenPasses;
609+
610+
// If the bitcode files contain ARC code and were compiled with optimization,
611+
// the ObjCARCContractPass must be run, so do it unconditionally here.
612+
preCodeGenPasses.add(createObjCARCContractPass());
613+
preCodeGenPasses.run(*MergedModule);
614+
583615
// Re-externalize globals that may have been internalized to increase scope
584616
// for splitting
585617
restoreLinkageForExternals();
586618

587-
lto::Config Conf = toConfig();
588-
ModuleSummaryIndex CombinedIndex(false);
589-
590-
Error Err =
591-
backend(Conf, AddStream, ParallelismLevel, *MergedModule, CombinedIndex);
592-
assert(!Err && "unexpected code-generation failure");
593-
(void)Err;
619+
splitCodeGen(
620+
*MergedModule, Out, {}, [&]() { return createTargetMachine(); }, FileType,
621+
ShouldRestoreGlobalsLinkage);
594622

595623
// If statistics were requested, save them to the specified file or
596624
// print them out after codegen.

llvm/test/LTO/X86/disable-verify.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ target triple = "x86_64-apple-macosx10.10.0"
77

88
; -disable-verify should disable verification from the optimization pipeline.
99
; CHECK: Pass Arguments:
10-
; CHECK-NOT: -verify {{.*}} -verify
10+
; CHECK-NOT: -verify
1111

1212
; VERIFY: Pass Arguments: {{.*}} -verify {{.*}} -verify
1313

llvm/test/tools/lto/print-stats.ll

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,5 @@
55

66
target triple = "x86_64-apple-macosx10.8.0"
77

8-
define i32 @test(i32 %a) {
9-
%r = add i32 %a, 1
10-
%r.1 = add i32 1, %a
11-
%r.2 = add i32 %r, %r.1
12-
ret i32 %r.2
13-
}
14-
158
; STATS: Statistics Collected
169
; NO_STATS-NOT: Statistics Collected

llvm/tools/llvm-lto/llvm-lto.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,24 +1041,25 @@ int main(int argc, char **argv) {
10411041
error("writing merged module failed.");
10421042
}
10431043

1044-
auto AddStream =
1045-
[&](size_t Task) -> std::unique_ptr<lto::NativeObjectStream> {
1044+
std::list<ToolOutputFile> OSs;
1045+
std::vector<raw_pwrite_stream *> OSPtrs;
1046+
for (unsigned I = 0; I != Parallelism; ++I) {
10461047
std::string PartFilename = OutputFilename;
10471048
if (Parallelism != 1)
1048-
PartFilename += "." + utostr(Task);
1049-
1049+
PartFilename += "." + utostr(I);
10501050
std::error_code EC;
1051-
auto S =
1052-
std::make_unique<raw_fd_ostream>(PartFilename, EC, sys::fs::OF_None);
1051+
OSs.emplace_back(PartFilename, EC, sys::fs::OF_None);
10531052
if (EC)
10541053
error("error opening the file '" + PartFilename + "': " + EC.message());
1055-
return std::make_unique<lto::NativeObjectStream>(std::move(S));
1056-
};
1054+
OSPtrs.push_back(&OSs.back().os());
1055+
}
10571056

1058-
if (!CodeGen.compileOptimized(AddStream, Parallelism))
1057+
if (!CodeGen.compileOptimized(OSPtrs))
10591058
// Diagnostic messages should have been printed by the handler.
10601059
error("error compiling the code");
10611060

1061+
for (ToolOutputFile &OS : OSs)
1062+
OS.keep();
10621063
} else {
10631064
if (Parallelism != 1)
10641065
error("-j must be specified together with -o");

0 commit comments

Comments
 (0)