173471bf0Spatrick //===-- Annotation2Metadata.cpp - Add !annotation metadata. ---------------===//
273471bf0Spatrick //
373471bf0Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
473471bf0Spatrick // See https://llvm.org/LICENSE.txt for license information.
573471bf0Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
673471bf0Spatrick //
773471bf0Spatrick //===----------------------------------------------------------------------===//
873471bf0Spatrick //
973471bf0Spatrick // Add !annotation metadata for entries in @llvm.global.anotations, generated
1073471bf0Spatrick // using __attribute__((annotate("_name"))) on functions in Clang.
1173471bf0Spatrick //
1273471bf0Spatrick //===----------------------------------------------------------------------===//
1373471bf0Spatrick
1473471bf0Spatrick #include "llvm/Transforms/IPO/Annotation2Metadata.h"
1573471bf0Spatrick #include "llvm/Analysis/OptimizationRemarkEmitter.h"
1673471bf0Spatrick #include "llvm/IR/Constants.h"
1773471bf0Spatrick #include "llvm/IR/Function.h"
1873471bf0Spatrick #include "llvm/IR/InstIterator.h"
1973471bf0Spatrick #include "llvm/IR/Module.h"
2073471bf0Spatrick #include "llvm/InitializePasses.h"
2173471bf0Spatrick #include "llvm/Pass.h"
2273471bf0Spatrick #include "llvm/Transforms/IPO.h"
2373471bf0Spatrick
2473471bf0Spatrick using namespace llvm;
2573471bf0Spatrick
2673471bf0Spatrick #define DEBUG_TYPE "annotation2metadata"
2773471bf0Spatrick
convertAnnotation2Metadata(Module & M)2873471bf0Spatrick static bool convertAnnotation2Metadata(Module &M) {
2973471bf0Spatrick // Only add !annotation metadata if the corresponding remarks pass is also
3073471bf0Spatrick // enabled.
3173471bf0Spatrick if (!OptimizationRemarkEmitter::allowExtraAnalysis(M.getContext(),
3273471bf0Spatrick "annotation-remarks"))
3373471bf0Spatrick return false;
3473471bf0Spatrick
3573471bf0Spatrick auto *Annotations = M.getGlobalVariable("llvm.global.annotations");
3673471bf0Spatrick auto *C = dyn_cast_or_null<Constant>(Annotations);
3773471bf0Spatrick if (!C || C->getNumOperands() != 1)
3873471bf0Spatrick return false;
3973471bf0Spatrick
4073471bf0Spatrick C = cast<Constant>(C->getOperand(0));
4173471bf0Spatrick
4273471bf0Spatrick // Iterate over all entries in C and attach !annotation metadata to suitable
4373471bf0Spatrick // entries.
4473471bf0Spatrick for (auto &Op : C->operands()) {
4573471bf0Spatrick // Look at the operands to check if we can use the entry to generate
4673471bf0Spatrick // !annotation metadata.
4773471bf0Spatrick auto *OpC = dyn_cast<ConstantStruct>(&Op);
4873471bf0Spatrick if (!OpC || OpC->getNumOperands() != 4)
4973471bf0Spatrick continue;
50*d415bd75Srobert auto *StrC = dyn_cast<GlobalValue>(OpC->getOperand(1)->stripPointerCasts());
5173471bf0Spatrick if (!StrC)
5273471bf0Spatrick continue;
5373471bf0Spatrick auto *StrData = dyn_cast<ConstantDataSequential>(StrC->getOperand(0));
5473471bf0Spatrick if (!StrData)
5573471bf0Spatrick continue;
56*d415bd75Srobert auto *Fn = dyn_cast<Function>(OpC->getOperand(0)->stripPointerCasts());
5773471bf0Spatrick if (!Fn)
5873471bf0Spatrick continue;
5973471bf0Spatrick
6073471bf0Spatrick // Add annotation to all instructions in the function.
6173471bf0Spatrick for (auto &I : instructions(Fn))
6273471bf0Spatrick I.addAnnotationMetadata(StrData->getAsCString());
6373471bf0Spatrick }
6473471bf0Spatrick return true;
6573471bf0Spatrick }
6673471bf0Spatrick
6773471bf0Spatrick namespace {
6873471bf0Spatrick struct Annotation2MetadataLegacy : public ModulePass {
6973471bf0Spatrick static char ID;
7073471bf0Spatrick
Annotation2MetadataLegacy__anonc2248f6a0111::Annotation2MetadataLegacy7173471bf0Spatrick Annotation2MetadataLegacy() : ModulePass(ID) {
7273471bf0Spatrick initializeAnnotation2MetadataLegacyPass(*PassRegistry::getPassRegistry());
7373471bf0Spatrick }
7473471bf0Spatrick
runOnModule__anonc2248f6a0111::Annotation2MetadataLegacy7573471bf0Spatrick bool runOnModule(Module &M) override { return convertAnnotation2Metadata(M); }
7673471bf0Spatrick
getAnalysisUsage__anonc2248f6a0111::Annotation2MetadataLegacy7773471bf0Spatrick void getAnalysisUsage(AnalysisUsage &AU) const override {
7873471bf0Spatrick AU.setPreservesAll();
7973471bf0Spatrick }
8073471bf0Spatrick };
8173471bf0Spatrick
8273471bf0Spatrick } // end anonymous namespace
8373471bf0Spatrick
8473471bf0Spatrick char Annotation2MetadataLegacy::ID = 0;
8573471bf0Spatrick
8673471bf0Spatrick INITIALIZE_PASS_BEGIN(Annotation2MetadataLegacy, DEBUG_TYPE,
8773471bf0Spatrick "Annotation2Metadata", false, false)
8873471bf0Spatrick INITIALIZE_PASS_END(Annotation2MetadataLegacy, DEBUG_TYPE,
8973471bf0Spatrick "Annotation2Metadata", false, false)
9073471bf0Spatrick
createAnnotation2MetadataLegacyPass()9173471bf0Spatrick ModulePass *llvm::createAnnotation2MetadataLegacyPass() {
9273471bf0Spatrick return new Annotation2MetadataLegacy();
9373471bf0Spatrick }
9473471bf0Spatrick
run(Module & M,ModuleAnalysisManager & AM)9573471bf0Spatrick PreservedAnalyses Annotation2MetadataPass::run(Module &M,
9673471bf0Spatrick ModuleAnalysisManager &AM) {
9773471bf0Spatrick convertAnnotation2Metadata(M);
9873471bf0Spatrick return PreservedAnalyses::all();
9973471bf0Spatrick }
100