xref: /openbsd-src/gnu/llvm/llvm/lib/Transforms/IPO/Annotation2Metadata.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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