OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AnnotateInternalFunctionsPass.h
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <llvm/IR/Function.h>
18 
19 #include <llvm/Analysis/CallGraph.h>
20 #include <llvm/Analysis/CallGraphSCCPass.h>
21 
22 #include <llvm/Pass.h>
23 #include <llvm/Support/raw_ostream.h>
24 
25 #include "Logger/Logger.h"
26 
34 class AnnotateInternalFunctionsPass : public llvm::CallGraphSCCPass {
35  public:
36  static char ID;
37  AnnotateInternalFunctionsPass() : CallGraphSCCPass(ID) {}
38 
39  bool runOnSCC(llvm::CallGraphSCC& SCC) override {
40  bool updated_function_defs = false;
41 
42  // iterate the call graph
43  for (auto& node : SCC) {
44  CHECK(node);
45  auto fcn = node->getFunction();
46  if (!fcn) {
47  continue;
48  }
49  if (isInternalStatelessFunction(fcn->getName()) ||
50  isInternalMathFunction(fcn->getName())) {
51  updated_function_defs = true;
52  std::vector<llvm::Attribute::AttrKind> attrs{llvm::Attribute::NoFree,
53  llvm::Attribute::NoSync,
54  llvm::Attribute::NoUnwind,
55  llvm::Attribute::WillReturn,
56  llvm::Attribute::ReadNone,
57  llvm::Attribute::Speculatable};
58  // WriteOnly is automatically added to all math functions in llvm 14.0
59  // https://reviews.llvm.org/D116426 which is incompatible with ReadNone.
60  fcn->removeFnAttr(llvm::Attribute::WriteOnly);
61  for (const auto& attr : attrs) {
62  fcn->addFnAttr(attr);
63  }
64  }
65  }
66 
67  return updated_function_defs;
68  }
69 
70  llvm::StringRef getPassName() const override { return "AnnotateInternalFunctionsPass"; }
71 
72  private:
73  static const std::set<std::string> extension_functions;
74 
75  static bool isInternalStatelessFunction(const llvm::StringRef& func_name) {
76  // extension functions or non-inlined builtins which do not modify any state
77  return extension_functions.count(func_name.str()) > 0;
78  }
79 
80  static const std::set<std::string> math_builtins;
81 
82  static bool isInternalMathFunction(const llvm::StringRef& func_name) {
83  // include all math functions from ExtensionFunctions.hpp
84  return math_builtins.count(func_name.str()) > 0;
85  }
86 };
87 
89 
90 const std::set<std::string> AnnotateInternalFunctionsPass::extension_functions =
91  std::set<std::string>{"point_coord_array_is_null",
92  "decompress_x_coord_geoint",
93  "decompress_y_coord_geoint",
94  "compress_x_coord_geoint",
95  "compress_y_coord_geoint",
96  // GeoOpsRuntime.cpp
97  "transform_4326_900913_x",
98  "transform_4326_900913_y",
99  "transform_900913_4326_x",
100  "transform_900913_4326_y",
101  // ExtensionFunctions.hpp
102  "conv_4326_900913_x",
103  "conv_4326_900913_y",
104  "distance_in_meters",
105  "approx_distance_in_meters",
106  "rect_pixel_bin_x",
107  "rect_pixel_bin_y",
108  "rect_pixel_bin_packed",
109  "reg_hex_horiz_pixel_bin_x",
110  "reg_hex_horiz_pixel_bin_y",
111  "reg_hex_horiz_pixel_bin_packed",
112  "reg_hex_vert_pixel_bin_x",
113  "reg_hex_vert_pixel_bin_y",
114  "reg_hex_vert_pixel_bin_packed",
115  "convert_meters_to_merc_pixel_width",
116  "convert_meters_to_merc_pixel_height",
117  "is_point_in_merc_view",
118  "is_point_size_in_merc_view"};
119 
120 // TODO: consider either adding specializations here for the `__X` versions (for different
121 // types), or just truncate the function name removing the underscores in
122 // `isInternalMathFunction`.
123 const std::set<std::string> AnnotateInternalFunctionsPass::math_builtins =
124  std::set<std::string>{"Acos", "Asin", "Atan", "Atan2", "Ceil", "Cos",
125  "Cot", "degrees", "Exp", "Floor", "ln", "Log",
126  "Log10", "log", "pi", "power", "radians", "Round",
127  "Sin", "Tan", "tan", "Truncate", "is_nan", "is_inf"};
bool runOnSCC(llvm::CallGraphSCC &SCC) override
static const std::set< std::string > extension_functions
static bool isInternalStatelessFunction(const llvm::StringRef &func_name)
#define CHECK(condition)
Definition: Logger.h:291
llvm::StringRef getPassName() const override
static const std::set< std::string > math_builtins
static bool isInternalMathFunction(const llvm::StringRef &func_name)