LLVM: lib/Target/AArch64/AArch64CompressJumpTables.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

23

24using namespace llvm;

25

26#define DEBUG_TYPE "aarch64-jump-tables"

27

28STATISTIC(NumJT8, "Number of jump-tables with 1-byte entries");

29STATISTIC(NumJT16, "Number of jump-tables with 2-byte entries");

30STATISTIC(NumJT32, "Number of jump-tables with 4-byte entries");

31

32namespace {

37

38

39

41

42

43

44 bool scanFunction();

45

47

48public:

49 static char ID;

51

52 bool runOnMachineFunction(MachineFunction &MF) override;

53

54 MachineFunctionProperties getRequiredProperties() const override {

55 return MachineFunctionProperties().setNoVRegs();

56 }

57 StringRef getPassName() const override {

58 return "AArch64 Compress Jump Tables";

59 }

60};

61char AArch64CompressJumpTables::ID = 0;

62}

63

65 "AArch64 compress jump tables pass", false, false)

66

67std::optional<int>

71

72

73

74 if (MI.getOpcode() == AArch64::INLINEASM ||

75 MI.getOpcode() == AArch64::INLINEASM_BR)

76 return std::nullopt;

77 Size += TII->getInstSizeInBytes(MI);

78 }

80}

81

82bool AArch64CompressJumpTables::scanFunction() {

83 BlockInfo.clear();

85

86

87

89 for (MachineBasicBlock &MBB : *MF) {

91 unsigned OffsetAfterAlignment = Offset;

92

93 if (Alignment > Align(4))

94 OffsetAfterAlignment += Alignment.value() - 4;

95 BlockInfo[MBB.getNumber()] = OffsetAfterAlignment;

98 return false;

100 }

101 return true;

102}

103

104bool AArch64CompressJumpTables::compressJumpTable(MachineInstr &MI,

106 if (MI.getOpcode() != AArch64::JumpTableDest32)

107 return false;

108

109 int JTIdx = MI.getOperand(4).getIndex();

110 auto &JTInfo = *MF->getJumpTableInfo();

111 const MachineJumpTableEntry &JT = JTInfo.getJumpTables()[JTIdx];

112

113

114 if (JT.MBBs.empty())

115 return false;

116

117 int MaxOffset = std::numeric_limits::min(),

118 MinOffset = std::numeric_limits::max();

119 MachineBasicBlock *MinBlock = nullptr;

120 for (auto *Block : JT.MBBs) {

121 int BlockOffset = BlockInfo[Block->getNumber()];

122 assert(BlockOffset % 4 == 0 && "misaligned basic block");

123

124 MaxOffset = std::max(MaxOffset, BlockOffset);

125 if (BlockOffset <= MinOffset) {

126 MinOffset = BlockOffset;

127 MinBlock = Block;

128 }

129 }

130 assert(MinBlock && "Failed to find minimum offset block");

131

132

133

135 ++NumJT32;

136 return false;

137 }

138

139 int Span = MaxOffset - MinOffset;

140 auto *AFI = MF->getInfo();

142 AFI->setJumpTableEntryInfo(JTIdx, 1, MinBlock->getSymbol());

143 MI.setDesc(TII->get(AArch64::JumpTableDest8));

144 ++NumJT8;

145 return true;

146 }

148 AFI->setJumpTableEntryInfo(JTIdx, 2, MinBlock->getSymbol());

149 MI.setDesc(TII->get(AArch64::JumpTableDest16));

150 ++NumJT16;

151 return true;

152 }

153

154 ++NumJT32;

155 return false;

156}

157

158bool AArch64CompressJumpTables::runOnMachineFunction(MachineFunction &MFIn) {

160 MF = &MFIn;

161

162 const auto &ST = MF->getSubtarget();

163 TII = ST.getInstrInfo();

164

165 if (ST.force32BitJumpTables() && !MF->getFunction().hasMinSize())

166 return false;

167

168 if (!scanFunction())

169 return false;

170

171 for (MachineBasicBlock &MBB : *MF) {

173 for (MachineInstr &MI : MBB) {

176 }

177 }

178

180}

181

183 return new AArch64CompressJumpTables();

184}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const HexagonInstrInfo * TII

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

static const int BlockSize

FunctionPass class - This class is used to implement most global optimizations.

LLVM_ABI MCSymbol * getSymbol() const

Return the MCSymbol for this basic block.

int getNumber() const

MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...

Align getAlignment() const

Return alignment of the basic block.

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

unsigned getNumBlockIDs() const

getNumBlockIDs - Return the number of MBB ID's allocated.

Representation of each machine instruction.

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

TargetInstrInfo - Interface to description of machine instruction set.

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

This is an optimization pass for GlobalISel generic memory operations.

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

FunctionPass * createAArch64CompressJumpTablesPass()

Definition AArch64CompressJumpTables.cpp:182

constexpr bool isUInt(uint64_t x)

Checks if an unsigned integer fits into the given bit width.

Implement std::hash so that hash_code can be used in STL containers.

constexpr uint64_t value() const

This is a hole in the type system and should not be abused.