|
123 | 123 | #include "llvm/Transforms/IPO.h"
|
124 | 124 | #include "llvm/Transforms/IPO/MergeFunctions.h"
|
125 | 125 | #include "llvm/Transforms/Utils/FunctionComparator.h"
|
| 126 | +#include "llvm/Transforms/Utils/ModuleUtils.h" |
126 | 127 | #include <algorithm>
|
127 | 128 | #include <cassert>
|
128 | 129 | #include <iterator>
|
@@ -228,6 +229,9 @@ class MergeFunctions {
|
228 | 229 | /// analyzed again.
|
229 | 230 | std::vector<WeakTrackingVH> Deferred;
|
230 | 231 |
|
| 232 | + /// Set of values marked as used in llvm.used and llvm.compiler.used. |
| 233 | + SmallPtrSet<GlobalValue *, 4> Used; |
| 234 | + |
231 | 235 | #ifndef NDEBUG
|
232 | 236 | /// Checks the rules of order relation introduced among functions set.
|
233 | 237 | /// Returns true, if sanity check has been passed, and false if failed.
|
@@ -410,6 +414,11 @@ static bool isEligibleForMerging(Function &F) {
|
410 | 414 | bool MergeFunctions::runOnModule(Module &M) {
|
411 | 415 | bool Changed = false;
|
412 | 416 |
|
| 417 | + SmallVector<GlobalValue *, 4> UsedV; |
| 418 | + collectUsedGlobalVariables(M, UsedV, /*CompilerUsed=*/false); |
| 419 | + collectUsedGlobalVariables(M, UsedV, /*CompilerUsed=*/true); |
| 420 | + Used.insert(UsedV.begin(), UsedV.end()); |
| 421 | + |
413 | 422 | // All functions in the module, ordered by hash. Functions with a unique
|
414 | 423 | // hash value are easily eliminated.
|
415 | 424 | std::vector<std::pair<FunctionComparator::FunctionHash, Function *>>
|
@@ -456,6 +465,7 @@ bool MergeFunctions::runOnModule(Module &M) {
|
456 | 465 | FnTree.clear();
|
457 | 466 | FNodesInTree.clear();
|
458 | 467 | GlobalNumbers.clear();
|
| 468 | + Used.clear(); |
459 | 469 |
|
460 | 470 | return Changed;
|
461 | 471 | }
|
@@ -828,7 +838,10 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) {
|
828 | 838 | // For better debugability, under MergeFunctionsPDI, we do not modify G's
|
829 | 839 | // call sites to point to F even when within the same translation unit.
|
830 | 840 | if (!G->isInterposable() && !MergeFunctionsPDI) {
|
831 |
| - if (G->hasGlobalUnnamedAddr()) { |
| 841 | + // Functions referred to by llvm.used/llvm.compiler.used are special: |
| 842 | + // there are uses of the symbol name that are not visible to LLVM, |
| 843 | + // usually from inline asm. |
| 844 | + if (G->hasGlobalUnnamedAddr() && !Used.contains(G)) { |
832 | 845 | // G might have been a key in our GlobalNumberState, and it's illegal
|
833 | 846 | // to replace a key in ValueMap<GlobalValue *> with a non-global.
|
834 | 847 | GlobalNumbers.erase(G);
|
|
0 commit comments