* Build information necessary for inlining external function references in * mod. */
| 171 | * mod. |
| 172 | */ |
| 173 | static std::unique_ptr<ImportMapTy> |
| 174 | llvm_build_inline_plan(llvm::Module *mod) |
| 175 | { |
| 176 | std::unique_ptr<ImportMapTy> globalsToInline(new ImportMapTy()); |
| 177 | FunctionInlineStates functionStates; |
| 178 | InlineWorkList worklist; |
| 179 | |
| 180 | InlineSearchPath defaultSearchPath; |
| 181 | |
| 182 | /* attempt to add module to search path */ |
| 183 | add_module_to_inline_search_path(defaultSearchPath, "$libdir/postgres"); |
| 184 | /* if postgres isn't available, no point continuing */ |
| 185 | if (defaultSearchPath.empty()) |
| 186 | return nullptr; |
| 187 | |
| 188 | /* |
| 189 | * Start inlining with current references to external functions by putting |
| 190 | * them on the inlining worklist. If, during inlining of those, new extern |
| 191 | * functions need to be inlined, they'll also be put there, with a lower |
| 192 | * priority. |
| 193 | */ |
| 194 | for (const llvm::Function &funcDecl : mod->functions()) |
| 195 | { |
| 196 | InlineWorkListItem item = {}; |
| 197 | FunctionInlineState inlineState = {}; |
| 198 | |
| 199 | /* already has a definition */ |
| 200 | if (!funcDecl.isDeclaration()) |
| 201 | continue; |
| 202 | |
| 203 | /* llvm provides implementation */ |
| 204 | if (funcDecl.isIntrinsic()) |
| 205 | continue; |
| 206 | |
| 207 | item.symbolName = funcDecl.getName(); |
| 208 | item.searchpath = defaultSearchPath; |
| 209 | worklist.push_back(item); |
| 210 | inlineState.costLimit = inline_initial_cost; |
| 211 | inlineState.processed = false; |
| 212 | inlineState.inlined = false; |
| 213 | inlineState.allowReconsidering = false; |
| 214 | functionStates[funcDecl.getName()] = inlineState; |
| 215 | } |
| 216 | |
| 217 | /* |
| 218 | * Iterate over pending worklist items, look them up in index, check |
| 219 | * whether they should be inlined. |
| 220 | */ |
| 221 | while (!worklist.empty()) |
| 222 | { |
| 223 | InlineWorkListItem item = worklist.pop_back_val(); |
| 224 | llvm::StringRef symbolName = item.symbolName; |
| 225 | char *cmodname; |
| 226 | char *cfuncname; |
| 227 | FunctionInlineState &inlineState = functionStates[symbolName]; |
| 228 | llvm::GlobalValue::GUID funcGUID; |
| 229 | |
| 230 | llvm_split_symbol_name(symbolName.data(), &cmodname, &cfuncname); |
no test coverage detected