summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2015-01-22 00:24:57 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2015-01-22 00:24:57 +0000
commite5df59ff78faebd897e81907606ce6074aac0df6 (patch)
tree7f1ba19983a42f716c7643dd07244aa4a9531790 /clang/lib/CodeGen/CodeGenModule.cpp
parent343e4964733d0063de2551a93d912b93880cada9 (diff)
downloadbcm5719-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.cpp40
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());
+ }
}
}
OpenPOWER on IntegriCloud