diff --git a/llvm/include/llvm/Transforms/Utils/FunctionAnnotator.h b/llvm/include/llvm/Transforms/Utils/FunctionAnnotator.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Transforms/Utils/FunctionAnnotator.h @@ -0,0 +1,16 @@ +#ifndef LLVM_TRANSFORMS_FUNCTIONANNOTATOR_H +#define LLVM_TRANSFORMS_FUNCTIONANNOTATOR_H + +#include "llvm/IR/PassManager.h" +#include "llvm/Support/CommandLine.h" + +namespace llvm { + class FunctionAnnotator : public PassInfoMixin { + public: + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); + static cl::opt CSVFilePath; + }; + + } // namespace llvm + + #endif // LLVM_TRANSFORMS_FUNCTIONANNOTATOR_H 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 @@ -232,6 +232,7 @@ #include "llvm/Transforms/Utils/Debugify.h" #include "llvm/Transforms/Utils/EntryExitInstrumenter.h" #include "llvm/Transforms/Utils/FixIrreducible.h" +#include "llvm/Transforms/Utils/FunctionAnnotator.h" #include "llvm/Transforms/Utils/HelloWorld.h" #include "llvm/Transforms/Utils/InjectTLIMappings.h" #include "llvm/Transforms/Utils/InstructionNamer.h" 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 @@ -59,6 +59,7 @@ MODULE_PASS("elim-avail-extern", EliminateAvailableExternallyPass()) MODULE_PASS("extract-blocks", BlockExtractorPass({}, false)) MODULE_PASS("forceattrs", ForceFunctionAttrsPass()) +MODULE_PASS("function-annotator", FunctionAnnotator()) MODULE_PASS("function-import", FunctionImportPass()) MODULE_PASS("globaldce", GlobalDCEPass()) MODULE_PASS("globalopt", GlobalOptPass()) diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt --- a/llvm/lib/Transforms/Utils/CMakeLists.txt +++ b/llvm/lib/Transforms/Utils/CMakeLists.txt @@ -25,6 +25,7 @@ Evaluator.cpp FixIrreducible.cpp FlattenCFG.cpp + FunctionAnnotator.cpp FunctionComparator.cpp FunctionImportUtils.cpp GlobalStatus.cpp diff --git a/llvm/lib/Transforms/Utils/FunctionAnnotator.cpp b/llvm/lib/Transforms/Utils/FunctionAnnotator.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Transforms/Utils/FunctionAnnotator.cpp @@ -0,0 +1,60 @@ +#include "llvm/Transforms/Utils/FunctionAnnotator.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Testing/Annotations/Annotations.h" +#include +#include + +using namespace llvm; + +PreservedAnalyses FunctionAnnotator::run(Module &M, ModuleAnalysisManager &AM) { + /*cl::opt ForceAnnotate( + "force-annotate", cl::init(""), + cl::desc("Force annotate functions with desired optimization level")); + + enum optLev { O0, O1, O2, O3 }; + + // Enable Optimization Options to be specified on the command line + cl::opt DebugLevel( + "optimization-level", cl::desc("Set the optimization level:"), + cl::values(clEnumValN(O0, "none", "Default Optimization"), + clEnumVal(O1, "Optimization level O1"), + clEnumVal(O2, "Optimization level 02"), + clEnumVal(O3, "Optimization level 02"))); + */ + + static cl::opt OptLevelAttributeName( + "-opt-level-attribute-name", cl::init(""), cl::Hidden, + cl::desc("Optimization attribute name")); + + static cl::opt CSVFilePath( + "-csv-file-path", cl::Hidden, cl::Required, + cl::desc("CSV file containing function names and optimization level as " + "attribute")); + + std::ifstream CSVFile; + CSVFile.open(CSVFilePath); + + if (!CSVFile.is_open()) { + report_fatal_error("CSV File does not exist"); + } + + std::string Line; + for (Function &F : M) { + while (std::getline(CSVFile, Line)) { + + std::istringstream stringObj(Line); + std::string FuncName, OptLevel; + + if (std::getline(stringObj, FuncName, ',') && + std::getline(stringObj, OptLevel, ',')) { + if (FuncName == F.getName()) { + F.addFnAttr(OptLevelAttributeName, OptLevel); + break; + } + } + } + CSVFile.close(); + } + + return PreservedAnalyses::all(); +} \ No newline at end of file diff --git a/llvm/test/Transforms/Annotations/FunctionAnnotation.csv b/llvm/test/Transforms/Annotations/FunctionAnnotation.csv new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Annotations/FunctionAnnotation.csv @@ -0,0 +1,6 @@ +FunctionName,OptimizationLevel +first_function,O2 +second_function,O1 +third_function,O3 +fourth_function,O1 +fifth_function,O2 \ No newline at end of file diff --git a/llvm/test/Transforms/Annotations/FunctionAnnotator.ll b/llvm/test/Transforms/Annotations/FunctionAnnotator.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Annotations/FunctionAnnotator.ll @@ -0,0 +1,6 @@ +; RUN: opt -passes='module(function-annotator)' -csv-file-path="./FunctionAnnotation.csv" < %s | FileCheck %s + +; CHECK_LABEL: AttributeList +; CHECK-NEXT: AttributeList[ +; CHECK-NEXT: { function => noinline nounwind ssp uwtable(sync) "O[0123]" [a-zA-Z_][a-zA-Z0-9_]["*\.\+-,] +; CHECK-NEXT: ]