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