RelLookupTableConverter.h 2.8 KB

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