diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-01-22 00:24:57 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-01-22 00:24:57 +0000 |
commit | e5df59ff78faebd897e81907606ce6074aac0df6 (patch) | |
tree | 7f1ba19983a42f716c7643dd07244aa4a9531790 /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | 343e4964733d0063de2551a93d912b93880cada9 (diff) | |
download | bcm5719-llvm-e5df59ff78faebd897e81907606ce6074aac0df6.tar.gz bcm5719-llvm-e5df59ff78faebd897e81907606ce6074aac0df6.zip |
Emit DeferredDeclsToEmit in a DFS order.
Currently we emit DeferredDeclsToEmit in reverse order. This patch changes that.
The advantages of the change are that
* The output order is a bit closer to the source order. The change to
test/CodeGenCXX/pod-member-memcpys.cpp is a good example.
* If we decide to deffer more, it will not cause as large changes in the
estcases as it would without this patch.
llvm-svn: 226751
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0c8d4f65f09..c710b5bdad0 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1084,24 +1084,28 @@ void CodeGenModule::EmitDeferred() { // previously unused static decl may become used during the generation of code // for a static function, iterate until no changes are made. - while (true) { - if (!DeferredVTables.empty()) { - EmitDeferredVTables(); - - // Emitting a v-table doesn't directly cause more v-tables to - // become deferred, although it can cause functions to be - // emitted that then need those v-tables. - assert(DeferredVTables.empty()); - } + if (!DeferredVTables.empty()) { + EmitDeferredVTables(); - // Stop if we're out of both deferred v-tables and deferred declarations. - if (DeferredDeclsToEmit.empty()) - break; + // Emitting a v-table doesn't directly cause more v-tables to + // become deferred, although it can cause functions to be + // emitted that then need those v-tables. + assert(DeferredVTables.empty()); + } + + // Stop if we're out of both deferred v-tables and deferred declarations. + if (DeferredDeclsToEmit.empty()) + return; + + // Grab the list of decls to emit. If EmitGlobalDefinition schedules more + // work, it will not interfere with this. + std::vector<DeferredGlobal> CurDeclsToEmit; + CurDeclsToEmit.swap(DeferredDeclsToEmit); - DeferredGlobal &G = DeferredDeclsToEmit.back(); + for (DeferredGlobal &G : CurDeclsToEmit) { GlobalDecl D = G.GD; llvm::GlobalValue *GV = G.GV; - DeferredDeclsToEmit.pop_back(); + G.GV = nullptr; assert(!GV || GV == GetGlobalValue(getMangledName(D))); if (!GV) @@ -1118,6 +1122,14 @@ void CodeGenModule::EmitDeferred() { // Otherwise, emit the definition and move on to the next one. EmitGlobalDefinition(D, GV); + + // If we found out that we need to emit more decls, do that recursively. + // This has the advantage that the decls are emitted in a DFS and related + // ones are close together, which is convenient for testing. + if (!DeferredVTables.empty() || !DeferredDeclsToEmit.empty()) { + EmitDeferred(); + assert(DeferredVTables.empty() && DeferredDeclsToEmit.empty()); + } } } |