diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -6513,6 +6513,23 @@ operands give the execution count that each of the respective prior target functions was called. +.. _md_annotation: + +'``annotation``' Metadata +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``annotation`` metadata can be used to attach a tuple of annotation strings +to any instruction. This metadata does not impact the semantics of the program +and may only be used to provide additional insight about the program and +transformations to users. + +Example: + +.. code-block:: text + + %a.addr = alloca float*, align 8, !annotation !0 + !0 = !{!"auto-init"} + Module Flags Metadata ===================== diff --git a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h --- a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h +++ b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h @@ -88,8 +88,12 @@ /// provide more context so that non-trivial false positives can be quickly /// detected by the user. bool allowExtraAnalysis(StringRef PassName) const { - return (F->getContext().getLLVMRemarkStreamer() || - F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName)); + return OptimizationRemarkEmitter::allowExtraAnalysis(*F, PassName); + } + + static bool allowExtraAnalysis(const Function &F, StringRef PassName) { + return F.getContext().getLLVMRemarkStreamer() || + F.getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName); } private: diff --git a/llvm/include/llvm/IR/FixedMetadataKinds.def b/llvm/include/llvm/IR/FixedMetadataKinds.def --- a/llvm/include/llvm/IR/FixedMetadataKinds.def +++ b/llvm/include/llvm/IR/FixedMetadataKinds.def @@ -41,4 +41,5 @@ LLVM_FIXED_MD_KIND(MD_preserve_access_index, "llvm.preserve.access.index", 27) LLVM_FIXED_MD_KIND(MD_misexpect, "misexpect", 28) LLVM_FIXED_MD_KIND(MD_vcall_visibility, "vcall_visibility", 29) -LLVM_FIXED_MD_KIND(MD_noundef, "noundef", 30) \ No newline at end of file +LLVM_FIXED_MD_KIND(MD_noundef, "noundef", 30) +LLVM_FIXED_MD_KIND(MD_annotation, "annotation", 31) diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -73,6 +73,7 @@ void initializeAlwaysInlinerLegacyPassPass(PassRegistry&); void initializeAssumeSimplifyPassLegacyPassPass(PassRegistry &); void initializeAssumeBuilderPassLegacyPassPass(PassRegistry &); +void initializeAnnotationRemarksLegacyPass(PassRegistry &); void initializeOpenMPOptLegacyPassPass(PassRegistry &); void initializeArgPromotionPass(PassRegistry&); void initializeAssumptionCacheTrackerPass(PassRegistry&); diff --git a/llvm/include/llvm/Transforms/Scalar.h b/llvm/include/llvm/Transforms/Scalar.h --- a/llvm/include/llvm/Transforms/Scalar.h +++ b/llvm/include/llvm/Transforms/Scalar.h @@ -31,6 +31,12 @@ // FunctionPass *createAlignmentFromAssumptionsPass(); +//===----------------------------------------------------------------------===// +// +// AnnotationRemarks - Emit remarks for !annotation metadata. +// +FunctionPass *createAnnotationRemarksLegacyPass(); + //===----------------------------------------------------------------------===// // // SCCP - Sparse conditional constant propagation. diff --git a/llvm/include/llvm/Transforms/Scalar/AnnotationRemarks.h b/llvm/include/llvm/Transforms/Scalar/AnnotationRemarks.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Transforms/Scalar/AnnotationRemarks.h @@ -0,0 +1,26 @@ +//===- AnnotationRemarks.cpp - Emit remarks for !annotation MD --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// \file +// This file defines AnnotationRemarksPass for the new pass manager. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_ANNOTATION_REMARKS_H +#define LLVM_TRANSFORMS_SCALAR_ANNOTATION_REMARKS_H + +#include "llvm/IR/Function.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { +struct AnnotationRemarksPass : public PassInfoMixin { + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; +} // namespace llvm + +#endif // LLVM_TRANSFORMS_SCALAR_ANNOTATION_REMARKS_H diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -427,6 +427,7 @@ void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty); void visitDereferenceableMetadata(Instruction &I, MDNode *MD); void visitProfMetadata(Instruction &I, MDNode *MD); + void visitAnnotationMetadata(MDNode *Annotation); template bool isValidMetadataArray(const MDTuple &N); #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N); @@ -4294,6 +4295,14 @@ } } +void Verifier::visitAnnotationMetadata(MDNode *Annotation) { + Assert(isa(Annotation), "annotation must be a tuple"); + Assert(Annotation->getNumOperands() >= 1, + "annotation must have at least one operand"); + for (const MDOperand &Op : Annotation->operands()) + Assert(isa(Op.get()), "operands must be strings"); +} + /// verifyInstruction - Verify that an instruction is well formed. /// void Verifier::visitInstruction(Instruction &I) { @@ -4454,6 +4463,9 @@ if (MDNode *MD = I.getMetadata(LLVMContext::MD_prof)) visitProfMetadata(I, MD); + if (MDNode *Annotation = I.getMetadata(LLVMContext::MD_annotation)) + visitAnnotationMetadata(Annotation); + if (MDNode *N = I.getDebugLoc().getAsMDNode()) { AssertDI(isa(N), "invalid !dbg metadata attachment", &I, N); visitMDNode(*N, AreDebugLocsAllowed::Yes); diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -132,6 +132,7 @@ #include "llvm/Transforms/ObjCARC.h" #include "llvm/Transforms/Scalar/ADCE.h" #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h" +#include "llvm/Transforms/Scalar/AnnotationRemarks.h" #include "llvm/Transforms/Scalar/BDCE.h" #include "llvm/Transforms/Scalar/CallSiteSplitting.h" #include "llvm/Transforms/Scalar/ConstantHoisting.h" @@ -485,6 +486,13 @@ C(LAM); } +// Helper to add AnnotationRemarksPass. +static void addAnnotationRemarksPass(ModulePassManager &MPM) { + FunctionPassManager FPM; + FPM.addPass(AnnotationRemarksPass()); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); +} + // TODO: Investigate the cost/benefit of tail call elimination on debugging. FunctionPassManager PassBuilder::buildO1FunctionSimplificationPipeline(OptimizationLevel Level, @@ -1334,6 +1342,9 @@ // Now add the optimization pipeline. MPM.addPass(buildModuleOptimizationPipeline(Level, LTOPreLink)); + // Emit annotation remarks. + addAnnotationRemarksPass(MPM); + return MPM; } @@ -1378,6 +1389,9 @@ if (PTO.Coroutines) MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); + // Emit annotation remarks. + addAnnotationRemarksPass(MPM); + return MPM; } @@ -1417,6 +1431,9 @@ // Now add the optimization pipeline. MPM.addPass(buildModuleOptimizationPipeline(Level)); + // Emit annotation remarks. + addAnnotationRemarksPass(MPM); + return MPM; } @@ -1442,6 +1459,10 @@ // Run a second time to clean up any type tests left behind by WPD for use // in ICP. MPM.addPass(LowerTypeTestsPass(nullptr, nullptr, true)); + + // Emit annotation remarks. + addAnnotationRemarksPass(MPM); + return MPM; } @@ -1512,6 +1533,10 @@ // in ICP (which is performed earlier than this in the regular LTO // pipeline). MPM.addPass(LowerTypeTestsPass(nullptr, nullptr, true)); + + // Emit annotation remarks. + addAnnotationRemarksPass(MPM); + return MPM; } @@ -1658,6 +1683,9 @@ // Now that we have optimized the program, discard unreachable functions. MPM.addPass(GlobalDCEPass()); + // Emit annotation remarks. + addAnnotationRemarksPass(MPM); + // FIXME: Maybe enable MergeFuncs conditionally after it's ported. return MPM; } diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -193,6 +193,7 @@ FUNCTION_PASS("assume-builder", AssumeBuilderPass()) FUNCTION_PASS("assume-simplify", AssumeSimplifyPass()) FUNCTION_PASS("alignment-from-assumptions", AlignmentFromAssumptionsPass()) +FUNCTION_PASS("annotation-remarks", AnnotationRemarksPass()) FUNCTION_PASS("bdce", BDCEPass()) FUNCTION_PASS("bounds-checking", BoundsCheckingPass()) FUNCTION_PASS("break-crit-edges", BreakCriticalEdgesPass()) diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp --- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -902,6 +902,8 @@ // Rename anon globals to be able to handle them in the summary MPM.add(createNameAnonGlobalPass()); } + + MPM.add(createAnnotationRemarksLegacyPass()); } void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) { @@ -1179,6 +1181,8 @@ addExtensionsToPM(EP_FullLinkTimeOptimizationLast, PM); + PM.add(createAnnotationRemarksLegacyPass()); + if (VerifyOutput) PM.add(createVerifierPass()); } diff --git a/llvm/lib/Transforms/Scalar/AnnotationRemarks.cpp b/llvm/lib/Transforms/Scalar/AnnotationRemarks.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Transforms/Scalar/AnnotationRemarks.cpp @@ -0,0 +1,90 @@ +//===-- AnnotationRemarks.cpp - Generate remarks for annotated instrs. ----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Generate remarks for instructions marked with !annotation. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Scalar/AnnotationRemarks.h" +#include "llvm/ADT/MapVector.h" +#include "llvm/Analysis/OptimizationRemarkEmitter.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" +#include "llvm/Support/Debug.h" +#include "llvm/Transforms/Scalar.h" + +using namespace llvm; +using namespace llvm::ore; + +#define DEBUG_TYPE "annotation-remarks" +#define REMARK_PASS DEBUG_TYPE + +static void runImpl(Function &F) { + if (!OptimizationRemarkEmitter::allowExtraAnalysis(F, REMARK_PASS)) + return; + + OptimizationRemarkEmitter ORE(&F); + // For now, just generate a summary of the annotated instructions. + MapVector Mapping; + for (Instruction &I : instructions(F)) { + if (!I.hasMetadata(LLVMContext::MD_annotation)) + continue; + for (const MDOperand &Op : + I.getMetadata(LLVMContext::MD_annotation)->operands()) { + auto Iter = Mapping.insert({cast(Op.get())->getString(), 0}); + Iter.first->second++; + } + } + + Instruction *IP = &*F.begin()->begin(); + for (const auto &KV : Mapping) + ORE.emit(OptimizationRemarkAnalysis(REMARK_PASS, "AnnotationSummary", IP) + << "Annotated " << NV("count", KV.second) << " instructions with " + << NV("type", KV.first)); +} + +namespace { + +struct AnnotationRemarksLegacy : public FunctionPass { + static char ID; + + AnnotationRemarksLegacy() : FunctionPass(ID) { + initializeAnnotationRemarksLegacyPass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override { + runImpl(F); + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; + +} // end anonymous namespace + +char AnnotationRemarksLegacy::ID = 0; + +INITIALIZE_PASS_BEGIN(AnnotationRemarksLegacy, "annotation-remarks", + "Annotation Remarks", false, false) +INITIALIZE_PASS_END(AnnotationRemarksLegacy, "annotation-remarks", + "Annotation Remarks", false, false) + +FunctionPass *llvm::createAnnotationRemarksLegacyPass() { + return new AnnotationRemarksLegacy(); +} + +PreservedAnalyses AnnotationRemarksPass::run(Function &F, + FunctionAnalysisManager &AM) { + runImpl(F); + return PreservedAnalyses::all(); +} diff --git a/llvm/lib/Transforms/Scalar/CMakeLists.txt b/llvm/lib/Transforms/Scalar/CMakeLists.txt --- a/llvm/lib/Transforms/Scalar/CMakeLists.txt +++ b/llvm/lib/Transforms/Scalar/CMakeLists.txt @@ -1,6 +1,7 @@ add_llvm_component_library(LLVMScalarOpts ADCE.cpp AlignmentFromAssumptions.cpp + AnnotationRemarks.cpp BDCE.cpp CallSiteSplitting.cpp ConstantHoisting.cpp diff --git a/llvm/lib/Transforms/Scalar/Scalar.cpp b/llvm/lib/Transforms/Scalar/Scalar.cpp --- a/llvm/lib/Transforms/Scalar/Scalar.cpp +++ b/llvm/lib/Transforms/Scalar/Scalar.cpp @@ -34,6 +34,7 @@ /// ScalarOpts library. void llvm::initializeScalarOpts(PassRegistry &Registry) { initializeADCELegacyPassPass(Registry); + initializeAnnotationRemarksLegacyPass(Registry); initializeBDCELegacyPassPass(Registry); initializeAlignmentFromAssumptionsPass(Registry); initializeCallSiteSplittingLegacyPassPass(Registry); diff --git a/llvm/test/CodeGen/AMDGPU/opt-pipeline.ll b/llvm/test/CodeGen/AMDGPU/opt-pipeline.ll --- a/llvm/test/CodeGen/AMDGPU/opt-pipeline.ll +++ b/llvm/test/CodeGen/AMDGPU/opt-pipeline.ll @@ -307,6 +307,7 @@ ; GCN-O1-NEXT: Remove redundant instructions ; GCN-O1-NEXT: Hoist/decompose integer division and remainder ; GCN-O1-NEXT: Simplify the CFG +; GCN-O1-NEXT: Annotation Remarks ; GCN-O1-NEXT: Pass Arguments: ; GCN-O1-NEXT: FunctionPass Manager @@ -664,6 +665,7 @@ ; GCN-O2-NEXT: Remove redundant instructions ; GCN-O2-NEXT: Hoist/decompose integer division and remainder ; GCN-O2-NEXT: Simplify the CFG +; GCN-O2-NEXT: Annotation Remarks ; GCN-O2-NEXT: Pass Arguments: ; GCN-O2-NEXT: FunctionPass Manager @@ -1026,6 +1028,7 @@ ; GCN-O3-NEXT: Remove redundant instructions ; GCN-O3-NEXT: Hoist/decompose integer division and remainder ; GCN-O3-NEXT: Simplify the CFG +; GCN-O3-NEXT: Annotation Remarks ; GCN-O3-NEXT: Pass Arguments: ; GCN-O3-NEXT: FunctionPass Manager diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll --- a/llvm/test/Other/new-pm-defaults.ll +++ b/llvm/test/Other/new-pm-defaults.ll @@ -272,6 +272,7 @@ ; CHECK-O-NEXT: Running pass: CGProfilePass ; CHECK-O-NEXT: Running pass: GlobalDCEPass ; CHECK-O-NEXT: Running pass: ConstantMergePass +; CHECK-O-NEXT: Running pass: AnnotationRemarksPass on foo ; CHECK-O-NEXT: Running pass: PrintModulePass ; ; Make sure we get the IR back out without changes when we print the module. diff --git a/llvm/test/Other/new-pm-lto-defaults.ll b/llvm/test/Other/new-pm-lto-defaults.ll --- a/llvm/test/Other/new-pm-lto-defaults.ll +++ b/llvm/test/Other/new-pm-lto-defaults.ll @@ -104,6 +104,7 @@ ; CHECK-O2-NEXT: Running pass: SimplifyCFGPass ; CHECK-O2-NEXT: Running pass: EliminateAvailableExternallyPass ; CHECK-O2-NEXT: Running pass: GlobalDCEPass +; CHECK-O-NEXT: Running pass: AnnotationRemarksPass on foo ; CHECK-O-NEXT: Running pass: PrintModulePass ; Make sure we get the IR back out without changes when we print the module. diff --git a/llvm/test/Other/new-pm-thinlto-defaults.ll b/llvm/test/Other/new-pm-thinlto-defaults.ll --- a/llvm/test/Other/new-pm-thinlto-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-defaults.ll @@ -240,6 +240,7 @@ ; CHECK-POSTLINK-O-NEXT: Running pass: CGProfilePass ; CHECK-POSTLINK-O-NEXT: Running pass: GlobalDCEPass ; CHECK-POSTLINK-O-NEXT: Running pass: ConstantMergePass +; CHECK-O-NEXT: Running pass: AnnotationRemarksPass on foo ; CHECK-PRELINK-O-NEXT: Running pass: NameAnonGlobalPass ; CHECK-O-NEXT: Running pass: PrintModulePass diff --git a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll --- a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll @@ -209,6 +209,7 @@ ; CHECK-O-NEXT: Running pass: CGProfilePass ; CHECK-O-NEXT: Running pass: GlobalDCEPass ; CHECK-O-NEXT: Running pass: ConstantMergePass +; CHECK-O-NEXT: Running pass: AnnotationRemarksPass on foo ; CHECK-O-NEXT: Running pass: PrintModulePass ; Make sure we get the IR back out without changes when we print the module. diff --git a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll --- a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll @@ -220,6 +220,7 @@ ; CHECK-O-NEXT: Running pass: CGProfilePass ; CHECK-O-NEXT: Running pass: GlobalDCEPass ; CHECK-O-NEXT: Running pass: ConstantMergePass +; CHECK-O-NEXT: Running pass: AnnotationRemarksPass on foo ; CHECK-O-NEXT: Running pass: PrintModulePass ; Make sure we get the IR back out without changes when we print the module. diff --git a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll --- a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll @@ -218,6 +218,7 @@ ; CHECK-O-NEXT: Running pass: GlobalOptPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis on bar ; CHECK-EXT: Running pass: {{.*}}::Bye +; CHECK-O-NEXT: Running pass: AnnotationRemarksPass on foo ; CHECK-O-NEXT: Running pass: NameAnonGlobalPass ; CHECK-O-NEXT: Running pass: PrintModulePass diff --git a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll --- a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll @@ -171,6 +171,7 @@ ; CHECK-O-NEXT: Finished CGSCC pass manager run. ; CHECK-O-NEXT: Finished {{.*}}Module pass manager run. ; CHECK-O-NEXT: Running pass: GlobalOptPass +; CHECK-O-NEXT: Running pass: AnnotationRemarksPass on foo ; CHECK-O-NEXT: Running pass: NameAnonGlobalPass ; CHECK-O-NEXT: Running pass: PrintModulePass diff --git a/llvm/test/Other/opt-LTO-pipeline.ll b/llvm/test/Other/opt-LTO-pipeline.ll --- a/llvm/test/Other/opt-LTO-pipeline.ll +++ b/llvm/test/Other/opt-LTO-pipeline.ll @@ -186,6 +186,7 @@ ; CHECK-NEXT: Eliminate Available Externally Globals ; CHECK-NEXT: Dead Global Elimination ; CHECK-NEXT: FunctionPass Manager +; CHECK-NEXT: Annotation Remarks ; CHECK-NEXT: Module Verifier ; CHECK-NEXT: Bitcode Writer ; CHECK-NEXT: Pass Arguments: diff --git a/llvm/test/Other/opt-O2-pipeline.ll b/llvm/test/Other/opt-O2-pipeline.ll --- a/llvm/test/Other/opt-O2-pipeline.ll +++ b/llvm/test/Other/opt-O2-pipeline.ll @@ -311,6 +311,7 @@ ; CHECK-NEXT: Remove redundant instructions ; CHECK-NEXT: Hoist/decompose integer division and remainder ; CHECK-NEXT: Simplify the CFG +; CHECK-NEXT: Annotation Remarks ; CHECK-NEXT: Module Verifier ; CHECK-NEXT: Bitcode Writer ; CHECK-NEXT: Pass Arguments: diff --git a/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll b/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll --- a/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll +++ b/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll @@ -323,6 +323,7 @@ ; CHECK-NEXT: Remove redundant instructions ; CHECK-NEXT: Hoist/decompose integer division and remainder ; CHECK-NEXT: Simplify the CFG +; CHECK-NEXT: Annotation Remarks ; CHECK-NEXT: Module Verifier ; CHECK-NEXT: Bitcode Writer ; CHECK-NEXT: Pass Arguments: diff --git a/llvm/test/Other/opt-O3-pipeline.ll b/llvm/test/Other/opt-O3-pipeline.ll --- a/llvm/test/Other/opt-O3-pipeline.ll +++ b/llvm/test/Other/opt-O3-pipeline.ll @@ -316,6 +316,7 @@ ; CHECK-NEXT: Remove redundant instructions ; CHECK-NEXT: Hoist/decompose integer division and remainder ; CHECK-NEXT: Simplify the CFG +; CHECK-NEXT: Annotation Remarks ; CHECK-NEXT: Module Verifier ; CHECK-NEXT: Bitcode Writer ; CHECK-NEXT: Pass Arguments: diff --git a/llvm/test/Other/opt-Os-pipeline.ll b/llvm/test/Other/opt-Os-pipeline.ll --- a/llvm/test/Other/opt-Os-pipeline.ll +++ b/llvm/test/Other/opt-Os-pipeline.ll @@ -297,6 +297,7 @@ ; CHECK-NEXT: Remove redundant instructions ; CHECK-NEXT: Hoist/decompose integer division and remainder ; CHECK-NEXT: Simplify the CFG +; CHECK-NEXT: Annotation Remarks ; CHECK-NEXT: Module Verifier ; CHECK-NEXT: Bitcode Writer ; CHECK-NEXT: Pass Arguments: diff --git a/llvm/test/Transforms/Util/annotation-remarks.ll b/llvm/test/Transforms/Util/annotation-remarks.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Util/annotation-remarks.ll @@ -0,0 +1,52 @@ +; RUN: opt -annotation-remarks -pass-remarks-missed='annotation-remarks' -disable-output -pass-remarks-output=%t.opt.yaml %s +; RUN: FileCheck --input-file=%t.opt.yaml %s +; RUN: opt -passes='annotation-remarks' -pass-remarks-missed='annotation-remarks' -disable-output -pass-remarks-output=%t.opt.yaml %s +; RUN: FileCheck --input-file=%t.opt.yaml %s + +; CHECK: --- !Analysis +; CHECK-NEXT: Pass: annotation-remarks +; CHECK-NEXT: Name: AnnotationSummary +; CHECK-NEXT: Function: test1 +; CHECK-NEXT: Args: +; CHECK-NEXT: - String: 'Annotated ' +; CHECK-NEXT: - count: '4' +; CHECK-NEXT: - String: ' instructions with ' +; CHECK-NEXT: - type: _remarks1 +; CHECK-NEXT: ... +; CHECK-NEXT: --- !Analysis +; CHECK-NEXT: Pass: annotation-remarks +; CHECK-NEXT: Name: AnnotationSummary +; CHECK-NEXT: Function: test1 +; CHECK-NEXT: Args: +; CHECK-NEXT: - String: 'Annotated ' +; CHECK-NEXT: - count: '3' +; CHECK-NEXT: - String: ' instructions with ' +; CHECK-NEXT: - type: _remarks2 +; CHECK-NEXT: ... +; CHECK-NEXT: --- !Analysis +; CHECK-NEXT: Pass: annotation-remarks +; CHECK-NEXT: Name: AnnotationSummary +; CHECK-NEXT: Function: test2 +; CHECK-NEXT: Args: +; CHECK-NEXT: - String: 'Annotated ' +; CHECK-NEXT: - count: '2' +; CHECK-NEXT: - String: ' instructions with ' +; CHECK-NEXT: - type: _remarks1 +; CHECK-NEXT: ... + +define void @test1(float* %a) { +entry: + %a.addr = alloca float*, align 8, !annotation !0 + store float* null, float** %a.addr, align 8, !annotation !1 + store float* %a, float** %a.addr, align 8, !annotation !0 + ret void, !annotation !0 +} + +define void @test2(float* %a) { +entry: + %a.addr = alloca float*, align 8, !annotation !1 + ret void, !annotation !1 +} + +!0 = !{!"_remarks1", !"_remarks2"} +!1 = !{!"_remarks1"} diff --git a/llvm/test/Verifier/annotation-metadata.ll b/llvm/test/Verifier/annotation-metadata.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Verifier/annotation-metadata.ll @@ -0,0 +1,13 @@ +; RUN: not llvm-as -disable-output < %s -o /dev/null 2>&1 | FileCheck %s + +define void @test1(float* %a) { +entry: +; CHECK: annotation must have at least one operand + %a.addr = alloca float*, align 8, !annotation !0 + +; CHECK-NEXT: operands must be strings + ret void, !annotation !1 +} + +!0 = !{} +!1 = !{i32 10}