~LTOCodeGenerator();
/// Merge given module. Return true on success.
+ ///
+ /// Resets \a HasVerifiedInput.
bool addModule(struct LTOModule *);
/// Set the destination module.
+ ///
+ /// Resets \a HasVerifiedInput.
void setModule(std::unique_ptr<LTOModule> M);
void setTargetOptions(TargetOptions Options);
/// Write the merged module to the file specified by the given path. Return
/// true on success.
+ ///
+ /// Calls \a verifyMergedModuleOnce().
bool writeMergedModules(const char *Path);
/// Compile the merged module into a *single* output file; the path to output
bool DisableVectorization);
/// Optimizes the merged module. Returns true on success.
+ ///
+ /// Calls \a verifyMergedModuleOnce().
bool optimize(bool DisableVerify, bool DisableInline, bool DisableGVNLoadPRE,
bool DisableVectorization);
/// than one element, code generation is done in parallel with out.size()
/// threads. Output files will be written to members of out. Returns true on
/// success.
+ ///
+ /// Calls \a verifyMergedModuleOnce().
bool compileOptimized(ArrayRef<raw_pwrite_stream *> Out);
void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
private:
void initializeLTOPasses();
+ /// Verify the merged module on first call.
+ ///
+ /// Sets \a HasVerifiedInput on first call and doesn't run again on the same
+ /// input.
+ void verifyMergedModuleOnce();
+
bool compileOptimizedToFile(const char **Name);
void restoreLinkageForExternals();
void applyScopeRestrictions();
std::unique_ptr<TargetMachine> TargetMach;
bool EmitDwarfDebugInfo = false;
bool ScopeRestrictionsDone = false;
+ bool HasVerifiedInput = false;
Reloc::Model RelocModel = Reloc::Default;
StringSet<> MustPreserveSymbols;
StringSet<> AsmUndefinedRefs;
for (int i = 0, e = undefs.size(); i != e; ++i)
AsmUndefinedRefs[undefs[i]] = 1;
+ // We've just changed the input, so let's make sure we verify it.
+ HasVerifiedInput = false;
+
return !ret;
}
const std::vector<const char*> &Undefs = Mod->getAsmUndefinedRefs();
for (int I = 0, E = Undefs.size(); I != E; ++I)
AsmUndefinedRefs[Undefs[I]] = 1;
+
+ // We've just changed the input, so let's make sure we verify it.
+ HasVerifiedInput = false;
}
void LTOCodeGenerator::setTargetOptions(TargetOptions Options) {
if (!determineTarget())
return false;
+ // We always run the verifier once on the merged module.
+ verifyMergedModuleOnce();
+
// mark which symbols can not be internalized
applyScopeRestrictions();
externalize);
}
+void LTOCodeGenerator::verifyMergedModuleOnce() {
+ // Only run on the first call.
+ if (HasVerifiedInput)
+ return;
+ HasVerifiedInput = true;
+
+ if (verifyModule(*MergedModule, &dbgs()))
+ report_fatal_error("Broken module found, compilation aborted!");
+}
+
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline,
bool DisableGVNLoadPRE,
// We always run the verifier once on the merged module, the `DisableVerify`
// parameter only applies to subsequent verify.
- if (verifyModule(*MergedModule, &dbgs()))
- report_fatal_error("Broken module found, compilation aborted!");
+ verifyMergedModuleOnce();
// Mark which symbols can not be internalized
this->applyScopeRestrictions();
if (!this->determineTarget())
return false;
+ // We always run the verifier once on the merged module. If it has already
+ // been called in optimize(), this call will return early.
+ verifyMergedModuleOnce();
+
legacy::PassManager preCodeGenPasses;
// If the bitcode files contain ARC code and were compiled with optimization,