|
11 | 11 | #include "llvm/ADT/STLExtras.h" |
12 | 12 | #include "llvm/Analysis/BranchProbabilityInfo.h" |
13 | 13 | #include "llvm/IR/Analysis.h" |
| 14 | +#include "llvm/IR/Constants.h" |
14 | 15 | #include "llvm/IR/Dominators.h" |
15 | 16 | #include "llvm/IR/Function.h" |
| 17 | +#include "llvm/IR/GlobalValue.h" |
| 18 | +#include "llvm/IR/GlobalVariable.h" |
16 | 19 | #include "llvm/IR/Instructions.h" |
17 | 20 | #include "llvm/IR/LLVMContext.h" |
18 | 21 | #include "llvm/IR/MDBuilder.h" |
| 22 | +#include "llvm/IR/Module.h" |
| 23 | +#include "llvm/IR/PassManager.h" |
19 | 24 | #include "llvm/IR/ProfDataUtils.h" |
20 | 25 | #include "llvm/Support/BranchProbability.h" |
| 26 | +#include "llvm/Support/Casting.h" |
21 | 27 | #include "llvm/Support/CommandLine.h" |
22 | 28 |
|
23 | 29 | using namespace llvm; |
@@ -189,11 +195,43 @@ PreservedAnalyses ProfileInjectorPass::run(Function &F, |
189 | 195 | return PreservedAnalyses::none(); |
190 | 196 | } |
191 | 197 |
|
| 198 | +PreservedAnalyses ProfileVerifierPass::run(Module &M, |
| 199 | + ModuleAnalysisManager &MAM) { |
| 200 | + auto PopulateIgnoreList = [&](StringRef GVName) { |
| 201 | + if (const auto *CT = M.getGlobalVariable(GVName)) |
| 202 | + if (const auto *CA = |
| 203 | + dyn_cast_if_present<ConstantArray>(CT->getInitializer())) |
| 204 | + for (const auto &Elt : CA->operands()) |
| 205 | + if (const auto *CS = dyn_cast<ConstantStruct>(Elt)) |
| 206 | + if (CS->getNumOperands() >= 2 && CS->getOperand(1)) |
| 207 | + if (const auto *F = dyn_cast<Function>( |
| 208 | + CS->getOperand(1)->stripPointerCasts())) |
| 209 | + IgnoreList.insert(F); |
| 210 | + }; |
| 211 | + PopulateIgnoreList("llvm.global_ctors"); |
| 212 | + PopulateIgnoreList("llvm.global_dtors"); |
| 213 | + |
| 214 | + // expose the function-level run as public through a wrapper, so we can use |
| 215 | + // pass manager mechanisms dealing with declarations and with composing the |
| 216 | + // returned PreservedAnalyses values. |
| 217 | + struct Wrapper : PassInfoMixin<Wrapper> { |
| 218 | + ProfileVerifierPass &PVP; |
| 219 | + PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) { |
| 220 | + return PVP.run(F, FAM); |
| 221 | + } |
| 222 | + explicit Wrapper(ProfileVerifierPass &PVP) : PVP(PVP) {} |
| 223 | + }; |
| 224 | + |
| 225 | + return createModuleToFunctionPassAdaptor(Wrapper(*this)).run(M, MAM); |
| 226 | +} |
| 227 | + |
192 | 228 | PreservedAnalyses ProfileVerifierPass::run(Function &F, |
193 | 229 | FunctionAnalysisManager &FAM) { |
194 | 230 | // skip purely asm functions |
195 | 231 | if (isAsmOnly(F)) |
196 | 232 | return PreservedAnalyses::all(); |
| 233 | + if (IgnoreList.contains(&F)) |
| 234 | + return PreservedAnalyses::all(); |
197 | 235 |
|
198 | 236 | const auto EntryCount = F.getEntryCount(/*AllowSynthetic=*/true); |
199 | 237 | if (!EntryCount) { |
|
0 commit comments