OmniSciDB  6686921089
 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 2021 OmniSci, 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  for (const auto& attr : attrs) {
59  fcn->addFnAttr(attr);
60  }
61  }
62  }
63 
64  return updated_function_defs;
65  }
66 
67  llvm::StringRef getPassName() const override { return "AnnotateInternalFunctionsPass"; }
68 
69  private:
70  static const std::set<std::string> extension_functions;
71 
72  static bool isInternalStatelessFunction(const llvm::StringRef& func_name) {
73  // extension functions or non-inlined builtins which do not modify any state
74  return extension_functions.count(func_name.str()) > 0;
75  }
76 
77  static const std::set<std::string> math_builtins;
78 
79  static bool isInternalMathFunction(const llvm::StringRef& func_name) {
80  // include all math functions from ExtensionFunctions.hpp
81  return math_builtins.count(func_name.str()) > 0;
82  }
83 };
84 
86 
87 const std::set<std::string> AnnotateInternalFunctionsPass::extension_functions =
88  std::set<std::string>{"point_coord_array_is_null",
89  "decompress_x_coord_geoint",
90  "decompress_y_coord_geoint",
91  "compress_x_coord_geoint",
92  "compress_y_coord_geoint",
93  // GeoOpsRuntime.cpp
94  "transform_4326_900913_x",
95  "transform_4326_900913_y",
96  "transform_900913_4326_x",
97  "transform_900913_4326_y",
98  // ExtensionFunctions.hpp
99  "conv_4326_900913_x",
100  "conv_4326_900913_y",
101  "distance_in_meters",
102  "approx_distance_in_meters",
103  "rect_pixel_bin_x",
104  "rect_pixel_bin_y",
105  "rect_pixel_bin_packed",
106  "reg_hex_horiz_pixel_bin_x",
107  "reg_hex_horiz_pixel_bin_y",
108  "reg_hex_horiz_pixel_bin_packed",
109  "reg_hex_vert_pixel_bin_x",
110  "reg_hex_vert_pixel_bin_y",
111  "reg_hex_vert_pixel_bin_packed",
112  "convert_meters_to_merc_pixel_width",
113  "convert_meters_to_merc_pixel_height",
114  "is_point_in_merc_view",
115  "is_point_size_in_merc_view"};
116 
117 // TODO: consider either adding specializations here for the `__X` versions (for different
118 // types), or just truncate the function name removing the underscores in
119 // `isInternalMathFunction`.
120 const std::set<std::string> AnnotateInternalFunctionsPass::math_builtins =
121  std::set<std::string>{"Acos", "Asin", "Atan", "Atan2", "Ceil", "Cos",
122  "Cot", "degrees", "Exp", "Floor", "ln", "Log",
123  "Log10", "log", "pi", "power", "radians", "Round",
124  "Sin", "Tan", "tan", "Truncate", "isNan"};
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:209
llvm::StringRef getPassName() const override
static const std::set< std::string > math_builtins
static bool isInternalMathFunction(const llvm::StringRef &func_name)