1b60736ecSDimitry Andric //===-- Annotation2Metadata.cpp - Add !annotation metadata. ---------------===// 2b60736ecSDimitry Andric // 3b60736ecSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4b60736ecSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5b60736ecSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6b60736ecSDimitry Andric // 7b60736ecSDimitry Andric //===----------------------------------------------------------------------===// 8b60736ecSDimitry Andric // 9b60736ecSDimitry Andric // Add !annotation metadata for entries in @llvm.global.anotations, generated 10b60736ecSDimitry Andric // using __attribute__((annotate("_name"))) on functions in Clang. 11b60736ecSDimitry Andric // 12b60736ecSDimitry Andric //===----------------------------------------------------------------------===// 13b60736ecSDimitry Andric 14b60736ecSDimitry Andric #include "llvm/Transforms/IPO/Annotation2Metadata.h" 15b60736ecSDimitry Andric #include "llvm/Analysis/OptimizationRemarkEmitter.h" 16b60736ecSDimitry Andric #include "llvm/IR/Constants.h" 17b60736ecSDimitry Andric #include "llvm/IR/Function.h" 18b60736ecSDimitry Andric #include "llvm/IR/InstIterator.h" 19b60736ecSDimitry Andric #include "llvm/IR/Module.h" 20b60736ecSDimitry Andric #include "llvm/Transforms/IPO.h" 21b60736ecSDimitry Andric 22b60736ecSDimitry Andric using namespace llvm; 23b60736ecSDimitry Andric 24b60736ecSDimitry Andric #define DEBUG_TYPE "annotation2metadata" 25b60736ecSDimitry Andric convertAnnotation2Metadata(Module & M)26b60736ecSDimitry Andricstatic bool convertAnnotation2Metadata(Module &M) { 27b60736ecSDimitry Andric // Only add !annotation metadata if the corresponding remarks pass is also 28b60736ecSDimitry Andric // enabled. 29b60736ecSDimitry Andric if (!OptimizationRemarkEmitter::allowExtraAnalysis(M.getContext(), 30b60736ecSDimitry Andric "annotation-remarks")) 31b60736ecSDimitry Andric return false; 32b60736ecSDimitry Andric 33b60736ecSDimitry Andric auto *Annotations = M.getGlobalVariable("llvm.global.annotations"); 34b60736ecSDimitry Andric auto *C = dyn_cast_or_null<Constant>(Annotations); 35b60736ecSDimitry Andric if (!C || C->getNumOperands() != 1) 36b60736ecSDimitry Andric return false; 37b60736ecSDimitry Andric 38b60736ecSDimitry Andric C = cast<Constant>(C->getOperand(0)); 39b60736ecSDimitry Andric 40b60736ecSDimitry Andric // Iterate over all entries in C and attach !annotation metadata to suitable 41b60736ecSDimitry Andric // entries. 42b60736ecSDimitry Andric for (auto &Op : C->operands()) { 43b60736ecSDimitry Andric // Look at the operands to check if we can use the entry to generate 44b60736ecSDimitry Andric // !annotation metadata. 45b60736ecSDimitry Andric auto *OpC = dyn_cast<ConstantStruct>(&Op); 46b60736ecSDimitry Andric if (!OpC || OpC->getNumOperands() != 4) 47b60736ecSDimitry Andric continue; 48e3b55780SDimitry Andric auto *StrC = dyn_cast<GlobalValue>(OpC->getOperand(1)->stripPointerCasts()); 49b60736ecSDimitry Andric if (!StrC) 50b60736ecSDimitry Andric continue; 51b60736ecSDimitry Andric auto *StrData = dyn_cast<ConstantDataSequential>(StrC->getOperand(0)); 52b60736ecSDimitry Andric if (!StrData) 53b60736ecSDimitry Andric continue; 54e3b55780SDimitry Andric auto *Fn = dyn_cast<Function>(OpC->getOperand(0)->stripPointerCasts()); 55b60736ecSDimitry Andric if (!Fn) 56b60736ecSDimitry Andric continue; 57b60736ecSDimitry Andric 58b60736ecSDimitry Andric // Add annotation to all instructions in the function. 59b60736ecSDimitry Andric for (auto &I : instructions(Fn)) 60b60736ecSDimitry Andric I.addAnnotationMetadata(StrData->getAsCString()); 61b60736ecSDimitry Andric } 62b60736ecSDimitry Andric return true; 63b60736ecSDimitry Andric } 64b60736ecSDimitry Andric run(Module & M,ModuleAnalysisManager & AM)65b60736ecSDimitry AndricPreservedAnalyses Annotation2MetadataPass::run(Module &M, 66b60736ecSDimitry Andric ModuleAnalysisManager &AM) { 677fa27ce4SDimitry Andric return convertAnnotation2Metadata(M) ? PreservedAnalyses::none() 687fa27ce4SDimitry Andric : PreservedAnalyses::all(); 69b60736ecSDimitry Andric } 70