xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/RelLookupTableConverter.h (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
1fe6060f1SDimitry Andric //===-- RelLookupTableConverterPass.h - Rel Table Conv ----------*- C++ -*-===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric //
9fe6060f1SDimitry Andric /// \file
10fe6060f1SDimitry Andric /// This file implements relative lookup table converter that converts
11fe6060f1SDimitry Andric /// lookup tables to relative lookup tables to make them PIC-friendly.
12fe6060f1SDimitry Andric ///
13fe6060f1SDimitry Andric /// Switch lookup table example:
14fe6060f1SDimitry Andric /// @switch.table.foo = private unnamed_addr constant [3 x i8*]
15fe6060f1SDimitry Andric /// [
16fe6060f1SDimitry Andric /// i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0),
17fe6060f1SDimitry Andric /// i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0),
18fe6060f1SDimitry Andric /// i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0)
19fe6060f1SDimitry Andric /// ], align 8
20fe6060f1SDimitry Andric ///
21fe6060f1SDimitry Andric /// switch.lookup:
22fe6060f1SDimitry Andric ///   %1 = sext i32 %cond to i64
23fe6060f1SDimitry Andric ///   %switch.gep = getelementptr inbounds [3 x i8*],
24fe6060f1SDimitry Andric ///                 [3 x i8*]* @switch.table.foo, i64 0, i64 %1
25fe6060f1SDimitry Andric ///   %switch.load = load i8*, i8** %switch.gep, align 8
26fe6060f1SDimitry Andric ///  ret i8* %switch.load
27fe6060f1SDimitry Andric ///
28fe6060f1SDimitry Andric /// Switch lookup table will become a relative lookup table that
29fe6060f1SDimitry Andric /// consists of relative offsets.
30fe6060f1SDimitry Andric ///
31fe6060f1SDimitry Andric /// @reltable.foo = private unnamed_addr constant [3 x i32]
32fe6060f1SDimitry Andric /// [
33fe6060f1SDimitry Andric /// i32 trunc (i64 sub (i64 ptrtoint ([5 x i8]* @.str to i64),
34fe6060f1SDimitry Andric ///                     i64 ptrtoint ([3 x i32]* @reltable.foo to i64)) to i32),
35fe6060f1SDimitry Andric /// i32 trunc (i64 sub (i64 ptrtoint ([4 x i8]* @.str.1 to i64),
36fe6060f1SDimitry Andric ///                     i64 ptrtoint ([3 x i32]* @reltable.foo to i64)) to i32),
37fe6060f1SDimitry Andric /// i32 trunc (i64 sub (i64 ptrtoint ([4 x i8]* @.str.2 to i64),
38fe6060f1SDimitry Andric ///                     i64 ptrtoint ([3 x i32]* @reltable.foo to i64)) to i32)
39fe6060f1SDimitry Andric /// ], align 4
40fe6060f1SDimitry Andric ///
41fe6060f1SDimitry Andric /// IR after converting to a relative lookup table:
42fe6060f1SDimitry Andric /// switch.lookup:
43fe6060f1SDimitry Andric ///  %1 = sext i32 %cond to i64
44fe6060f1SDimitry Andric ///  %reltable.shift = shl i64 %1, 2
45fe6060f1SDimitry Andric ///  %reltable.intrinsic = call i8* @llvm.load.relative.i64(
46fe6060f1SDimitry Andric ///                        i8* bitcast ([3 x i32]* @reltable.foo to i8*),
47fe6060f1SDimitry Andric ///                        i64 %reltable.shift)
48fe6060f1SDimitry Andric ///  ret i8* %reltable.intrinsic
49fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
50fe6060f1SDimitry Andric 
51fe6060f1SDimitry Andric #ifndef LLVM_TRANSFORMS_UTILS_RELLOOKUPTABLECONVERTER_H
52fe6060f1SDimitry Andric #define LLVM_TRANSFORMS_UTILS_RELLOOKUPTABLECONVERTER_H
53fe6060f1SDimitry Andric 
54fe6060f1SDimitry Andric #include "llvm/IR/PassManager.h"
55fe6060f1SDimitry Andric 
56fe6060f1SDimitry Andric namespace llvm {
57fe6060f1SDimitry Andric 
58*81ad6265SDimitry Andric class Module;
59*81ad6265SDimitry Andric 
60fe6060f1SDimitry Andric // Pass that converts lookup tables to relative lookup tables.
61fe6060f1SDimitry Andric class RelLookupTableConverterPass
62fe6060f1SDimitry Andric     : public PassInfoMixin<RelLookupTableConverterPass> {
63fe6060f1SDimitry Andric public:
64fe6060f1SDimitry Andric   RelLookupTableConverterPass() = default;
65fe6060f1SDimitry Andric 
66fe6060f1SDimitry Andric   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
67fe6060f1SDimitry Andric };
68fe6060f1SDimitry Andric 
69fe6060f1SDimitry Andric } // end namespace llvm
70fe6060f1SDimitry Andric 
71fe6060f1SDimitry Andric #endif // LLVM_TRANSFORMS_UTILS_RELLOOKUPTABLECONVERTER_H
72