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 | |
| 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')
| -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()); +    }    }  }  | 

