LLVM: lib/Target/Hexagon/HexagonCFGOptimizer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

20#include

21#include

22

23using namespace llvm;

24

25#define DEBUG_TYPE "hexagon_cfg"

26

27namespace {

28

30private:

33

34public:

35 static char ID;

36

38

39 StringRef getPassName() const override { return "Hexagon CFG Optimizer"; }

41

44 }

45};

46

47}

48

49char HexagonCFGOptimizer::ID = 0;

50

52 switch (Opc) {

53 case Hexagon::J2_jumpt:

54 case Hexagon::J2_jumptpt:

55 case Hexagon::J2_jumpf:

56 case Hexagon::J2_jumpfpt:

57 case Hexagon::J2_jumptnew:

58 case Hexagon::J2_jumpfnew:

59 case Hexagon::J2_jumptnewpt:

60 case Hexagon::J2_jumpfnewpt:

61 return true;

62 }

63 return false;

64}

65

67 return (Opc == Hexagon::J2_jump);

68}

69

70void HexagonCFGOptimizer::InvertAndChangeJumpTarget(

72 const TargetInstrInfo *TII =

73 MI.getParent()->getParent()->getSubtarget().getInstrInfo();

74 int NewOpcode = 0;

75 switch (MI.getOpcode()) {

76 case Hexagon::J2_jumpt:

77 NewOpcode = Hexagon::J2_jumpf;

78 break;

79 case Hexagon::J2_jumpf:

80 NewOpcode = Hexagon::J2_jumpt;

81 break;

82 case Hexagon::J2_jumptnewpt:

83 NewOpcode = Hexagon::J2_jumpfnewpt;

84 break;

85 case Hexagon::J2_jumpfnewpt:

86 NewOpcode = Hexagon::J2_jumptnewpt;

87 break;

88 default:

90 }

91

92 MI.setDesc(TII->get(NewOpcode));

93 MI.getOperand(1).setMBB(NewTarget);

94}

95

96bool HexagonCFGOptimizer::isOnFallThroughPath(MachineBasicBlock *MBB) {

98 return true;

100 if (PB->isLayoutSuccessor(MBB) && PB->canFallThrough())

101 return true;

102 return false;

103}

104

105bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {

107 return false;

108

109

110 for (MachineBasicBlock &MBB : Fn) {

111

113 if (MII != MBB.end()) {

114 MachineInstr &MI = *MII;

115 int Opc = MI.getOpcode();

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

146 MachineBasicBlock* FirstSucc = *SI;

147 MachineBasicBlock* SecondSucc = *(++SI);

148 MachineBasicBlock* LayoutSucc = nullptr;

149 MachineBasicBlock* JumpAroundTarget = nullptr;

150

152 LayoutSucc = FirstSucc;

153 JumpAroundTarget = SecondSucc;

155 LayoutSucc = SecondSucc;

156 JumpAroundTarget = FirstSucc;

157 } else {

158

159 }

160

161

162

163 MachineBasicBlock* CondBranchTarget = nullptr;

164 if (MI.getOpcode() == Hexagon::J2_jumpt ||

165 MI.getOpcode() == Hexagon::J2_jumpf) {

166 CondBranchTarget = MI.getOperand(1).getMBB();

167 }

168

169 if (!LayoutSucc || (CondBranchTarget != JumpAroundTarget)) {

170 continue;

171 }

172

173 if ((NumSuccs == 2) && LayoutSucc && (LayoutSucc->pred_size() == 1)) {

174

175 if ((LayoutSucc->size() == 1) &&

177 assert(JumpAroundTarget && "jump target is needed to process second basic block");

178 MachineBasicBlock* UncondTarget =

180

182 bool case2 = JumpAroundTarget->isSuccessor(UncondTarget) &&

183 !JumpAroundTarget->empty() &&

185 JumpAroundTarget->pred_size() == 1 &&

186 JumpAroundTarget->succ_size() == 1;

187

188 if (case1 || case2) {

189 InvertAndChangeJumpTarget(MI, UncondTarget);

191

192

193 LayoutSucc->erase(LayoutSucc->begin());

194 LayoutSucc->replaceSuccessor(UncondTarget, JumpAroundTarget);

195

196

197

198 if (case2 && !case1) {

199 JumpAroundTarget->moveAfter(LayoutSucc);

200

201

202 if (!isOnFallThroughPath(UncondTarget))

203 UncondTarget->moveAfter(JumpAroundTarget);

204 }

205

206

207

208

209 std::vectorMachineBasicBlock::RegisterMaskPair OrigLiveIn(

211 std::vectorMachineBasicBlock::RegisterMaskPair NewLiveIn(

214 for (const auto &OrigLI : OrigLiveIn)

216 for (const auto &NewLI : NewLiveIn)

218 }

219 }

220 }

221 }

222 }

223 }

224 return true;

225}

226

227

228

229

230

231INITIALIZE_PASS(HexagonCFGOptimizer, "hexagon-cfg", "Hexagon CFG Optimizer",

232 false, false)

233

235 return new HexagonCFGOptimizer();

236}

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

const TargetInstrInfo & TII

static bool IsConditionalBranch(int Opc)

Definition HexagonCFGOptimizer.cpp:51

static bool IsUnconditionalJump(int Opc)

Definition HexagonCFGOptimizer.cpp:66

PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)

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

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

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

unsigned pred_size() const

livein_iterator livein_end() const

LLVM_ABI void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)

Replace successor OLD with NEW and update probability info.

LLVM_ABI bool canFallThrough()

Return true if the block can implicitly transfer control to the block after it by falling off the end...

succ_iterator succ_begin()

LLVM_ABI void removeLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll())

Remove the specified register from the live in set.

LLVM_ABI iterator getFirstTerminator()

Returns an iterator to the first terminator instruction of this basic block.

LLVM_ABI livein_iterator livein_begin() const

unsigned succ_size() const

SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator

LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const

Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...

void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())

Adds the specified register as a live in.

LLVM_ABI instr_iterator erase(instr_iterator I)

Remove an instruction from the instruction list and delete it.

LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const

Return true if the specified MBB is a successor of this block.

iterator_range< pred_iterator > predecessors()

MachineInstrBundleIterator< MachineInstr > iterator

LLVM_ABI void moveAfter(MachineBasicBlock *NewBefore)

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

Properties which a MachineFunction may have at a given point in time.

Function & getFunction()

Return the LLVM function that this machine code represents.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineOperand & getOperand(unsigned i) const

MachineBasicBlock * getMBB() const

StringRef - Represent a constant reference to a string, i.e.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

unsigned ID

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

This is an optimization pass for GlobalISel generic memory operations.

FunctionPass * createHexagonCFGOptimizer()